summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp52
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIAArch64.h32
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp831
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h (renamed from lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h)21
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp800
-rw-r--r--lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h (renamed from lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h)21
-rw-r--r--lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp (renamed from lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp)10
-rw-r--r--lldb/source/Plugins/ABI/ARC/ABISysV_arc.h (renamed from lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.h)4
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABIARM.cpp24
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABIARM.h17
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp (renamed from lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp)2
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h (renamed from lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h)14
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp (renamed from lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/ARM/ABISysV_arm.h (renamed from lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h)14
-rw-r--r--lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp (renamed from lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h (renamed from lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h)14
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp2451
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABIMips.cpp24
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABIMips.h17
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp (renamed from lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABISysV_mips.h (renamed from lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h)14
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp (renamed from lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h (renamed from lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h)16
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp24
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h17
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp (renamed from lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h (renamed from lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h)16
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp (renamed from lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp)12
-rw-r--r--lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h (renamed from lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h)16
-rw-r--r--lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp2420
-rw-r--r--lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp (renamed from lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp)4
-rw-r--r--lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h (renamed from lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h)14
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp (renamed from lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp)662
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h (renamed from lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h)26
-rw-r--r--lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp (renamed from lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp)131
-rw-r--r--lldb/source/Plugins/ABI/X86/ABISysV_i386.h (renamed from lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h)21
-rw-r--r--lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp (renamed from lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp)173
-rw-r--r--lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h (renamed from lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h)23
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp (renamed from lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp)997
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h (renamed from lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h)21
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIX86.cpp43
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIX86.h24
-rw-r--r--lldb/source/Plugins/ABI/X86/ABIX86_64.h26
-rw-r--r--lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp4
-rw-r--r--lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h6
-rw-r--r--lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp16
-rw-r--r--lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h9
-rw-r--r--lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp4
-rw-r--r--lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h6
-rw-r--r--lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp (renamed from lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp)158
-rw-r--r--lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h (renamed from lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h)6
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp8
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h10
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp2
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h6
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp2
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h4
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp4
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h12
-rw-r--r--lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp19
-rw-r--r--lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h9
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp9
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h6
-rw-r--r--lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp70
-rw-r--r--lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h48
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp50
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h15
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h9
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp1212
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h328
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp35
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h110
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp1154
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h166
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp400
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h115
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h13
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp357
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h18
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp142
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h38
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h19
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp88
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h66
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp8
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp10
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp65
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp26
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h28
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp155
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp87
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h50
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp16
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp289
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h65
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp8
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp47
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h11
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp179
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h124
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp19
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h6
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp2
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h9
-rw-r--r--lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp59
-rw-r--r--lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h9
-rw-r--r--lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp8
-rw-r--r--lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h8
-rw-r--r--lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp8
-rw-r--r--lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h8
-rw-r--r--lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp6
-rw-r--r--lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h6
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp (renamed from lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp)48
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h (renamed from lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h)14
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp (renamed from lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp)65
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h68
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h67
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp (renamed from lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp)118
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h (renamed from lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h)14
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp (renamed from lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp)55
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h (renamed from lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h)14
-rw-r--r--lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp10
-rw-r--r--lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp22
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp25
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp33
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h7
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp261
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.h34
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp22
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp17
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp8
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp13
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp28
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h4
-rw-r--r--lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp3
-rw-r--r--lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/CF.cpp7
-rw-r--r--lldb/source/Plugins/Language/ObjC/CF.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp114
-rw-r--r--lldb/source/Plugins/Language/ObjC/CFBasicHash.h76
-rw-r--r--lldb/source/Plugins/Language/ObjC/Cocoa.cpp22
-rw-r--r--lldb/source/Plugins/Language/ObjC/Cocoa.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/CoreMedia.cpp3
-rw-r--r--lldb/source/Plugins/Language/ObjC/CoreMedia.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSArray.cpp79
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSDictionary.cpp330
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSDictionary.h9
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSError.cpp8
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSException.cpp6
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp6
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSSet.cpp213
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSSet.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSString.cpp21
-rw-r--r--lldb/source/Plugins/Language/ObjC/NSString.h6
-rw-r--r--lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp33
-rw-r--r--lldb/source/Plugins/Language/ObjC/ObjCLanguage.h6
-rw-r--r--lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp5
-rw-r--r--lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp5
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h13
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp29
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h19
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp64
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h26
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp76
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h10
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp83
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h14
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp11
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h12
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp132
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h32
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp145
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h14
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp46
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h22
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp254
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h78
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp16
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h20
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp39
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h42
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp16
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h4
-rw-r--r--lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp11
-rw-r--r--lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h6
-rw-r--r--lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp6
-rw-r--r--lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp2
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp42
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h9
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp11
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h6
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp466
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h151
-rw-r--r--lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp6
-rw-r--r--lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp4
-rw-r--r--lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h9
-rw-r--r--lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp8
-rw-r--r--lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h9
-rw-r--r--lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp4
-rw-r--r--lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h9
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp157
-rw-r--r--lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h13
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp96
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h14
-rw-r--r--lldb/source/Plugins/Plugins.def.in37
-rw-r--r--lldb/source/Plugins/Process/Darwin/CFBundle.cpp68
-rw-r--r--lldb/source/Plugins/Process/Darwin/CFBundle.h35
-rw-r--r--lldb/source/Plugins/Process/Darwin/CFString.cpp153
-rw-r--r--lldb/source/Plugins/Process/Darwin/CFString.h40
-rw-r--r--lldb/source/Plugins/Process/Darwin/CFUtils.h75
-rw-r--r--lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp638
-rw-r--r--lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.h48
-rw-r--r--lldb/source/Plugins/Process/Darwin/LaunchFlavor.h32
-rw-r--r--lldb/source/Plugins/Process/Darwin/MachException.cpp514
-rw-r--r--lldb/source/Plugins/Process/Darwin/MachException.h139
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp1535
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h337
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp281
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.h165
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp702
-rw-r--r--lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.h138
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp22
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp8
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp6
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp8
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h4
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp2
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp4
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp2
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp614
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h15
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp2
-rw-r--r--lldb/source/Plugins/Process/POSIX/CrashReason.cpp2
-rw-r--r--lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp7
-rw-r--r--lldb/source/Plugins/Process/POSIX/NativeProcessELF.h10
-rw-r--r--lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp2
-rw-r--r--lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/ARMDefines.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/ARMUtils.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/AuxVector.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/AuxVector.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp4
-rw-r--r--lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/FreeBSDSignals.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryThread.cpp8
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryThread.h9
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp13
-rw-r--r--lldb/source/Plugins/Process/Utility/HistoryUnwind.h12
-rw-r--r--lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/InstructionUtils.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxProcMaps.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxSignals.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/LinuxSignals.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/NetBSDSignals.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextDummy.h9
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp3
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextHistory.h10
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp2198
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h259
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp160
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h56
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h7
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextMemory.h10
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp96
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h25
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp59
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h7
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp31
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h11
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp176
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h54
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp13
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h8
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp31
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h11
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp30
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h10
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp30
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h11
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp30
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h11
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h10
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContext_mips.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContext_x86.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h36
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h5
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp127
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h28
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp2
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h4
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h37
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h2
-rw-r--r--lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp63
-rw-r--r--lldb/source/Plugins/Process/Utility/StopInfoMachException.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/ThreadMemory.cpp18
-rw-r--r--lldb/source/Plugins/Process/Utility/ThreadMemory.h9
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp519
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h158
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp247
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h54
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h6
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h11
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.h9
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp12
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp32
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h9
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp2
-rw-r--r--lldb/source/Plugins/Process/elf-core/RegisterUtilities.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp37
-rw-r--r--lldb/source/Plugins/Process/elf-core/ThreadElfCore.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp72
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h13
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp131
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h32
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp39
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h14
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp14
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp360
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h15
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h11
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h14
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp359
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h7
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.h7
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpTypes.h7
-rw-r--r--lldb/source/Plugins/Process/minidump/NtStructures.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp12
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h6
-rw-r--r--lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp2
-rw-r--r--lldb/source/Plugins/Process/minidump/ThreadMinidump.h6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp32
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h1
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp56
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h2
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp4
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp95
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h30
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp230
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h2
-rw-r--r--lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp14
-rw-r--r--lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp54
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp135
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h42
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DIERef.h16
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp1295
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h72
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp34
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h16
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp24
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp45
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h11
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp110
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h16
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp27
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp450
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h47
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp317
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h46
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp50
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp58
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h80
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp216
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h41
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp176
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h55
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp226
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h54
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp273
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h54
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp34
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h19
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp1391
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h117
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp32
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h21
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp91
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h34
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp37
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h39
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp138
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h50
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h5
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp64
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp31
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp90
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp156
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h14
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp95
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h18
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h9
-rw-r--r--lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp4
-rw-r--r--lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h9
-rw-r--r--lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp147
-rw-r--r--lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h45
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp9587
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h1153
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp50
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h6
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp6
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h6
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp2
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h10
603 files changed, 25778 insertions, 24154 deletions
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
new file mode 100644
index 000000000000..5cf9fb4ad37f
--- /dev/null
+++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -0,0 +1,52 @@
+//===-- AArch66.h ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIAArch64.h"
+#include "ABIMacOSX_arm64.h"
+#include "ABISysV_arm64.h"
+#include "Utility/ARM64_DWARF_Registers.h"
+#include "lldb/Core/PluginManager.h"
+
+LLDB_PLUGIN_DEFINE(ABIAArch64)
+
+void ABIAArch64::Initialize() {
+ ABISysV_arm64::Initialize();
+ ABIMacOSX_arm64::Initialize();
+}
+
+void ABIAArch64::Terminate() {
+ ABISysV_arm64::Terminate();
+ ABIMacOSX_arm64::Terminate();
+}
+
+std::pair<uint32_t, uint32_t>
+ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
+ if (name == "pc")
+ return {LLDB_INVALID_REGNUM, arm64_dwarf::pc};
+ if (name == "cpsr")
+ return {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr};
+ return MCBasedABI::GetEHAndDWARFNums(name);
+}
+
+uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) {
+ return llvm::StringSwitch<uint32_t>(name)
+ .Case("pc", LLDB_REGNUM_GENERIC_PC)
+ .Case("lr", LLDB_REGNUM_GENERIC_RA)
+ .Case("sp", LLDB_REGNUM_GENERIC_SP)
+ .Case("fp", LLDB_REGNUM_GENERIC_FP)
+ .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS)
+ .Case("x0", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("x1", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("x2", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("x3", LLDB_REGNUM_GENERIC_ARG4)
+ .Case("x4", LLDB_REGNUM_GENERIC_ARG5)
+ .Case("x5", LLDB_REGNUM_GENERIC_ARG6)
+ .Case("x6", LLDB_REGNUM_GENERIC_ARG7)
+ .Case("x7", LLDB_REGNUM_GENERIC_ARG8)
+ .Default(LLDB_INVALID_REGNUM);
+}
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
new file mode 100644
index 000000000000..981145e2017e
--- /dev/null
+++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
@@ -0,0 +1,32 @@
+//===-- AArch64.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIAARCH64_H
+#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIAARCH64_H
+
+#include "lldb/Target/ABI.h"
+
+class ABIAArch64: public lldb_private::MCBasedABI {
+public:
+ static void Initialize();
+ static void Terminate();
+
+protected:
+ std::pair<uint32_t, uint32_t>
+ GetEHAndDWARFNums(llvm::StringRef name) override;
+
+ std::string GetMCName(std::string reg) override {
+ MapRegisterName(reg, "v", "q");
+ return reg;
+ }
+
+ uint32_t GetGenericNum(llvm::StringRef name) override;
+
+ using lldb_private::MCBasedABI::MCBasedABI;
+};
+#endif
diff --git a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
new file mode 100644
index 000000000000..983da26a2a6d
--- /dev/null
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -0,0 +1,831 @@
+//===-- ABIMacOSX_arm64.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIMacOSX_arm64.h"
+
+#include <vector>
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
+#include "lldb/Utility/Status.h"
+
+#include "Utility/ARM64_DWARF_Registers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
+
+size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; }
+
+// Static Functions
+
+ABISP
+ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
+ const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
+ const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
+
+ if (vendor_type == llvm::Triple::Apple) {
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
+ }
+ }
+
+ return ABISP();
+}
+
+bool ABIMacOSX_arm64::PrepareTrivialCall(
+ Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr,
+ lldb::addr_t return_addr, llvm::ArrayRef<lldb::addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+
+ // x0 - x7 contain first 8 simple args
+ if (args.size() > 8) // TODO handle more than 6 arguments
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+ LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(ra_reg_num), return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(sp_reg_num), sp))
+ return false;
+
+ // Set "pc" to the address requested
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfoAtIndex(pc_reg_num), func_addr))
+ return false;
+
+ return true;
+}
+
+bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread,
+ ValueList &values) const {
+ uint32_t num_values = values.GetSize();
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ addr_t sp = 0;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
+
+ CompilerType value_type = value->GetCompilerType();
+ llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
+
+ bool is_signed = false;
+ size_t bit_width = 0;
+ if (value_type.IsIntegerOrEnumerationType(is_signed)) {
+ bit_width = *bit_size;
+ } else if (value_type.IsPointerOrReferenceType()) {
+ bit_width = *bit_size;
+ } else {
+ // We only handle integer, pointer and reference types currently...
+ return false;
+ }
+
+ if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 8) {
+ // Arguments 1-6 are in x0-x5...
+ const RegisterInfo *reg_info = nullptr;
+ // Search by generic ID first, then fall back to by name
+ uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+ if (arg_reg_num != LLDB_INVALID_REGNUM) {
+ reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+ } else {
+ switch (value_idx) {
+ case 0:
+ reg_info = reg_ctx->GetRegisterInfoByName("x0");
+ break;
+ case 1:
+ reg_info = reg_ctx->GetRegisterInfoByName("x1");
+ break;
+ case 2:
+ reg_info = reg_ctx->GetRegisterInfoByName("x2");
+ break;
+ case 3:
+ reg_info = reg_ctx->GetRegisterInfoByName("x3");
+ break;
+ case 4:
+ reg_info = reg_ctx->GetRegisterInfoByName("x4");
+ break;
+ case 5:
+ reg_info = reg_ctx->GetRegisterInfoByName("x5");
+ break;
+ case 6:
+ reg_info = reg_ctx->GetRegisterInfoByName("x6");
+ break;
+ case 7:
+ reg_info = reg_ctx->GetRegisterInfoByName("x7");
+ break;
+ }
+ }
+
+ if (reg_info) {
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
+ return false;
+ continue;
+ }
+ }
+ return false;
+ } else {
+ if (sp == 0) {
+ // Read the stack pointer if we already haven't read it
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Status error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
+
+ sp += arg_byte_size;
+ // Align up to the next 8 byte boundary if needed
+ if (sp % 8) {
+ sp >>= 3;
+ sp += 1;
+ sp <<= 3;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+Status
+ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Status error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType return_value_type = new_value_sp->GetCompilerType();
+ if (!return_value_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ DataExtractor data;
+ Status data_error;
+ const uint64_t byte_size = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ lldb::offset_t offset = 0;
+ if (byte_size <= 16) {
+ const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
+ if (byte_size <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
+ error.SetErrorString("failed to write register x0");
+ } else {
+ uint64_t raw_value = data.GetMaxU64(&offset, 8);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
+ const RegisterInfo *x1_info =
+ reg_ctx->GetRegisterInfoByName("x1", 0);
+ raw_value = data.GetMaxU64(&offset, byte_size - offset);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
+ error.SetErrorString("failed to write register x1");
+ }
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 128 bit "
+ "integer values at present.");
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ error.SetErrorString(
+ "returning complex float values are not supported");
+ } else {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= 16) {
+ if (byte_size <= RegisterValue::GetMaxByteSize()) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "returning float values with a byte size of %" PRIu64
+ " are not supported",
+ byte_size);
+ }
+ } else {
+ error.SetErrorString("returning float values longer than 128 "
+ "bits are not supported");
+ }
+ } else {
+ error.SetErrorString("v0 register is not available on this target");
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ error.SetErrorString("no registers are available");
+ }
+
+ return error;
+}
+
+bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = arm64_dwarf::lr;
+ uint32_t sp_reg_num = arm64_dwarf::sp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // Our previous PC is in the LR
+ row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = arm64_dwarf::fp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 8;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
+ return true;
+}
+
+// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
+// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
+// volatile (and specifically only the lower 8 bytes of these regs), the rest
+// of the fp/SIMD registers are volatile.
+//
+// v. https://github.com/ARM-software/abi-aa/blob/master/aapcs64/
+
+// We treat x29 as callee preserved also, else the unwinder won't try to
+// retrieve fp saves.
+
+bool ABIMacOSX_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ const char *name = reg_info->name;
+
+ // Sometimes we'll be called with the "alternate" name for these registers;
+ // recognize them as non-volatile.
+
+ if (name[0] == 'p' && name[1] == 'c') // pc
+ return false;
+ if (name[0] == 'f' && name[1] == 'p') // fp
+ return false;
+ if (name[0] == 's' && name[1] == 'p') // sp
+ return false;
+ if (name[0] == 'l' && name[1] == 'r') // lr
+ return false;
+
+ if (name[0] == 'x') {
+ // Volatile registers: x0-x18, x30 (lr)
+ // Return false for the non-volatile gpr regs, true for everything else
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '9':
+ return false; // x19 is non-volatile
+ default:
+ return true;
+ }
+ break;
+ case '2':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ return false; // x20 - 28 are non-volatile
+ case '9':
+ return false; // x29 aka fp treat as non-volatile on Darwin
+ default:
+ return true;
+ }
+ case '3': // x30 aka lr treat as non-volatile
+ if (name[2] == '0')
+ return false;
+ break;
+ default:
+ return true;
+ }
+ } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
+ // Volatile registers: v0-7, v16-v31
+ // Return false for non-volatile fp/SIMD regs, true for everything else
+ switch (name[1]) {
+ case '8':
+ case '9':
+ return false; // v8-v9 are non-volatile
+ case '1':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return false; // v10-v15 are non-volatile
+ default:
+ return true;
+ }
+ default:
+ return true;
+ }
+ }
+ }
+ return true;
+}
+
+static bool LoadValueFromConsecutiveGPRRegisters(
+ ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
+ const CompilerType &value_type,
+ bool is_return_value, // false => parameter, true => return value
+ uint32_t &NGRN, // NGRN (see ABI documentation)
+ uint32_t &NSRN, // NSRN (see ABI documentation)
+ DataExtractor &data) {
+ llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
+ if (!byte_size || *byte_size == 0)
+ return false;
+
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ Status error;
+
+ CompilerType base_type;
+ const uint32_t homogeneous_count =
+ value_type.IsHomogeneousAggregate(&base_type);
+ if (homogeneous_count > 0 && homogeneous_count <= 8) {
+ // Make sure we have enough registers
+ if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
+ if (!base_type)
+ return false;
+ llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ if (!base_byte_size)
+ return false;
+ uint32_t data_offset = 0;
+
+ for (uint32_t i = 0; i < homogeneous_count; ++i) {
+ char v_name[8];
+ ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfoByName(v_name, 0);
+ if (reg_info == nullptr)
+ return false;
+
+ if (*base_byte_size > reg_info->byte_size)
+ return false;
+
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ // Make sure we have enough room in "heap_data_up"
+ if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
+ byte_order, error);
+ if (bytes_copied != *base_byte_size)
+ return false;
+ data_offset += bytes_copied;
+ ++NSRN;
+ } else
+ return false;
+ }
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_up.release()));
+ return true;
+ }
+ }
+
+ const size_t max_reg_byte_size = 16;
+ if (*byte_size <= max_reg_byte_size) {
+ size_t bytes_left = *byte_size;
+ uint32_t data_offset = 0;
+ while (data_offset < *byte_size) {
+ if (NGRN >= 8)
+ return false;
+
+ uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info == nullptr)
+ return false;
+
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
+ byte_order, error);
+ if (bytes_copied == 0)
+ return false;
+ if (bytes_copied >= bytes_left)
+ break;
+ data_offset += bytes_copied;
+ bytes_left -= bytes_copied;
+ ++NGRN;
+ }
+ } else {
+ const RegisterInfo *reg_info = nullptr;
+ if (is_return_value) {
+ // We are assuming we are decoding this immediately after returning from
+ // a function call and that the address of the structure is in x8
+ reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
+ } else {
+ // We are assuming we are stopped at the first instruction in a function
+ // and that the ABI is being respected so all parameters appear where
+ // they should be (functions with no external linkage can legally violate
+ // the ABI).
+ if (NGRN >= 8)
+ return false;
+
+ uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return false;
+ reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info == nullptr)
+ return false;
+ ++NGRN;
+ }
+
+ if (reg_info == nullptr)
+ return false;
+
+ const lldb::addr_t value_addr =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
+
+ if (value_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ if (exe_ctx.GetProcessRef().ReadMemory(
+ value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
+ error) != heap_data_up->GetByteSize()) {
+ return false;
+ }
+ }
+
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_up.release()));
+ return true;
+}
+
+ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ if (*byte_size <= 8) {
+ const RegisterInfo *x0_reg_info =
+ reg_ctx->GetRegisterInfoByName("x0", 0);
+ if (x0_reg_info) {
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
+ 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (*byte_size) {
+ default:
+ break;
+ case 16: // uint128_t
+ // In register x0 and x1
+ {
+ const RegisterInfo *x1_reg_info =
+ reg_ctx->GetRegisterInfoByName("x1", 0);
+
+ if (x1_reg_info) {
+ if (*byte_size <=
+ x0_reg_info->byte_size + x1_reg_info->byte_size) {
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order =
+ exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue x0_reg_value;
+ RegisterValue x1_reg_value;
+ if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
+ reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
+ Status error;
+ if (x0_reg_value.GetAsMemoryData(
+ x0_reg_info, heap_data_up->GetBytes() + 0, 8,
+ byte_order, error) &&
+ x1_reg_value.GetAsMemoryData(
+ x1_reg_info, heap_data_up->GetBytes() + 8, 8,
+ byte_order, error)) {
+ DataExtractor data(
+ DataBufferSP(heap_data_up.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ return return_valobj_sp;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ if (*byte_size <= sizeof(long double)) {
+ const RegisterInfo *v0_reg_info =
+ reg_ctx->GetRegisterInfoByName("v0", 0);
+ RegisterValue v0_value;
+ if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
+ DataExtractor data;
+ if (v0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (*byte_size == sizeof(float)) {
+ value.GetScalar() = data.GetFloat(&offset);
+ success = true;
+ } else if (*byte_size == sizeof(double)) {
+ value.GetScalar() = data.GetDouble(&offset);
+ success = true;
+ } else if (*byte_size == sizeof(long double)) {
+ value.GetScalar() = data.GetLongDouble(&offset);
+ success = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector) {
+ if (*byte_size > 0) {
+
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (*byte_size <= v0_info->byte_size) {
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(v0_info, reg_value)) {
+ Status error;
+ if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(),
+ heap_data_up->GetByteSize(),
+ byte_order, error)) {
+ DataExtractor data(DataBufferSP(heap_data_up.release()),
+ byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
+ DataExtractor data;
+
+ uint32_t NGRN = 0; // Search ABI docs for NGRN
+ uint32_t NSRN = 0; // Search ABI docs for NSRN
+ const bool is_return_value = true;
+ if (LoadValueFromConsecutiveGPRRegisters(
+ exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
+ data)) {
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ return return_valobj_sp;
+}
+
+void ABIMacOSX_arm64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
+ CreateInstance);
+}
+
+void ABIMacOSX_arm64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+// PluginInterface protocol
+
+ConstString ABIMacOSX_arm64::GetPluginNameStatic() {
+ static ConstString g_plugin_name("ABIMacOSX_arm64");
+ return g_plugin_name;
+}
+
+uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
index c7a91ba9c468..fc8ccee92e71 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABIMacOSX_arm64_h_
-#define liblldb_ABIMacOSX_arm64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H
+#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H
-#include "lldb/Target/ABI.h"
+#include "Plugins/ABI/AArch64/ABIAArch64.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
-class ABIMacOSX_arm64 : public lldb_private::ABI {
+class ABIMacOSX_arm64 : public ABIAArch64 {
public:
~ABIMacOSX_arm64() override = default;
@@ -42,7 +42,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -62,9 +62,6 @@ public:
return true;
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
// Static Functions
static void Initialize();
@@ -93,11 +90,7 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using ABIAArch64::ABIAArch64; // Call CreateInstance instead.
};
-#endif // liblldb_ABIMacOSX_arm64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABIMACOSX_ARM64_H
diff --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
new file mode 100644
index 000000000000..831c8aa0d760
--- /dev/null
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -0,0 +1,800 @@
+//===-- ABISysV_arm64.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABISysV_arm64.h"
+
+#include <vector>
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
+#include "lldb/Utility/Status.h"
+
+#include "Utility/ARM64_DWARF_Registers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) {
+ name = "x0";
+ return true;
+}
+
+size_t ABISysV_arm64::GetRedZoneSize() const { return 128; }
+
+// Static Functions
+
+ABISP
+ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
+ const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
+ const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
+
+ if (vendor_type != llvm::Triple::Apple) {
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
+ }
+ }
+
+ return ABISP();
+}
+
+bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log) {
+ StreamString s;
+ s.Printf("ABISysV_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
+ ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
+ ", return_addr = 0x%" PRIx64,
+ thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
+ (uint64_t)return_addr);
+
+ for (size_t i = 0; i < args.size(); ++i)
+ s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
+ s.PutCString(")");
+ log->PutString(s.GetString());
+ }
+
+ // x0 - x7 contain first 8 simple args
+ if (args.size() > 8)
+ return false;
+
+ for (size_t i = 0; i < args.size(); ++i) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+ LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
+ static_cast<int>(i + 1), args[i], reg_info->name);
+ if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+ return false;
+ }
+
+ // Set "lr" to the return address
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA),
+ return_addr))
+ return false;
+
+ // Set "sp" to the requested value
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_SP),
+ sp))
+ return false;
+
+ // Set "pc" to the address requested
+ if (!reg_ctx->WriteRegisterFromUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC),
+ func_addr))
+ return false;
+
+ return true;
+}
+
+// TODO: We dont support fp/SIMD arguments in v0-v7
+bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
+ uint32_t num_values = values.GetSize();
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ addr_t sp = 0;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
+ // We currently only support extracting values with Clang QualTypes. Do we
+ // care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
+
+ CompilerType value_type = value->GetCompilerType();
+ if (value_type) {
+ bool is_signed = false;
+ size_t bit_width = 0;
+ llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
+ if (value_type.IsIntegerOrEnumerationType(is_signed)) {
+ bit_width = *bit_size;
+ } else if (value_type.IsPointerOrReferenceType()) {
+ bit_width = *bit_size;
+ } else {
+ // We only handle integer, pointer and reference types currently...
+ return false;
+ }
+
+ if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 8) {
+ // Arguments 1-8 are in x0-x7...
+ const RegisterInfo *reg_info = nullptr;
+ reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+
+ if (reg_info) {
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
+ return false;
+ continue;
+ }
+ }
+ return false;
+ } else {
+ // TODO: Verify for stack layout for SysV
+ if (sp == 0) {
+ // Read the stack pointer if we already haven't read it
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Status error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
+
+ sp += arg_byte_size;
+ // Align up to the next 8 byte boundary if needed
+ if (sp % 8) {
+ sp >>= 3;
+ sp += 1;
+ sp <<= 3;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value_sp) {
+ Status error;
+ if (!new_value_sp) {
+ error.SetErrorString("Empty value object for return value.");
+ return error;
+ }
+
+ CompilerType return_value_type = new_value_sp->GetCompilerType();
+ if (!return_value_type) {
+ error.SetErrorString("Null clang type for return value.");
+ return error;
+ }
+
+ Thread *thread = frame_sp->GetThread().get();
+
+ RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ DataExtractor data;
+ Status data_error;
+ const uint64_t byte_size = new_value_sp->GetData(data, data_error);
+ if (data_error.Fail()) {
+ error.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s",
+ data_error.AsCString());
+ return error;
+ }
+
+ const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ lldb::offset_t offset = 0;
+ if (byte_size <= 16) {
+ const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ if (byte_size <= 8) {
+ uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
+ error.SetErrorString("failed to write register x0");
+ } else {
+ uint64_t raw_value = data.GetMaxU64(&offset, 8);
+
+ if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
+ const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ raw_value = data.GetMaxU64(&offset, byte_size - offset);
+
+ if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
+ error.SetErrorString("failed to write register x1");
+ }
+ }
+ } else {
+ error.SetErrorString("We don't support returning longer than 128 bit "
+ "integer values at present.");
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ error.SetErrorString(
+ "returning complex float values are not supported");
+ } else {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= 16) {
+ if (byte_size <= RegisterValue::GetMaxByteSize()) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "returning float values with a byte size of %" PRIu64
+ " are not supported",
+ byte_size);
+ }
+ } else {
+ error.SetErrorString("returning float values longer than 128 "
+ "bits are not supported");
+ }
+ } else {
+ error.SetErrorString("v0 register is not available on this target");
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsVector) {
+ if (byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ if (byte_size <= v0_info->byte_size) {
+ RegisterValue reg_value;
+ error = reg_value.SetValueFromData(v0_info, data, 0, true);
+ if (error.Success()) {
+ if (!reg_ctx->WriteRegister(v0_info, reg_value))
+ error.SetErrorString("failed to write register v0");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ error.SetErrorString("no registers are available");
+ }
+
+ return error;
+}
+
+bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t lr_reg_num = arm64_dwarf::lr;
+ uint32_t sp_reg_num = arm64_dwarf::sp;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our previous Call Frame Address is the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetReturnAddressRegister(lr_reg_num);
+
+ // All other registers are the same.
+
+ unwind_plan.SetSourceName("arm64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ uint32_t fp_reg_num = arm64_dwarf::fp;
+ uint32_t pc_reg_num = arm64_dwarf::pc;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+ const int32_t ptr_size = 8;
+
+ row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
+ row->SetOffset(0);
+
+ row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+ row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("arm64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
+
+ return true;
+}
+
+// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
+// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
+// volatile (and specifically only the lower 8 bytes of these regs), the rest
+// of the fp/SIMD registers are volatile.
+
+// We treat x29 as callee preserved also, else the unwinder won't try to
+// retrieve fp saves.
+
+bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (reg_info) {
+ const char *name = reg_info->name;
+
+ // Sometimes we'll be called with the "alternate" name for these registers;
+ // recognize them as non-volatile.
+
+ if (name[0] == 'p' && name[1] == 'c') // pc
+ return false;
+ if (name[0] == 'f' && name[1] == 'p') // fp
+ return false;
+ if (name[0] == 's' && name[1] == 'p') // sp
+ return false;
+ if (name[0] == 'l' && name[1] == 'r') // lr
+ return false;
+
+ if (name[0] == 'x' || name[0] == 'r') {
+ // Volatile registers: x0-x18
+ // Although documentation says only x19-28 + sp are callee saved We ll
+ // also have to treat x30 as non-volatile. Each dwarf frame has its own
+ // value of lr. Return false for the non-volatile gpr regs, true for
+ // everything else
+ switch (name[1]) {
+ case '1':
+ switch (name[2]) {
+ case '9':
+ return false; // x19 is non-volatile
+ default:
+ return true;
+ }
+ break;
+ case '2':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ return false; // x20 - 28 are non-volatile
+ case '9':
+ return false; // x29 aka fp treat as non-volatile
+ default:
+ return true;
+ }
+ case '3': // x30 (lr) and x31 (sp) treat as non-volatile
+ if (name[2] == '0' || name[2] == '1')
+ return false;
+ break;
+ default:
+ return true; // all volatile cases not handled above fall here.
+ }
+ } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
+ // Volatile registers: v0-7, v16-v31
+ // Return false for non-volatile fp/SIMD regs, true for everything else
+ switch (name[1]) {
+ case '8':
+ case '9':
+ return false; // v8-v9 are non-volatile
+ case '1':
+ switch (name[2]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return false; // v10-v15 are non-volatile
+ default:
+ return true;
+ }
+ default:
+ return true;
+ }
+ }
+ }
+ return true;
+}
+
+static bool LoadValueFromConsecutiveGPRRegisters(
+ ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
+ const CompilerType &value_type,
+ bool is_return_value, // false => parameter, true => return value
+ uint32_t &NGRN, // NGRN (see ABI documentation)
+ uint32_t &NSRN, // NSRN (see ABI documentation)
+ DataExtractor &data) {
+ llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
+
+ if (byte_size || *byte_size == 0)
+ return false;
+
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ Status error;
+
+ CompilerType base_type;
+ const uint32_t homogeneous_count =
+ value_type.IsHomogeneousAggregate(&base_type);
+ if (homogeneous_count > 0 && homogeneous_count <= 8) {
+ // Make sure we have enough registers
+ if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
+ if (!base_type)
+ return false;
+ llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ if (!base_byte_size)
+ return false;
+ uint32_t data_offset = 0;
+
+ for (uint32_t i = 0; i < homogeneous_count; ++i) {
+ char v_name[8];
+ ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfoByName(v_name, 0);
+ if (reg_info == nullptr)
+ return false;
+
+ if (*base_byte_size > reg_info->byte_size)
+ return false;
+
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ // Make sure we have enough room in "heap_data_up"
+ if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
+ byte_order, error);
+ if (bytes_copied != *base_byte_size)
+ return false;
+ data_offset += bytes_copied;
+ ++NSRN;
+ } else
+ return false;
+ }
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_up.release()));
+ return true;
+ }
+ }
+
+ const size_t max_reg_byte_size = 16;
+ if (*byte_size <= max_reg_byte_size) {
+ size_t bytes_left = *byte_size;
+ uint32_t data_offset = 0;
+ while (data_offset < *byte_size) {
+ if (NGRN >= 8)
+ return false;
+
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_info == nullptr)
+ return false;
+
+ RegisterValue reg_value;
+
+ if (!reg_ctx->ReadRegister(reg_info, reg_value))
+ return false;
+
+ const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
+ const size_t bytes_copied = reg_value.GetAsMemoryData(
+ reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
+ byte_order, error);
+ if (bytes_copied == 0)
+ return false;
+ if (bytes_copied >= bytes_left)
+ break;
+ data_offset += bytes_copied;
+ bytes_left -= bytes_copied;
+ ++NGRN;
+ }
+ } else {
+ const RegisterInfo *reg_info = nullptr;
+ if (is_return_value) {
+ // We are assuming we are decoding this immediately after returning from
+ // a function call and that the address of the structure is in x8
+ reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
+ } else {
+ // We are assuming we are stopped at the first instruction in a function
+ // and that the ABI is being respected so all parameters appear where
+ // they should be (functions with no external linkage can legally violate
+ // the ABI).
+ if (NGRN >= 8)
+ return false;
+
+ reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+ if (reg_info == nullptr)
+ return false;
+ ++NGRN;
+ }
+
+ if (reg_info == nullptr)
+ return false;
+
+ const lldb::addr_t value_addr =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
+
+ if (value_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ if (exe_ctx.GetProcessRef().ReadMemory(
+ value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
+ error) != heap_data_up->GetByteSize()) {
+ return false;
+ }
+ }
+
+ data.SetByteOrder(byte_order);
+ data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+ data.SetData(DataBufferSP(heap_data_up.release()));
+ return true;
+}
+
+ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+ Value value;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
+ return return_valobj_sp;
+
+ // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
+ value.SetCompilerType(return_compiler_type);
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+ if (!reg_ctx)
+ return return_valobj_sp;
+
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
+
+ const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
+ if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
+ // Extract the register context so we can read arguments from registers
+ if (*byte_size <= 8) {
+ const RegisterInfo *x0_reg_info = nullptr;
+ x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ if (x0_reg_info) {
+ uint64_t raw_value =
+ thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
+ 0);
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ switch (*byte_size) {
+ default:
+ break;
+ case 16: // uint128_t
+ // In register x0 and x1
+ {
+ const RegisterInfo *x1_reg_info = nullptr;
+ x1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG2);
+
+ if (x1_reg_info) {
+ if (*byte_size <=
+ x0_reg_info->byte_size + x1_reg_info->byte_size) {
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order =
+ exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue x0_reg_value;
+ RegisterValue x1_reg_value;
+ if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
+ reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
+ Status error;
+ if (x0_reg_value.GetAsMemoryData(
+ x0_reg_info, heap_data_up->GetBytes() + 0, 8,
+ byte_order, error) &&
+ x1_reg_value.GetAsMemoryData(
+ x1_reg_info, heap_data_up->GetBytes() + 8, 8,
+ byte_order, error)) {
+ DataExtractor data(
+ DataBufferSP(heap_data_up.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ return return_valobj_sp;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsFloat) {
+ if (type_flags & eTypeIsComplex) {
+ // Don't handle complex yet.
+ } else {
+ if (*byte_size <= sizeof(long double)) {
+ const RegisterInfo *v0_reg_info =
+ reg_ctx->GetRegisterInfoByName("v0", 0);
+ RegisterValue v0_value;
+ if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
+ DataExtractor data;
+ if (v0_value.GetData(data)) {
+ lldb::offset_t offset = 0;
+ if (*byte_size == sizeof(float)) {
+ value.GetScalar() = data.GetFloat(&offset);
+ success = true;
+ } else if (*byte_size == sizeof(double)) {
+ value.GetScalar() = data.GetDouble(&offset);
+ success = true;
+ } else if (*byte_size == sizeof(long double)) {
+ value.GetScalar() = data.GetLongDouble(&offset);
+ success = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create(
+ thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
+ } else if (type_flags & eTypeIsVector && *byte_size <= 16) {
+ if (*byte_size > 0) {
+ const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+ if (v0_info) {
+ std::unique_ptr<DataBufferHeap> heap_data_up(
+ new DataBufferHeap(*byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(v0_info, reg_value)) {
+ Status error;
+ if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(),
+ heap_data_up->GetByteSize(), byte_order,
+ error)) {
+ DataExtractor data(DataBufferSP(heap_data_up.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ }
+ }
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
+ (type_flags & eTypeIsVector && *byte_size > 16)) {
+ DataExtractor data;
+
+ uint32_t NGRN = 0; // Search ABI docs for NGRN
+ uint32_t NSRN = 0; // Search ABI docs for NSRN
+ const bool is_return_value = true;
+ if (LoadValueFromConsecutiveGPRRegisters(
+ exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
+ data)) {
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
+ }
+ }
+ return return_valobj_sp;
+}
+
+void ABISysV_arm64::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "SysV ABI for AArch64 targets", CreateInstance);
+}
+
+void ABISysV_arm64::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() {
+ static ConstString g_name("SysV-arm64");
+ return g_name;
+}
+
+// PluginInterface protocol
+
+ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ABISysV_arm64::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
index 1bf5773e2db3..aeb74acc38b5 100644
--- a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_arm64_h_
-#define liblldb_ABISysV_arm64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H
+#define LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H
-#include "lldb/Target/ABI.h"
+#include "Plugins/ABI/AArch64/ABIAArch64.h"
#include "lldb/lldb-private.h"
-class ABISysV_arm64 : public lldb_private::ABI {
+class ABISysV_arm64 : public ABIAArch64 {
public:
~ABISysV_arm64() override = default;
@@ -45,7 +45,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -65,9 +65,6 @@ public:
return true;
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
bool GetPointerReturnRegister(const char *&name) override;
// Static Functions
@@ -92,11 +89,7 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using ABIAArch64::ABIAArch64; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_arm64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_AARCH64_ABISYSV_ARM64_H
diff --git a/lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp b/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
index 715b5e5d2b95..a212eef2ab8a 100644
--- a/lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
+++ b/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_arc.cpp ---------------------------------------*- C++ -*-===//
+//===-- ABISysV_arc.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -55,6 +55,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(ABISysV_arc, ABIARC)
+
namespace {
namespace dwarf {
enum regnums {
@@ -144,7 +146,7 @@ size_t ABISysV_arc::GetRedZoneSize() const { return 0; }
bool ABISysV_arc::IsRegisterFileReduced(RegisterContext &reg_ctx) const {
if (!m_is_reg_file_reduced) {
const auto *const rf_build_reg = reg_ctx.GetRegisterInfoByName("rf_build");
-
+
const auto reg_value = reg_ctx.ReadRegisterAsUnsigned(rf_build_reg,
/*fail_value*/ 0);
// RF_BUILD "Number of Entries" bit.
@@ -239,7 +241,7 @@ bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc,
// Make sure number of parameters matches prototype.
assert(!prototype.isFunctionVarArg());
assert(prototype.getFunctionNumParams() == args.size());
-
+
const size_t regs_for_args_count = IsRegisterFileReduced(*reg_ctx) ? 4U : 8U;
// Number of arguments passed on stack.
@@ -520,7 +522,7 @@ ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
// Integer return type.
else if (retType.isIntegerTy()) {
size_t byte_size = retType.getPrimitiveSizeInBits();
- if (1 != byte_size) // For boolian type.
+ if (1 != byte_size) // For boolean type.
byte_size /= CHAR_BIT;
auto raw_value = ReadRawValue(reg_ctx, byte_size);
diff --git a/lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.h b/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
index c4b26a54158c..3fbe64b4b45b 100644
--- a/lldb/source/Plugins/ABI/SysV-arc/ABISysV_arc.h
+++ b/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h
@@ -16,7 +16,7 @@
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_arc : public lldb_private::ABI {
+class ABISysV_arc : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_arc() override = default;
@@ -97,7 +97,7 @@ private:
bool IsRegisterFileReduced(lldb_private::RegisterContext &reg_ctx) const;
- using lldb_private::ABI::ABI; // Call CreateInstance instead.
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
using RegisterFileFlag = llvm::Optional<bool>;
mutable RegisterFileFlag m_is_reg_file_reduced;
diff --git a/lldb/source/Plugins/ABI/ARM/ABIARM.cpp b/lldb/source/Plugins/ABI/ARM/ABIARM.cpp
new file mode 100644
index 000000000000..882c14d386e3
--- /dev/null
+++ b/lldb/source/Plugins/ABI/ARM/ABIARM.cpp
@@ -0,0 +1,24 @@
+//===-- ARM.h -------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIARM.h"
+#include "ABIMacOSX_arm.h"
+#include "ABISysV_arm.h"
+#include "lldb/Core/PluginManager.h"
+
+LLDB_PLUGIN_DEFINE(ABIARM)
+
+void ABIARM::Initialize() {
+ ABISysV_arm::Initialize();
+ ABIMacOSX_arm::Initialize();
+}
+
+void ABIARM::Terminate() {
+ ABISysV_arm::Terminate();
+ ABIMacOSX_arm::Terminate();
+}
diff --git a/lldb/source/Plugins/ABI/ARM/ABIARM.h b/lldb/source/Plugins/ABI/ARM/ABIARM.h
new file mode 100644
index 000000000000..7d04f1c9eb0f
--- /dev/null
+++ b/lldb/source/Plugins/ABI/ARM/ABIARM.h
@@ -0,0 +1,17 @@
+//===-- ARM.h -------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABIARM_H
+#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABIARM_H
+
+class ABIARM {
+public:
+ static void Initialize();
+ static void Terminate();
+};
+#endif
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
index 9dff12bcc748..ef500cb198a8 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
@@ -1,4 +1,4 @@
-//===-- ABIMacOSX_arm.cpp ---------------------------------------*- C++ -*-===//
+//===-- ABIMacOSX_arm.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
index e512651f86e5..e0fa349eea73 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
+++ b/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABIMacOSX_arm_h_
-#define liblldb_ABIMacOSX_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H
+#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABIMacOSX_arm : public lldb_private::ABI {
+class ABIMacOSX_arm : public lldb_private::RegInfoBasedABI {
public:
~ABIMacOSX_arm() override = default;
@@ -85,11 +85,7 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABIMacOSX_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_ARM_ABIMACOSX_ARM_H
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
index b6e8f8806829..1a93bac564f7 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_arm.cpp -----------------------------------------*- C++ -*-===//
+//===-- ABISysV_arm.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -34,6 +34,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_arm)
+
static RegisterInfo g_register_infos[] = {
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
// DWARF GENERIC PROCESS PLUGIN
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
index 60fb14be5f7b..f28f75ce4fe5 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_arm_h_
-#define liblldb_ABISysV_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H
+#define LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_arm : public lldb_private::ABI {
+class ABISysV_arm : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_arm() override = default;
@@ -85,11 +85,7 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_ARM_ABISYSV_ARM_H
diff --git a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
index 34d9258ccb92..32313d4cd815 100644
--- a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_hexagon.cpp -------------------------------------*- C++ -*-===//
+//===-- ABISysV_hexagon.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)
+
static RegisterInfo g_register_infos[] = {
// hexagon-core.xml
{"r00",
diff --git a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
index bef64a22d95f..d6dab0c2e378 100644
--- a/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
+++ b/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_hexagon_h_
-#define liblldb_ABISysV_hexagon_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H
+#define LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_hexagon : public lldb_private::ABI {
+class ABISysV_hexagon : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_hexagon() override = default;
@@ -97,11 +97,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_hexagon(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_hexagon_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_HEXAGON_ABISYSV_HEXAGON_H
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
deleted file mode 100644
index ec7588dfb50c..000000000000
--- a/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ /dev/null
@@ -1,2451 +0,0 @@
-//===-- ABIMacOSX_arm64.cpp -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "ABIMacOSX_arm64.h"
-
-#include <vector>
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/Status.h"
-
-#include "Utility/ARM64_DWARF_Registers.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
-
-static RegisterInfo g_register_infos[] = {
- // NAME ALT SZ OFF ENCODING FORMAT
- // EH_FRAME DWARF GENERIC
- // PROCESS PLUGIN LLDB NATIVE
- // ========== ======= == === ============= ===================
- // =================== ====================== ===========================
- // ======================= ======================
- {"x0",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x1",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x2",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x3",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x4",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x5",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x6",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x7",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x8",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x9",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x10",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x11",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x12",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x13",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x14",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x15",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x16",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x17",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x18",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x19",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x20",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x21",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x22",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x23",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x24",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x25",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x26",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x27",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x28",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fp",
- "x29",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"lr",
- "x30",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"sp",
- "x31",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"pc",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"cpsr",
- "psr",
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"v0",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v1",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v2",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v3",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v4",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v5",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v6",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v7",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v8",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v9",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v10",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v11",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v12",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v13",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v14",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v15",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v16",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v17",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v18",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v19",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v20",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v21",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v22",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v23",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v24",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v25",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v26",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v27",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v28",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v29",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v30",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v31",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"fpsr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fpcr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"s0",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s1",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s2",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s3",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s4",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s5",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s6",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s7",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s8",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s9",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s10",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s11",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s12",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s13",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s14",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s15",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s16",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s17",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s18",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s19",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s20",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s21",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s22",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s23",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s24",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s25",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s26",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s27",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s28",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s29",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s30",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s31",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"d0",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d1",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d2",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d3",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d4",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d5",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d6",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d7",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d8",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d9",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d10",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d11",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d12",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d13",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d14",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d15",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d16",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d17",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d18",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d19",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d20",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d21",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d22",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d23",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d24",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d25",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d26",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d27",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d28",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d29",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d30",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d31",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0}};
-
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABIMacOSX_arm64::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
-size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; }
-
-// Static Functions
-
-ABISP
-ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
- const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
- const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
-
- if (vendor_type == llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64 ||
- arch_type == llvm::Triple::aarch64_32) {
- return ABISP(
- new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
- }
- }
-
- return ABISP();
-}
-
-bool ABIMacOSX_arm64::PrepareTrivialCall(
- Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr,
- lldb::addr_t return_addr, llvm::ArrayRef<lldb::addr_t> args) const {
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log) {
- StreamString s;
- s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
- ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
- ", return_addr = 0x%" PRIx64,
- thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
- s.PutCString(")");
- log->PutString(s.GetString());
- }
-
- const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
- const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
-
- // x0 - x7 contain first 8 simple args
- if (args.size() > 8) // TODO handle more than 6 arguments
- return false;
-
- for (size_t i = 0; i < args.size(); ++i) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
-
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfoAtIndex(ra_reg_num), return_addr))
- return false;
-
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfoAtIndex(sp_reg_num), sp))
- return false;
-
- // Set "pc" to the address requested
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfoAtIndex(pc_reg_num), func_addr))
- return false;
-
- return true;
-}
-
-bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread,
- ValueList &values) const {
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx(thread.shared_from_this());
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- addr_t sp = 0;
-
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes. Do we
- // care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- return false;
-
- CompilerType value_type = value->GetCompilerType();
- llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
- if (!bit_size)
- return false;
-
- bool is_signed = false;
- size_t bit_width = 0;
- if (value_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = *bit_size;
- } else if (value_type.IsPointerOrReferenceType()) {
- bit_width = *bit_size;
- } else {
- // We only handle integer, pointer and reference types currently...
- return false;
- }
-
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
- if (value_idx < 8) {
- // Arguments 1-6 are in x0-x5...
- const RegisterInfo *reg_info = nullptr;
- // Search by generic ID first, then fall back to by name
- uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
- if (arg_reg_num != LLDB_INVALID_REGNUM) {
- reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
- } else {
- switch (value_idx) {
- case 0:
- reg_info = reg_ctx->GetRegisterInfoByName("x0");
- break;
- case 1:
- reg_info = reg_ctx->GetRegisterInfoByName("x1");
- break;
- case 2:
- reg_info = reg_ctx->GetRegisterInfoByName("x2");
- break;
- case 3:
- reg_info = reg_ctx->GetRegisterInfoByName("x3");
- break;
- case 4:
- reg_info = reg_ctx->GetRegisterInfoByName("x4");
- break;
- case 5:
- reg_info = reg_ctx->GetRegisterInfoByName("x5");
- break;
- case 6:
- reg_info = reg_ctx->GetRegisterInfoByName("x6");
- break;
- case 7:
- reg_info = reg_ctx->GetRegisterInfoByName("x7");
- break;
- }
- }
-
- if (reg_info) {
- RegisterValue reg_value;
-
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (is_signed)
- reg_value.SignExtend(bit_width);
- if (!reg_value.GetScalarValue(value->GetScalar()))
- return false;
- continue;
- }
- }
- return false;
- } else {
- if (sp == 0) {
- // Read the stack pointer if we already haven't read it
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
- return false;
- }
-
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
- Status error;
- if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
- sp, arg_byte_size, is_signed, value->GetScalar(), error))
- return false;
-
- sp += arg_byte_size;
- // Align up to the next 8 byte boundary if needed
- if (sp % 8) {
- sp >>= 3;
- sp += 1;
- sp <<= 3;
- }
- }
- }
- }
- return true;
-}
-
-Status
-ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
- lldb::ValueObjectSP &new_value_sp) {
- Status error;
- if (!new_value_sp) {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType return_value_type = new_value_sp->GetCompilerType();
- if (!return_value_type) {
- error.SetErrorString("Null clang type for return value.");
- return error;
- }
-
- Thread *thread = frame_sp->GetThread().get();
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- if (reg_ctx) {
- DataExtractor data;
- Status data_error;
- const uint64_t byte_size = new_value_sp->GetData(data, data_error);
- if (data_error.Fail()) {
- error.SetErrorStringWithFormat(
- "Couldn't convert return value to raw data: %s",
- data_error.AsCString());
- return error;
- }
-
- const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
- // Extract the register context so we can read arguments from registers
- lldb::offset_t offset = 0;
- if (byte_size <= 16) {
- const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
- if (byte_size <= 8) {
- uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
-
- if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
- error.SetErrorString("failed to write register x0");
- } else {
- uint64_t raw_value = data.GetMaxU64(&offset, 8);
-
- if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
- const RegisterInfo *x1_info =
- reg_ctx->GetRegisterInfoByName("x1", 0);
- raw_value = data.GetMaxU64(&offset, byte_size - offset);
-
- if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
- error.SetErrorString("failed to write register x1");
- }
- }
- } else {
- error.SetErrorString("We don't support returning longer than 128 bit "
- "integer values at present.");
- }
- } else if (type_flags & eTypeIsFloat) {
- if (type_flags & eTypeIsComplex) {
- // Don't handle complex yet.
- error.SetErrorString(
- "returning complex float values are not supported");
- } else {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- if (byte_size <= 16) {
- if (byte_size <= RegisterValue::GetMaxByteSize()) {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData(v0_info, data, 0, true);
- if (error.Success()) {
- if (!reg_ctx->WriteRegister(v0_info, reg_value))
- error.SetErrorString("failed to write register v0");
- }
- } else {
- error.SetErrorStringWithFormat(
- "returning float values with a byte size of %" PRIu64
- " are not supported",
- byte_size);
- }
- } else {
- error.SetErrorString("returning float values longer than 128 "
- "bits are not supported");
- }
- } else {
- error.SetErrorString("v0 register is not available on this target");
- }
- }
- }
- } else if (type_flags & eTypeIsVector) {
- if (byte_size > 0) {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- if (byte_size <= v0_info->byte_size) {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData(v0_info, data, 0, true);
- if (error.Success()) {
- if (!reg_ctx->WriteRegister(v0_info, reg_value))
- error.SetErrorString("failed to write register v0");
- }
- }
- }
- }
- }
- } else {
- error.SetErrorString("no registers are available");
- }
-
- return error;
-}
-
-bool ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
-
- uint32_t lr_reg_num = arm64_dwarf::lr;
- uint32_t sp_reg_num = arm64_dwarf::sp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
-
- // Our previous PC is in the LR
- row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
-
- unwind_plan.AppendRow(row);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName("arm64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
-
- return true;
-}
-
-bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
-
- uint32_t fp_reg_num = arm64_dwarf::fp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 8;
-
- row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
- row->SetOffset(0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
- unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
- return true;
-}
-
-// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
-// volatile (and specifically only the lower 8 bytes of these regs), the rest
-// of the fp/SIMD registers are volatile.
-//
-// v. https://github.com/ARM-software/software-standards/blob/master/abi/aapcs64/
-
-// We treat x29 as callee preserved also, else the unwinder won't try to
-// retrieve fp saves.
-
-bool ABIMacOSX_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
- if (reg_info) {
- const char *name = reg_info->name;
-
- // Sometimes we'll be called with the "alternate" name for these registers;
- // recognize them as non-volatile.
-
- if (name[0] == 'p' && name[1] == 'c') // pc
- return false;
- if (name[0] == 'f' && name[1] == 'p') // fp
- return false;
- if (name[0] == 's' && name[1] == 'p') // sp
- return false;
- if (name[0] == 'l' && name[1] == 'r') // lr
- return false;
-
- if (name[0] == 'x') {
- // Volatile registers: x0-x18, x30 (lr)
- // Return false for the non-volatile gpr regs, true for everything else
- switch (name[1]) {
- case '1':
- switch (name[2]) {
- case '9':
- return false; // x19 is non-volatile
- default:
- return true;
- }
- break;
- case '2':
- switch (name[2]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- return false; // x20 - 28 are non-volatile
- case '9':
- return false; // x29 aka fp treat as non-volatile on Darwin
- default:
- return true;
- }
- case '3': // x30 aka lr treat as non-volatile
- if (name[2] == '0')
- return false;
- break;
- default:
- return true;
- }
- } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
- // Volatile registers: v0-7, v16-v31
- // Return false for non-volatile fp/SIMD regs, true for everything else
- switch (name[1]) {
- case '8':
- case '9':
- return false; // v8-v9 are non-volatile
- case '1':
- switch (name[2]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return false; // v10-v15 are non-volatile
- default:
- return true;
- }
- default:
- return true;
- }
- }
- }
- return true;
-}
-
-static bool LoadValueFromConsecutiveGPRRegisters(
- ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
- const CompilerType &value_type,
- bool is_return_value, // false => parameter, true => return value
- uint32_t &NGRN, // NGRN (see ABI documentation)
- uint32_t &NSRN, // NSRN (see ABI documentation)
- DataExtractor &data) {
- llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
- if (!byte_size || *byte_size == 0)
- return false;
-
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- Status error;
-
- CompilerType base_type;
- const uint32_t homogeneous_count =
- value_type.IsHomogeneousAggregate(&base_type);
- if (homogeneous_count > 0 && homogeneous_count <= 8) {
- // Make sure we have enough registers
- if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
- if (!base_type)
- return false;
- llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
- if (!base_byte_size)
- return false;
- uint32_t data_offset = 0;
-
- for (uint32_t i = 0; i < homogeneous_count; ++i) {
- char v_name[8];
- ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
- const RegisterInfo *reg_info =
- reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == nullptr)
- return false;
-
- if (*base_byte_size > reg_info->byte_size)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- // Make sure we have enough room in "heap_data_up"
- if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
- const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
- byte_order, error);
- if (bytes_copied != *base_byte_size)
- return false;
- data_offset += bytes_copied;
- ++NSRN;
- } else
- return false;
- }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP(heap_data_up.release()));
- return true;
- }
- }
-
- const size_t max_reg_byte_size = 16;
- if (*byte_size <= max_reg_byte_size) {
- size_t bytes_left = *byte_size;
- uint32_t data_offset = 0;
- while (data_offset < *byte_size) {
- if (NGRN >= 8)
- return false;
-
- uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_num == LLDB_INVALID_REGNUM)
- return false;
-
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == nullptr)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
- const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
- byte_order, error);
- if (bytes_copied == 0)
- return false;
- if (bytes_copied >= bytes_left)
- break;
- data_offset += bytes_copied;
- bytes_left -= bytes_copied;
- ++NGRN;
- }
- } else {
- const RegisterInfo *reg_info = nullptr;
- if (is_return_value) {
- // We are assuming we are decoding this immediately after returning from
- // a function call and that the address of the structure is in x8
- reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
- } else {
- // We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where
- // they should be (functions with no external linkage can legally violate
- // the ABI).
- if (NGRN >= 8)
- return false;
-
- uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_num == LLDB_INVALID_REGNUM)
- return false;
- reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
- if (reg_info == nullptr)
- return false;
- ++NGRN;
- }
-
- if (reg_info == nullptr)
- return false;
-
- const lldb::addr_t value_addr =
- reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
-
- if (value_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- if (exe_ctx.GetProcessRef().ReadMemory(
- value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
- error) != heap_data_up->GetByteSize()) {
- return false;
- }
- }
-
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP(heap_data_up.release()));
- return true;
-}
-
-ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
- Thread &thread, CompilerType &return_compiler_type) const {
- ValueObjectSP return_valobj_sp;
- Value value;
-
- ExecutionContext exe_ctx(thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
-
- // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
- if (!byte_size)
- return return_valobj_sp;
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- value.SetValueType(Value::eValueTypeScalar);
-
- bool success = false;
- if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
- // Extract the register context so we can read arguments from registers
- if (*byte_size <= 8) {
- const RegisterInfo *x0_reg_info =
- reg_ctx->GetRegisterInfoByName("x0", 0);
- if (x0_reg_info) {
- uint64_t raw_value =
- thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
- 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (*byte_size) {
- default:
- break;
- case 16: // uint128_t
- // In register x0 and x1
- {
- const RegisterInfo *x1_reg_info =
- reg_ctx->GetRegisterInfoByName("x1", 0);
-
- if (x1_reg_info) {
- if (*byte_size <=
- x0_reg_info->byte_size + x1_reg_info->byte_size) {
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order =
- exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue x0_reg_value;
- RegisterValue x1_reg_value;
- if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
- reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
- Status error;
- if (x0_reg_value.GetAsMemoryData(
- x0_reg_info, heap_data_up->GetBytes() + 0, 8,
- byte_order, error) &&
- x1_reg_value.GetAsMemoryData(
- x1_reg_info, heap_data_up->GetBytes() + 8, 8,
- byte_order, error)) {
- DataExtractor data(
- DataBufferSP(heap_data_up.release()), byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
-
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- return return_valobj_sp;
- }
- }
- }
- }
- }
- break;
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
- }
- }
- }
- } else if (type_flags & eTypeIsFloat) {
- if (type_flags & eTypeIsComplex) {
- // Don't handle complex yet.
- } else {
- if (*byte_size <= sizeof(long double)) {
- const RegisterInfo *v0_reg_info =
- reg_ctx->GetRegisterInfoByName("v0", 0);
- RegisterValue v0_value;
- if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
- DataExtractor data;
- if (v0_value.GetData(data)) {
- lldb::offset_t offset = 0;
- if (*byte_size == sizeof(float)) {
- value.GetScalar() = data.GetFloat(&offset);
- success = true;
- } else if (*byte_size == sizeof(double)) {
- value.GetScalar() = data.GetDouble(&offset);
- success = true;
- } else if (*byte_size == sizeof(long double)) {
- value.GetScalar() = data.GetLongDouble(&offset);
- success = true;
- }
- }
- }
- }
- }
- }
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsVector) {
- if (*byte_size > 0) {
-
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- if (*byte_size <= v0_info->byte_size) {
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(v0_info, reg_value)) {
- Status error;
- if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(),
- heap_data_up->GetByteSize(),
- byte_order, error)) {
- DataExtractor data(DataBufferSP(heap_data_up.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
- }
- }
- }
- }
- } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
- DataExtractor data;
-
- uint32_t NGRN = 0; // Search ABI docs for NGRN
- uint32_t NSRN = 0; // Search ABI docs for NSRN
- const bool is_return_value = true;
- if (LoadValueFromConsecutiveGPRRegisters(
- exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
- data)) {
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
- }
- return return_valobj_sp;
-}
-
-void ABIMacOSX_arm64::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
- CreateInstance);
-}
-
-void ABIMacOSX_arm64::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-// PluginInterface protocol
-
-ConstString ABIMacOSX_arm64::GetPluginNameStatic() {
- static ConstString g_plugin_name("ABIMacOSX_arm64");
- return g_plugin_name;
-}
-
-uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/ABI/Mips/ABIMips.cpp b/lldb/source/Plugins/ABI/Mips/ABIMips.cpp
new file mode 100644
index 000000000000..16ef1faf9d9d
--- /dev/null
+++ b/lldb/source/Plugins/ABI/Mips/ABIMips.cpp
@@ -0,0 +1,24 @@
+//===-- Mips.h ------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIMips.h"
+#include "ABISysV_mips.h"
+#include "ABISysV_mips64.h"
+#include "lldb/Core/PluginManager.h"
+
+LLDB_PLUGIN_DEFINE(ABIMips)
+
+void ABIMips::Initialize() {
+ ABISysV_mips::Initialize();
+ ABISysV_mips64::Initialize();
+}
+
+void ABIMips::Terminate() {
+ ABISysV_mips::Terminate();
+ ABISysV_mips64::Terminate();
+}
diff --git a/lldb/source/Plugins/ABI/Mips/ABIMips.h b/lldb/source/Plugins/ABI/Mips/ABIMips.h
new file mode 100644
index 000000000000..dc7704de1c96
--- /dev/null
+++ b/lldb/source/Plugins/ABI/Mips/ABIMips.h
@@ -0,0 +1,17 @@
+//===-- Mips.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABIMIPS_H
+#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABIMIPS_H
+
+class ABIMips {
+public:
+ static void Initialize();
+ static void Terminate();
+};
+#endif
diff --git a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
index 416db9f5ae87..d66e0926ad99 100644
--- a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_mips.cpp ----------------------------------------*- C++ -*-===//
+//===-- ABISysV_mips.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_mips)
+
enum dwarf_regnums {
dwarf_r0 = 0,
dwarf_r1,
diff --git a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
index 8143f552fc4d..715405e7ef97 100644
--- a/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_mips_h_
-#define liblldb_ABISysV_mips_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H
+#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_mips : public lldb_private::ABI {
+class ABISysV_mips : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_mips() override = default;
@@ -87,11 +87,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_mips_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS_H
diff --git a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
index 72ec0715b6cd..bb28a50e5f4a 100644
--- a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_mips64.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_mips64.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_mips64)
+
enum dwarf_regnums {
dwarf_r0 = 0,
dwarf_r1,
diff --git a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
index 76c3c5413b92..91428216a73a 100644
--- a/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_mips64_h_
-#define liblldb_ABISysV_mips64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H
+#define LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_mips64 : public lldb_private::ABI {
+class ABISysV_mips64 : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_mips64() override = default;
@@ -51,7 +51,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -100,11 +100,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_mips64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_MIPS_ABISYSV_MIPS64_H
diff --git a/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp b/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp
new file mode 100644
index 000000000000..b561e3c93f57
--- /dev/null
+++ b/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.cpp
@@ -0,0 +1,24 @@
+//===-- PowerPC.h ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIPowerPC.h"
+#include "ABISysV_ppc.h"
+#include "ABISysV_ppc64.h"
+#include "lldb/Core/PluginManager.h"
+
+LLDB_PLUGIN_DEFINE(ABIPowerPC)
+
+void ABIPowerPC::Initialize() {
+ ABISysV_ppc::Initialize();
+ ABISysV_ppc64::Initialize();
+}
+
+void ABIPowerPC::Terminate() {
+ ABISysV_ppc::Terminate();
+ ABISysV_ppc64::Terminate();
+}
diff --git a/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h b/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h
new file mode 100644
index 000000000000..5e745eae0a42
--- /dev/null
+++ b/lldb/source/Plugins/ABI/PowerPC/ABIPowerPC.h
@@ -0,0 +1,17 @@
+//===-- PowerPC.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABIPOWERPC_H
+#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABIPOWERPC_H
+
+class ABIPowerPC {
+public:
+ static void Initialize();
+ static void Terminate();
+};
+#endif
diff --git a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
index 857b7fee10e3..6f5eded7b031 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_ppc.cpp -----------------------------------------*- C++ -*-===//
+//===-- ABISysV_ppc.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_ppc)
+
enum dwarf_regnums {
dwarf_r0 = 0,
dwarf_r1,
diff --git a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
index 59907c4648ba..4a586849e585 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
+++ b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_ppc_h_
-#define liblldb_ABISysV_ppc_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H
+#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_ppc : public lldb_private::ABI {
+class ABISysV_ppc : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_ppc() override = default;
@@ -49,7 +49,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -96,11 +96,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_ppc_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC_H
diff --git a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
index 935353c38ca4..251ac972fd76 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_ppc64.cpp ---------------------------------------*- C++ -*-===//
+//===-- ABISysV_ppc64.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,6 +11,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "Utility/PPC64LE_DWARF_Registers.h"
#include "Utility/PPC64_DWARF_Registers.h"
#include "lldb/Core/Module.h"
@@ -19,7 +20,6 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Core/ValueObjectRegister.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -47,6 +47,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_ppc64)
+
const lldb_private::RegisterInfo *
ABISysV_ppc64::GetRegisterInfoArray(uint32_t &count) {
if (GetByteOrder() == lldb::eByteOrderLittle) {
@@ -806,10 +808,10 @@ private:
// case 3: get from GPRs
// first, check if this is a packed struct or not
- ClangASTContext *ast =
- llvm::dyn_cast<ClangASTContext>(m_type.GetTypeSystem());
+ TypeSystemClang *ast =
+ llvm::dyn_cast<TypeSystemClang>(m_type.GetTypeSystem());
if (ast) {
- clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(m_type);
+ clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(m_type);
if (record_decl) {
auto attrs = record_decl->attrs();
diff --git a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
index 1b58975dd9d9..8dcf3ca48b56 100644
--- a/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_ppc64_h_
-#define liblldb_ABISysV_ppc64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H
+#define LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_ppc64 : public lldb_private::ABI {
+class ABISysV_ppc64 : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_ppc64() override = default;
@@ -49,7 +49,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -96,13 +96,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
lldb::ByteOrder GetByteOrder() const;
};
-#endif // liblldb_ABISysV_ppc64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_POWERPC_ABISYSV_PPC64_H
diff --git a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
deleted file mode 100644
index 89a1f2b3cf04..000000000000
--- a/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ /dev/null
@@ -1,2420 +0,0 @@
-//===-- ABISysV_arm64.cpp ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "ABISysV_arm64.h"
-
-#include <vector>
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/Status.h"
-
-#include "Utility/ARM64_DWARF_Registers.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static RegisterInfo g_register_infos[] = {
- // NAME ALT SZ OFF ENCODING FORMAT
- // EH_FRAME DWARF GENERIC
- // PROCESS PLUGIN LLDB NATIVE
- // ========== ======= == === ============= ===================
- // =================== ====================== ===========================
- // ======================= ======================
- {"x0",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x1",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x2",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x3",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x4",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x5",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x6",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x7",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x8",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x8, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x9",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x9, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x10",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x10, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x11",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x11, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x12",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x12, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x13",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x13, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x14",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x14, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x15",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x15, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x16",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x16, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x17",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x17, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x18",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x18, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x19",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x19, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x20",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x20, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x21",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x21, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x22",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x22, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x23",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x23, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x24",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x24, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x25",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x25, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x26",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x26, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x27",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x27, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"x28",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x28, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fp",
- "x29",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"lr",
- "x30",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"sp",
- "x31",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"pc",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"cpsr",
- "psr",
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"v0",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v1",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v2",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v3",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v4",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v5",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v6",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v7",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v8",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v9",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v10",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v11",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v12",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v13",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v14",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v15",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v16",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v17",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v18",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v19",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v20",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v21",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v22",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v23",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v24",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v25",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v26",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v27",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v28",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v29",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v30",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"v31",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"fpsr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fpcr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"s0",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s1",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s2",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s3",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s4",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s5",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s6",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s7",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s8",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s9",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s10",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s11",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s12",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s13",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s14",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s15",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s16",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s17",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s18",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s19",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s20",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s21",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s22",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s23",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s24",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s25",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s26",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s27",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s28",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s29",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s30",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"s31",
- nullptr,
- 4,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
-
- {"d0",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d1",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d2",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d3",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d4",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d5",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d6",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d7",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d8",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d9",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d10",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d11",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d12",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d13",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d14",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d15",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d16",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d17",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d18",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d19",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d20",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d21",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d22",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d23",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d24",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d25",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d26",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d27",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d28",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d29",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d30",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"d31",
- nullptr,
- 8,
- 0,
- eEncodingIEEE754,
- eFormatFloat,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0}};
-
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABISysV_arm64::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
-bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) {
- name = "x0";
- return true;
-}
-
-size_t ABISysV_arm64::GetRedZoneSize() const { return 128; }
-
-// Static Functions
-
-ABISP
-ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
- const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
-
- if (vendor_type != llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64 ||
- arch_type == llvm::Triple::aarch64_32) {
- return ABISP(
- new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
- }
- }
-
- return ABISP();
-}
-
-bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
- addr_t func_addr, addr_t return_addr,
- llvm::ArrayRef<addr_t> args) const {
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return false;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log) {
- StreamString s;
- s.Printf("ABISysV_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
- ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
- ", return_addr = 0x%" PRIx64,
- thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
- (uint64_t)return_addr);
-
- for (size_t i = 0; i < args.size(); ++i)
- s.Printf(", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
- s.PutCString(")");
- log->PutString(s.GetString());
- }
-
- // x0 - x7 contain first 8 simple args
- if (args.size() > 8)
- return false;
-
- for (size_t i = 0; i < args.size(); ++i) {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- LLDB_LOGF(log, "About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
- if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
- return false;
- }
-
- // Set "lr" to the return address
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_RA),
- return_addr))
- return false;
-
- // Set "sp" to the requested value
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_SP),
- sp))
- return false;
-
- // Set "pc" to the address requested
- if (!reg_ctx->WriteRegisterFromUnsigned(
- reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC),
- func_addr))
- return false;
-
- return true;
-}
-
-// TODO: We dont support fp/SIMD arguments in v0-v7
-bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
- uint32_t num_values = values.GetSize();
-
- ExecutionContext exe_ctx(thread.shared_from_this());
-
- // Extract the register context so we can read arguments from registers
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-
- if (!reg_ctx)
- return false;
-
- addr_t sp = 0;
-
- for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
- // We currently only support extracting values with Clang QualTypes. Do we
- // care about others?
- Value *value = values.GetValueAtIndex(value_idx);
-
- if (!value)
- return false;
-
- CompilerType value_type = value->GetCompilerType();
- if (value_type) {
- bool is_signed = false;
- size_t bit_width = 0;
- llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
- if (!bit_size)
- return false;
- if (value_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = *bit_size;
- } else if (value_type.IsPointerOrReferenceType()) {
- bit_width = *bit_size;
- } else {
- // We only handle integer, pointer and reference types currently...
- return false;
- }
-
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
- if (value_idx < 8) {
- // Arguments 1-8 are in x0-x7...
- const RegisterInfo *reg_info = nullptr;
- reg_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
-
- if (reg_info) {
- RegisterValue reg_value;
-
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (is_signed)
- reg_value.SignExtend(bit_width);
- if (!reg_value.GetScalarValue(value->GetScalar()))
- return false;
- continue;
- }
- }
- return false;
- } else {
- // TODO: Verify for stack layout for SysV
- if (sp == 0) {
- // Read the stack pointer if we already haven't read it
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
- return false;
- }
-
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
- Status error;
- if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
- sp, arg_byte_size, is_signed, value->GetScalar(), error))
- return false;
-
- sp += arg_byte_size;
- // Align up to the next 8 byte boundary if needed
- if (sp % 8) {
- sp >>= 3;
- sp += 1;
- sp <<= 3;
- }
- }
- }
- }
- }
- return true;
-}
-
-Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
- lldb::ValueObjectSP &new_value_sp) {
- Status error;
- if (!new_value_sp) {
- error.SetErrorString("Empty value object for return value.");
- return error;
- }
-
- CompilerType return_value_type = new_value_sp->GetCompilerType();
- if (!return_value_type) {
- error.SetErrorString("Null clang type for return value.");
- return error;
- }
-
- Thread *thread = frame_sp->GetThread().get();
-
- RegisterContext *reg_ctx = thread->GetRegisterContext().get();
-
- if (reg_ctx) {
- DataExtractor data;
- Status data_error;
- const uint64_t byte_size = new_value_sp->GetData(data, data_error);
- if (data_error.Fail()) {
- error.SetErrorStringWithFormat(
- "Couldn't convert return value to raw data: %s",
- data_error.AsCString());
- return error;
- }
-
- const uint32_t type_flags = return_value_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
- // Extract the register context so we can read arguments from registers
- lldb::offset_t offset = 0;
- if (byte_size <= 16) {
- const RegisterInfo *x0_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- if (byte_size <= 8) {
- uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
-
- if (!reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value))
- error.SetErrorString("failed to write register x0");
- } else {
- uint64_t raw_value = data.GetMaxU64(&offset, 8);
-
- if (reg_ctx->WriteRegisterFromUnsigned(x0_info, raw_value)) {
- const RegisterInfo *x1_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
- raw_value = data.GetMaxU64(&offset, byte_size - offset);
-
- if (!reg_ctx->WriteRegisterFromUnsigned(x1_info, raw_value))
- error.SetErrorString("failed to write register x1");
- }
- }
- } else {
- error.SetErrorString("We don't support returning longer than 128 bit "
- "integer values at present.");
- }
- } else if (type_flags & eTypeIsFloat) {
- if (type_flags & eTypeIsComplex) {
- // Don't handle complex yet.
- error.SetErrorString(
- "returning complex float values are not supported");
- } else {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- if (byte_size <= 16) {
- if (byte_size <= RegisterValue::GetMaxByteSize()) {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData(v0_info, data, 0, true);
- if (error.Success()) {
- if (!reg_ctx->WriteRegister(v0_info, reg_value))
- error.SetErrorString("failed to write register v0");
- }
- } else {
- error.SetErrorStringWithFormat(
- "returning float values with a byte size of %" PRIu64
- " are not supported",
- byte_size);
- }
- } else {
- error.SetErrorString("returning float values longer than 128 "
- "bits are not supported");
- }
- } else {
- error.SetErrorString("v0 register is not available on this target");
- }
- }
- }
- } else if (type_flags & eTypeIsVector) {
- if (byte_size > 0) {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- if (byte_size <= v0_info->byte_size) {
- RegisterValue reg_value;
- error = reg_value.SetValueFromData(v0_info, data, 0, true);
- if (error.Success()) {
- if (!reg_ctx->WriteRegister(v0_info, reg_value))
- error.SetErrorString("failed to write register v0");
- }
- }
- }
- }
- }
- } else {
- error.SetErrorString("no registers are available");
- }
-
- return error;
-}
-
-bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
-
- uint32_t lr_reg_num = arm64_dwarf::lr;
- uint32_t sp_reg_num = arm64_dwarf::sp;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
-
- // Our previous Call Frame Address is the stack pointer
- row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
-
- unwind_plan.AppendRow(row);
- unwind_plan.SetReturnAddressRegister(lr_reg_num);
-
- // All other registers are the same.
-
- unwind_plan.SetSourceName("arm64 at-func-entry default");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
- unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
-
- return true;
-}
-
-bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
- unwind_plan.Clear();
- unwind_plan.SetRegisterKind(eRegisterKindDWARF);
-
- uint32_t fp_reg_num = arm64_dwarf::fp;
- uint32_t pc_reg_num = arm64_dwarf::pc;
-
- UnwindPlan::RowSP row(new UnwindPlan::Row);
- const int32_t ptr_size = 8;
-
- row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
- row->SetOffset(0);
-
- row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
- row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
-
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName("arm64 default unwind plan");
- unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
- unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
- unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
-
- return true;
-}
-
-// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
-// registers x19 through x28 and sp are callee preserved. v8-v15 are non-
-// volatile (and specifically only the lower 8 bytes of these regs), the rest
-// of the fp/SIMD registers are volatile.
-
-// We treat x29 as callee preserved also, else the unwinder won't try to
-// retrieve fp saves.
-
-bool ABISysV_arm64::RegisterIsVolatile(const RegisterInfo *reg_info) {
- if (reg_info) {
- const char *name = reg_info->name;
-
- // Sometimes we'll be called with the "alternate" name for these registers;
- // recognize them as non-volatile.
-
- if (name[0] == 'p' && name[1] == 'c') // pc
- return false;
- if (name[0] == 'f' && name[1] == 'p') // fp
- return false;
- if (name[0] == 's' && name[1] == 'p') // sp
- return false;
- if (name[0] == 'l' && name[1] == 'r') // lr
- return false;
-
- if (name[0] == 'x' || name[0] == 'r') {
- // Volatile registers: x0-x18
- // Although documentation says only x19-28 + sp are callee saved We ll
- // also have to treat x30 as non-volatile. Each dwarf frame has its own
- // value of lr. Return false for the non-volatile gpr regs, true for
- // everything else
- switch (name[1]) {
- case '1':
- switch (name[2]) {
- case '9':
- return false; // x19 is non-volatile
- default:
- return true;
- }
- break;
- case '2':
- switch (name[2]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- return false; // x20 - 28 are non-volatile
- case '9':
- return false; // x29 aka fp treat as non-volatile
- default:
- return true;
- }
- case '3': // x30 (lr) and x31 (sp) treat as non-volatile
- if (name[2] == '0' || name[2] == '1')
- return false;
- break;
- default:
- return true; // all volatile cases not handled above fall here.
- }
- } else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd') {
- // Volatile registers: v0-7, v16-v31
- // Return false for non-volatile fp/SIMD regs, true for everything else
- switch (name[1]) {
- case '8':
- case '9':
- return false; // v8-v9 are non-volatile
- case '1':
- switch (name[2]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- return false; // v10-v15 are non-volatile
- default:
- return true;
- }
- default:
- return true;
- }
- }
- }
- return true;
-}
-
-static bool LoadValueFromConsecutiveGPRRegisters(
- ExecutionContext &exe_ctx, RegisterContext *reg_ctx,
- const CompilerType &value_type,
- bool is_return_value, // false => parameter, true => return value
- uint32_t &NGRN, // NGRN (see ABI documentation)
- uint32_t &NSRN, // NSRN (see ABI documentation)
- DataExtractor &data) {
- llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
-
- if (byte_size || *byte_size == 0)
- return false;
-
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- Status error;
-
- CompilerType base_type;
- const uint32_t homogeneous_count =
- value_type.IsHomogeneousAggregate(&base_type);
- if (homogeneous_count > 0 && homogeneous_count <= 8) {
- // Make sure we have enough registers
- if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
- if (!base_type)
- return false;
- llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
- if (!base_byte_size)
- return false;
- uint32_t data_offset = 0;
-
- for (uint32_t i = 0; i < homogeneous_count; ++i) {
- char v_name[8];
- ::snprintf(v_name, sizeof(v_name), "v%u", NSRN);
- const RegisterInfo *reg_info =
- reg_ctx->GetRegisterInfoByName(v_name, 0);
- if (reg_info == nullptr)
- return false;
-
- if (*base_byte_size > reg_info->byte_size)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- // Make sure we have enough room in "heap_data_up"
- if ((data_offset + *base_byte_size) <= heap_data_up->GetByteSize()) {
- const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_up->GetBytes() + data_offset, *base_byte_size,
- byte_order, error);
- if (bytes_copied != *base_byte_size)
- return false;
- data_offset += bytes_copied;
- ++NSRN;
- } else
- return false;
- }
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP(heap_data_up.release()));
- return true;
- }
- }
-
- const size_t max_reg_byte_size = 16;
- if (*byte_size <= max_reg_byte_size) {
- size_t bytes_left = *byte_size;
- uint32_t data_offset = 0;
- while (data_offset < *byte_size) {
- if (NGRN >= 8)
- return false;
-
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == nullptr)
- return false;
-
- RegisterValue reg_value;
-
- if (!reg_ctx->ReadRegister(reg_info, reg_value))
- return false;
-
- const size_t curr_byte_size = std::min<size_t>(8, bytes_left);
- const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_up->GetBytes() + data_offset, curr_byte_size,
- byte_order, error);
- if (bytes_copied == 0)
- return false;
- if (bytes_copied >= bytes_left)
- break;
- data_offset += bytes_copied;
- bytes_left -= bytes_copied;
- ++NGRN;
- }
- } else {
- const RegisterInfo *reg_info = nullptr;
- if (is_return_value) {
- // We are assuming we are decoding this immediately after returning from
- // a function call and that the address of the structure is in x8
- reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
- } else {
- // We are assuming we are stopped at the first instruction in a function
- // and that the ABI is being respected so all parameters appear where
- // they should be (functions with no external linkage can legally violate
- // the ABI).
- if (NGRN >= 8)
- return false;
-
- reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_ARG1 + NGRN);
- if (reg_info == nullptr)
- return false;
- ++NGRN;
- }
-
- if (reg_info == nullptr)
- return false;
-
- const lldb::addr_t value_addr =
- reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
-
- if (value_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- if (exe_ctx.GetProcessRef().ReadMemory(
- value_addr, heap_data_up->GetBytes(), heap_data_up->GetByteSize(),
- error) != heap_data_up->GetByteSize()) {
- return false;
- }
- }
-
- data.SetByteOrder(byte_order);
- data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
- data.SetData(DataBufferSP(heap_data_up.release()));
- return true;
-}
-
-ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
- Thread &thread, CompilerType &return_compiler_type) const {
- ValueObjectSP return_valobj_sp;
- Value value;
-
- ExecutionContext exe_ctx(thread.shared_from_this());
- if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
- return return_valobj_sp;
-
- // value.SetContext (Value::eContextTypeClangType, return_compiler_type);
- value.SetCompilerType(return_compiler_type);
-
- RegisterContext *reg_ctx = thread.GetRegisterContext().get();
- if (!reg_ctx)
- return return_valobj_sp;
-
- llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
- if (!byte_size)
- return return_valobj_sp;
-
- const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
- if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
- value.SetValueType(Value::eValueTypeScalar);
-
- bool success = false;
- if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
- // Extract the register context so we can read arguments from registers
- if (*byte_size <= 8) {
- const RegisterInfo *x0_reg_info = nullptr;
- x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_ARG1);
- if (x0_reg_info) {
- uint64_t raw_value =
- thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
- 0);
- const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (*byte_size) {
- default:
- break;
- case 16: // uint128_t
- // In register x0 and x1
- {
- const RegisterInfo *x1_reg_info = nullptr;
- x1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_ARG2);
-
- if (x1_reg_info) {
- if (*byte_size <=
- x0_reg_info->byte_size + x1_reg_info->byte_size) {
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order =
- exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue x0_reg_value;
- RegisterValue x1_reg_value;
- if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
- reg_ctx->ReadRegister(x1_reg_info, x1_reg_value)) {
- Status error;
- if (x0_reg_value.GetAsMemoryData(
- x0_reg_info, heap_data_up->GetBytes() + 0, 8,
- byte_order, error) &&
- x1_reg_value.GetAsMemoryData(
- x1_reg_info, heap_data_up->GetBytes() + 8, 8,
- byte_order, error)) {
- DataExtractor data(
- DataBufferSP(heap_data_up.release()), byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
-
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- return return_valobj_sp;
- }
- }
- }
- }
- }
- break;
- case sizeof(uint64_t):
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- success = true;
- break;
-
- case sizeof(uint32_t):
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
- else
- value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
- success = true;
- break;
-
- case sizeof(uint16_t):
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
- else
- value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
- success = true;
- break;
-
- case sizeof(uint8_t):
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
- else
- value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
- success = true;
- break;
- }
- }
- }
- } else if (type_flags & eTypeIsFloat) {
- if (type_flags & eTypeIsComplex) {
- // Don't handle complex yet.
- } else {
- if (*byte_size <= sizeof(long double)) {
- const RegisterInfo *v0_reg_info =
- reg_ctx->GetRegisterInfoByName("v0", 0);
- RegisterValue v0_value;
- if (reg_ctx->ReadRegister(v0_reg_info, v0_value)) {
- DataExtractor data;
- if (v0_value.GetData(data)) {
- lldb::offset_t offset = 0;
- if (*byte_size == sizeof(float)) {
- value.GetScalar() = data.GetFloat(&offset);
- success = true;
- } else if (*byte_size == sizeof(double)) {
- value.GetScalar() = data.GetDouble(&offset);
- success = true;
- } else if (*byte_size == sizeof(long double)) {
- value.GetScalar() = data.GetLongDouble(&offset);
- success = true;
- }
- }
- }
- }
- }
- }
-
- if (success)
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsVector && *byte_size <= 16) {
- if (*byte_size > 0) {
- const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
-
- if (v0_info) {
- std::unique_ptr<DataBufferHeap> heap_data_up(
- new DataBufferHeap(*byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(v0_info, reg_value)) {
- Status error;
- if (reg_value.GetAsMemoryData(v0_info, heap_data_up->GetBytes(),
- heap_data_up->GetByteSize(), byte_order,
- error)) {
- DataExtractor data(DataBufferSP(heap_data_up.release()), byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
- }
- }
- }
- } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
- (type_flags & eTypeIsVector && *byte_size > 16)) {
- DataExtractor data;
-
- uint32_t NGRN = 0; // Search ABI docs for NGRN
- uint32_t NSRN = 0; // Search ABI docs for NSRN
- const bool is_return_value = true;
- if (LoadValueFromConsecutiveGPRRegisters(
- exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN,
- data)) {
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
- }
- return return_valobj_sp;
-}
-
-void ABISysV_arm64::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- "SysV ABI for AArch64 targets", CreateInstance);
-}
-
-void ABISysV_arm64::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() {
- static ConstString g_name("SysV-arm64");
- return g_name;
-}
-
-// PluginInterface protocol
-
-ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); }
-
-uint32_t ABISysV_arm64::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
index f4f803a8277d..eced2adc7591 100644
--- a/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_s390x.cpp ---------------------------------------*- C++ -*-===//
+//===-- ABISysV_s390x.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(ABISysV_s390x, ABISystemZ)
+
enum dwarf_regnums {
// General Purpose Registers
dwarf_r0_s390x = 0,
diff --git a/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
index 671d6a18260e..f8f412465658 100644
--- a/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
+++ b/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_s390x_h_
-#define liblldb_ABISysV_s390x_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H
+#define LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABISysV_s390x : public lldb_private::ABI {
+class ABISysV_s390x : public lldb_private::RegInfoBasedABI {
public:
~ABISysV_s390x() override = default;
@@ -88,11 +88,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_s390x(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using lldb_private::RegInfoBasedABI::RegInfoBasedABI; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_s390x_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_SYSTEMZ_ABISYSV_S390X_H
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
index 76ebd6476ffd..89112deb2c4a 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
@@ -1,4 +1,4 @@
-//===-- ABIMacOSX_i386.cpp --------------------------------------*- C++ -*-===//
+//===-- ABIMacOSX_i386.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -29,20 +29,7 @@
using namespace lldb;
using namespace lldb_private;
-enum {
- ehframe_eax = 0,
- ehframe_ecx,
- ehframe_edx,
- ehframe_ebx,
- ehframe_ebp, // Different from DWARF the regnums - eh_frame esp/ebp had their
- // regnums switched on i386 darwin
- ehframe_esp, // Different from DWARF the regnums - eh_frame esp/ebp had their
- // regnums switched on i386 darwin
- ehframe_esi,
- ehframe_edi,
- ehframe_eip,
- ehframe_eflags
-};
+LLDB_PLUGIN_DEFINE(ABIMacOSX_i386)
enum {
dwarf_eax = 0,
@@ -54,653 +41,8 @@ enum {
dwarf_esi,
dwarf_edi,
dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_ymm0 = dwarf_xmm0,
- dwarf_ymm1 = dwarf_xmm1,
- dwarf_ymm2 = dwarf_xmm2,
- dwarf_ymm3 = dwarf_xmm3,
- dwarf_ymm4 = dwarf_xmm4,
- dwarf_ymm5 = dwarf_xmm5,
- dwarf_ymm6 = dwarf_xmm6,
- dwarf_ymm7 = dwarf_xmm7
};
-static RegisterInfo g_register_infos[] = {
- // NAME ALT SZ OFF ENCODING FORMAT
- // EH_FRAME DWARF GENERIC
- // PROCESS PLUGIN LLDB NATIVE
- // ====== ======= == === ============= ============
- // ===================== ===================== ============================
- // ==================== ======================
- {"eax",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ebx",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ecx",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"edx",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"esi",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"edi",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ebp",
- "fp",
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"esp",
- "sp",
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"eip",
- "pc",
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"eflags",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"cs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ss",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ds",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"es",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"gs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm0",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm0, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm1",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm1, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm2",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm3",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm3, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm4",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm4, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm5",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm5, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm6",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm6, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm7",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_stmm7, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fctrl",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fstat",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ftag",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fiseg",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fioff",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"foseg",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fooff",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fop",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm0",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm1",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm2",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm3",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm4",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm5",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm6",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm7",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"mxcsr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm0",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm1",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm2",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm3",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm4",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm5",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm6",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm7",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0}};
-
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABIMacOSX_i386::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; }
// Static Functions
diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
index 50062b84d878..b8b253144165 100644
--- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABIMacOSX_i386_h_
-#define liblldb_ABIMacOSX_i386_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H
+#include "Plugins/ABI/X86/ABIX86.h"
#include "lldb/Core/Value.h"
-#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
-class ABIMacOSX_i386 : public lldb_private::ABI {
+class ABIMacOSX_i386 : public ABIX86 {
public:
~ABIMacOSX_i386() override = default;
@@ -45,7 +45,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (4-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
//
@@ -65,9 +65,6 @@ public:
return pc <= UINT32_MAX;
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
// Static Functions
static void Initialize();
@@ -91,12 +88,13 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
-private:
- ABIMacOSX_i386(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
+ std::string GetMCName(std::string name) override {
+ MapRegisterName(name, "stmm", "st");
+ return name;
}
+
+private:
+ using ABIX86::ABIX86; // Call CreateInstance instead.
};
-#endif // liblldb_ABIMacOSX_i386_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H
diff --git a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
index 69e4cff90ebf..2ac87d1512e9 100644
--- a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
@@ -1,4 +1,4 @@
-//===----------------------- ABISysV_i386.cpp -------------------*- C++ -*-===//
+//===-- ABISysV_i386.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -31,6 +31,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_i386)
+
// This source file uses the following document as a reference:
//====================================================================
// System V Application Binary Interface
@@ -63,135 +65,8 @@ enum dwarf_regnums {
dwarf_esi,
dwarf_edi,
dwarf_eip,
- dwarf_eflags,
-
- dwarf_st0 = 11,
- dwarf_st1,
- dwarf_st2,
- dwarf_st3,
- dwarf_st4,
- dwarf_st5,
- dwarf_st6,
- dwarf_st7,
-
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_ymm0 = dwarf_xmm0,
- dwarf_ymm1 = dwarf_xmm1,
- dwarf_ymm2 = dwarf_xmm2,
- dwarf_ymm3 = dwarf_xmm3,
- dwarf_ymm4 = dwarf_xmm4,
- dwarf_ymm5 = dwarf_xmm5,
- dwarf_ymm6 = dwarf_xmm6,
- dwarf_ymm7 = dwarf_xmm7,
-
- dwarf_mm0 = 29,
- dwarf_mm1,
- dwarf_mm2,
- dwarf_mm3,
- dwarf_mm4,
- dwarf_mm5,
- dwarf_mm6,
- dwarf_mm7,
-
- dwarf_bnd0 = 101,
- dwarf_bnd1,
- dwarf_bnd2,
- dwarf_bnd3
-};
-
-static RegisterInfo g_register_infos[] = {
- // clang-format off
- //NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE INVAL DYN EXPR SZ
- //========== ======= == === ============= ==================== =================== =================== ========================= =================== =================== ======= ======= ======== ==
- {"eax", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ebx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ecx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"edx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"esi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"edi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ebp", "fp", 4, 0, eEncodingUint, eFormatHex, {dwarf_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"esp", "sp", 4, 0, eEncodingUint, eFormatHex, {dwarf_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"eip", "pc", 4, 0, eEncodingUint, eFormatHex, {dwarf_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"eflags", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"cs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ss", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ds", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"es", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"gs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"st7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fctrl", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fstat", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ftag", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fiseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fioff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"foseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fooff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fop", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"mxcsr", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bndcfgu", nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bndstatus",nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}
- // clang-format on
};
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABISysV_i386::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
// Static Functions
ABISP
diff --git a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/lldb/source/Plugins/ABI/X86/ABISysV_i386.h
index 2362e9adda98..1ebb107d36df 100644
--- a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
+++ b/lldb/source/Plugins/ABI/X86/ABISysV_i386.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_i386_h_
-#define liblldb_ABISysV_i386_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H
-#include "lldb/Target/ABI.h"
+#include "Plugins/ABI/X86/ABIX86.h"
#include "lldb/lldb-private.h"
-class ABISysV_i386 : public lldb_private::ABI {
+class ABISysV_i386 : public ABIX86 {
public:
~ABISysV_i386() override = default;
@@ -53,7 +53,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (4-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
@@ -73,9 +73,6 @@ public:
return (pc <= UINT32_MAX);
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
// Static Functions
static void Initialize();
@@ -100,11 +97,7 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_i386(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using ABIX86::ABIX86; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_i386_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
index bf1c48f778e1..7729e58f8580 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===//
+//===-- ABISysV_x86_64.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -35,6 +35,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABISysV_x86_64)
+
enum dwarf_regnums {
dwarf_rax = 0,
dwarf_rdx,
@@ -53,162 +55,8 @@ enum dwarf_regnums {
dwarf_r14,
dwarf_r15,
dwarf_rip,
- dwarf_xmm0,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_xmm8,
- dwarf_xmm9,
- dwarf_xmm10,
- dwarf_xmm11,
- dwarf_xmm12,
- dwarf_xmm13,
- dwarf_xmm14,
- dwarf_xmm15,
- dwarf_stmm0,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_ymm0,
- dwarf_ymm1,
- dwarf_ymm2,
- dwarf_ymm3,
- dwarf_ymm4,
- dwarf_ymm5,
- dwarf_ymm6,
- dwarf_ymm7,
- dwarf_ymm8,
- dwarf_ymm9,
- dwarf_ymm10,
- dwarf_ymm11,
- dwarf_ymm12,
- dwarf_ymm13,
- dwarf_ymm14,
- dwarf_ymm15,
- dwarf_bnd0 = 126,
- dwarf_bnd1,
- dwarf_bnd2,
- dwarf_bnd3
-};
-
-static RegisterInfo g_register_infos[] = {
- // clang-format off
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC LLDB NATIVE
- // ======== ======= == === ============= =================== ======================= ===================== =========================== ===================== ======================
- {"rax", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rbx", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rcx", "arg4", 8, 0, eEncodingUint, eFormatHex, {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rdx", "arg3", 8, 0, eEncodingUint, eFormatHex, {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rsi", "arg2", 8, 0, eEncodingUint, eFormatHex, {dwarf_rsi, dwarf_rsi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rdi", "arg1", 8, 0, eEncodingUint, eFormatHex, {dwarf_rdi, dwarf_rdi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rbp", "fp", 8, 0, eEncodingUint, eFormatHex, {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rsp", "sp", 8, 0, eEncodingUint, eFormatHex, {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r8", "arg5", 8, 0, eEncodingUint, eFormatHex, {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r9", "arg6", 8, 0, eEncodingUint, eFormatHex, {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r10", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r11", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r12", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r13", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r14", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"r15", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rip", "pc", 8, 0, eEncodingUint, eFormatHex, {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"rflags", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"cs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ss", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ds", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"es", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"gs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"stmm7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fctrl", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fstat", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ftag", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fiseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fioff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"foseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fooff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"fop", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"xmm15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"mxcsr", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm8", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm9", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm10", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm11", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm12", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm13", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm14", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"ymm15", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bndcfgu", nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- {"bndstatus",nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
- // clang-format on
};
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
name = "rax";
return true;
@@ -1078,6 +926,21 @@ bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
return IsCalleeSaved;
}
+uint32_t ABISysV_x86_64::GetGenericNum(llvm::StringRef name) {
+ return llvm::StringSwitch<uint32_t>(name)
+ .Case("rip", LLDB_REGNUM_GENERIC_PC)
+ .Case("rsp", LLDB_REGNUM_GENERIC_SP)
+ .Case("rbp", LLDB_REGNUM_GENERIC_FP)
+ .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
+ .Case("rdi", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("rsi", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("rdx", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("rcx", LLDB_REGNUM_GENERIC_ARG4)
+ .Case("r8", LLDB_REGNUM_GENERIC_ARG5)
+ .Case("r9", LLDB_REGNUM_GENERIC_ARG6)
+ .Default(LLDB_INVALID_REGNUM);
+}
+
void ABISysV_x86_64::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
index d445d8f4142a..6dce4ce0f012 100644
--- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABISysV_x86_64_h_
-#define liblldb_ABISysV_x86_64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H
-#include "lldb/Target/ABI.h"
-#include "lldb/lldb-private.h"
+#include "Plugins/ABI/X86/ABIX86_64.h"
-class ABISysV_x86_64 : public lldb_private::ABI {
+class ABISysV_x86_64 : public ABIX86_64 {
public:
~ABISysV_x86_64() override = default;
@@ -49,7 +48,7 @@ public:
//
// To work around this, we relax that alignment to be just word-size
// (8-bytes).
- // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+ // Allowing the trap handlers for user space would be easy (_sigtramp) but
// in other environments there can be a large number of different functions
// involved in async traps.
bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
@@ -67,9 +66,6 @@ public:
return true;
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
bool GetPointerReturnRegister(const char *&name) override;
// Static Functions
@@ -96,13 +92,10 @@ protected:
lldb_private::CompilerType &ast_type) const;
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+ uint32_t GetGenericNum(llvm::StringRef reg) override;
private:
- ABISysV_x86_64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using ABIX86_64::ABIX86_64; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_x86_64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_X86_64_H
diff --git a/lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
index ac24426914e1..63b670b07277 100644
--- a/lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- ABIWindows_x86_64.cpp --------------------------------------*- C++ -*-===//
+//===-- ABIWindows_x86_64.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -33,6 +33,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ABIWindows_x86_64)
+
enum dwarf_regnums {
dwarf_rax = 0,
dwarf_rdx,
@@ -97,986 +99,6 @@ enum dwarf_regnums {
dwarf_bnd3
};
-static RegisterInfo g_register_infos[] = {
- // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
- // DWARF GENERIC PROCESS PLUGIN
- // LLDB NATIVE
- // ======== ======= == === ============= ===================
- // ======================= =====================
- // =========================== ===================== ======================
- {"rax",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rbx",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rcx",
- "arg1",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rdx",
- "arg2",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rsi",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rsi, dwarf_rsi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rdi",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rdi, dwarf_rdi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rbp",
- "fp",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rsp",
- "sp",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r8",
- "arg3",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r9",
- "arg4",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r10",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r11",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r12",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r13",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r14",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"r15",
- nullptr,
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rip",
- "pc",
- 8,
- 0,
- eEncodingUint,
- eFormatHex,
- {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"rflags",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"cs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ss",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ds",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"es",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"gs",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm0",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm1",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm2",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm3",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm4",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm5",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm6",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"stmm7",
- nullptr,
- 10,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fctrl",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fstat",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ftag",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fiseg",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fioff",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"foseg",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fooff",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"fop",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm0",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm1",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm2",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm3",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm4",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm5",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm6",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm7",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm8",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm9",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm10",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm11",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm12",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm13",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm14",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"xmm15",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"mxcsr",
- nullptr,
- 4,
- 0,
- eEncodingUint,
- eFormatHex,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm0",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm1",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm2",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm3",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm4",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm5",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm6",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm7",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm8",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm9",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm10",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm11",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm12",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm13",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm14",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"ymm15",
- nullptr,
- 32,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bnd0",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt64,
- {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bnd1",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt64,
- {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bnd2",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt64,
- {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bnd3",
- nullptr,
- 16,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt64,
- {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bndcfgu",
- nullptr,
- 8,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0},
- {"bndstatus",
- nullptr,
- 8,
- 0,
- eEncodingVector,
- eFormatVectorOfUInt8,
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
- nullptr,
- nullptr,
- nullptr,
- 0}};
-
-static const uint32_t k_num_register_infos =
- llvm::array_lengthof(g_register_infos);
-static bool g_register_info_names_constified = false;
-
-const lldb_private::RegisterInfo *
-ABIWindows_x86_64::GetRegisterInfoArray(uint32_t &count) {
- // Make the C-string names and alt_names for the register infos into const
- // C-string values by having the ConstString unique the names in the global
- // constant C-string pool.
- if (!g_register_info_names_constified) {
- g_register_info_names_constified = true;
- for (uint32_t i = 0; i < k_num_register_infos; ++i) {
- if (g_register_infos[i].name)
- g_register_infos[i].name =
- ConstString(g_register_infos[i].name).GetCString();
- if (g_register_infos[i].alt_name)
- g_register_infos[i].alt_name =
- ConstString(g_register_infos[i].alt_name).GetCString();
- }
- }
- count = k_num_register_infos;
- return g_register_infos;
-}
-
bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) {
name = "rax";
return true;
@@ -1777,6 +799,19 @@ bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
return IsCalleeSaved;
}
+uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) {
+ return llvm::StringSwitch<uint32_t>(reg)
+ .Case("rip", LLDB_REGNUM_GENERIC_PC)
+ .Case("rsp", LLDB_REGNUM_GENERIC_SP)
+ .Case("rbp", LLDB_REGNUM_GENERIC_FP)
+ .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
+ .Case("rcx", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("rdx", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("r8", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("r9", LLDB_REGNUM_GENERIC_ARG4)
+ .Default(LLDB_INVALID_REGNUM);
+}
+
void ABIWindows_x86_64::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
diff --git a/lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
index 2366566d7809..89fc6e6ca21f 100644
--- a/lldb/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
+++ b/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ABIWindows_x86_64_h_
-#define liblldb_ABIWindows_x86_64_h_
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H
-#include "lldb/Target/ABI.h"
-#include "lldb/lldb-private.h"
+#include "Plugins/ABI/X86/ABIX86_64.h"
-class ABIWindows_x86_64 : public lldb_private::ABI {
+class ABIWindows_x86_64 : public ABIX86_64 {
public:
~ABIWindows_x86_64() override = default;
@@ -56,9 +55,6 @@ public:
return true;
}
- const lldb_private::RegisterInfo *
- GetRegisterInfoArray(uint32_t &count) override;
-
bool GetPointerReturnRegister(const char *&name) override;
//------------------------------------------------------------------
@@ -89,13 +85,10 @@ protected:
lldb_private::CompilerType &ast_type) const;
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+ uint32_t GetGenericNum(llvm::StringRef reg) override;
private:
- ABIWindows_x86_64(lldb::ProcessSP process_sp,
- std::unique_ptr<llvm::MCRegisterInfo> info_up)
- : lldb_private::ABI(std::move(process_sp), std::move(info_up)) {
- // Call CreateInstance instead.
- }
+ using ABIX86_64::ABIX86_64; // Call CreateInstance instead.
};
-#endif // liblldb_ABISysV_x86_64_h_
+#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIWINDOWS_X86_64_H
diff --git a/lldb/source/Plugins/ABI/X86/ABIX86.cpp b/lldb/source/Plugins/ABI/X86/ABIX86.cpp
new file mode 100644
index 000000000000..bf5ab669417e
--- /dev/null
+++ b/lldb/source/Plugins/ABI/X86/ABIX86.cpp
@@ -0,0 +1,43 @@
+//===-- X86.h -------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIX86.h"
+#include "ABIMacOSX_i386.h"
+#include "ABISysV_i386.h"
+#include "ABISysV_x86_64.h"
+#include "ABIWindows_x86_64.h"
+#include "lldb/Core/PluginManager.h"
+
+LLDB_PLUGIN_DEFINE(ABIX86)
+
+void ABIX86::Initialize() {
+ ABIMacOSX_i386::Initialize();
+ ABISysV_i386::Initialize();
+ ABISysV_x86_64::Initialize();
+ ABIWindows_x86_64::Initialize();
+}
+
+void ABIX86::Terminate() {
+ ABIMacOSX_i386::Terminate();
+ ABISysV_i386::Terminate();
+ ABISysV_x86_64::Terminate();
+ ABIWindows_x86_64::Terminate();
+}
+
+uint32_t ABIX86::GetGenericNum(llvm::StringRef name) {
+ return llvm::StringSwitch<uint32_t>(name)
+ .Case("eip", LLDB_REGNUM_GENERIC_PC)
+ .Case("esp", LLDB_REGNUM_GENERIC_SP)
+ .Case("ebp", LLDB_REGNUM_GENERIC_FP)
+ .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS)
+ .Case("edi", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("esi", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("edx", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("ecx", LLDB_REGNUM_GENERIC_ARG4)
+ .Default(LLDB_INVALID_REGNUM);
+}
diff --git a/lldb/source/Plugins/ABI/X86/ABIX86.h b/lldb/source/Plugins/ABI/X86/ABIX86.h
new file mode 100644
index 000000000000..22521cacf180
--- /dev/null
+++ b/lldb/source/Plugins/ABI/X86/ABIX86.h
@@ -0,0 +1,24 @@
+//===-- X86.h ---------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_H
+
+#include "lldb/Target/ABI.h"
+
+class ABIX86 : public lldb_private::MCBasedABI {
+public:
+ static void Initialize();
+ static void Terminate();
+
+ uint32_t GetGenericNum(llvm::StringRef name) override;
+
+private:
+ using lldb_private::MCBasedABI::MCBasedABI;
+};
+#endif
diff --git a/lldb/source/Plugins/ABI/X86/ABIX86_64.h b/lldb/source/Plugins/ABI/X86/ABIX86_64.h
new file mode 100644
index 000000000000..e65c2d97d897
--- /dev/null
+++ b/lldb/source/Plugins/ABI/X86/ABIX86_64.h
@@ -0,0 +1,26 @@
+//===-- ABIX86_64.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H
+#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H
+
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABIX86_64 : public lldb_private::MCBasedABI {
+protected:
+ std::string GetMCName(std::string name) override {
+ MapRegisterName(name, "stmm", "st");
+ return name;
+ }
+
+private:
+ using lldb_private::MCBasedABI::MCBasedABI;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H
diff --git a/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
index 5b86df6c5273..58c7cbb4530a 100644
--- a/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
+++ b/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -1,4 +1,4 @@
-//===-- ArchitectureArm.cpp -------------------------------------*- C++ -*-===//
+//===-- ArchitectureArm.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,6 +17,8 @@
using namespace lldb_private;
using namespace lldb;
+LLDB_PLUGIN_DEFINE(ArchitectureArm)
+
ConstString ArchitectureArm::GetPluginNameStatic() {
return ConstString("arm");
}
diff --git a/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h b/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h
index 03e79ce524a7..36b79c7c01a1 100644
--- a/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h
+++ b/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGIN_ARCHITECTURE_ARM_H
-#define LLDB_PLUGIN_ARCHITECTURE_ARM_H
+#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H
+#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H
#include "lldb/Core/Architecture.h"
@@ -37,4 +37,4 @@ private:
} // namespace lldb_private
-#endif // LLDB_PLUGIN_ARCHITECTURE_ARM_H
+#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_ARM_ARCHITECTUREARM_H
diff --git a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
index 5f2f6eeb8261..22508969ceed 100644
--- a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
+++ b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -1,4 +1,4 @@
-//===-- ArchitectureMips.cpp -------------------------------------*- C++ -*-===//
+//===-- ArchitectureMips.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -21,6 +21,8 @@
using namespace lldb_private;
using namespace lldb;
+LLDB_PLUGIN_DEFINE(ArchitectureMips)
+
ConstString ArchitectureMips::GetPluginNameStatic() {
return ConstString("mips");
}
@@ -118,9 +120,7 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr,
if (current_offset == 0)
return addr;
- ExecutionContext ctx;
- target.CalculateExecutionContext(ctx);
- auto insn = GetInstructionAtAddress(ctx, current_offset, addr);
+ auto insn = GetInstructionAtAddress(target, current_offset, addr);
if (nullptr == insn || !insn->HasDelaySlot())
return addr;
@@ -136,8 +136,7 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr,
}
Instruction *ArchitectureMips::GetInstructionAtAddress(
- const ExecutionContext &exe_ctx, const Address &resolved_addr,
- addr_t symbol_offset) const {
+ Target &target, const Address &resolved_addr, addr_t symbol_offset) const {
auto loop_count = symbol_offset / 2;
@@ -169,10 +168,11 @@ Instruction *ArchitectureMips::GetInstructionAtAddress(
for (uint32_t i = 1; i <= loop_count; i++) {
// Adjust the address to read from.
addr.Slide(-2);
- AddressRange range(addr, i * 2);
uint32_t insn_size = 0;
- disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
+ disasm_sp->ParseInstructions(target, addr,
+ {Disassembler::Limit::Bytes, i * 2}, nullptr,
+ prefer_file_cache);
uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
if (num_insns) {
diff --git a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h
index a15991ff9ebf..71ee60184b69 100644
--- a/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h
+++ b/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGIN_ARCHITECTURE_MIPS_H
-#define LLDB_PLUGIN_ARCHITECTURE_MIPS_H
+#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H
+#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H
#include "lldb/Core/Architecture.h"
#include "lldb/Utility/ArchSpec.h"
@@ -35,11 +35,10 @@ public:
AddressClass addr_class) const override;
private:
- Instruction *GetInstructionAtAddress(const ExecutionContext &exe_ctx,
+ Instruction *GetInstructionAtAddress(Target &target,
const Address &resolved_addr,
lldb::addr_t symbol_offset) const;
-
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
ArchitectureMips(const ArchSpec &arch) : m_arch(arch) {}
@@ -48,4 +47,4 @@ private:
} // namespace lldb_private
-#endif // LLDB_PLUGIN_ARCHITECTURE_MIPS_H
+#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_MIPS_ARCHITECTUREMIPS_H
diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
index 76eaa44546eb..94301ecf052c 100644
--- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
+++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
@@ -1,4 +1,4 @@
-//===-- ArchitecturePPC64.cpp -----------------------------------*- C++ -*-===//
+//===-- ArchitecturePPC64.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -20,6 +20,8 @@
using namespace lldb_private;
using namespace lldb;
+LLDB_PLUGIN_DEFINE(ArchitecturePPC64)
+
ConstString ArchitecturePPC64::GetPluginNameStatic() {
return ConstString("ppc64");
}
diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
index dc663b849c4a..25210d37e53a 100644
--- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
+++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGIN_ARCHITECTURE_PPC64_H
-#define LLDB_PLUGIN_ARCHITECTURE_PPC64_H
+#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H
+#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H
#include "lldb/Core/Architecture.h"
@@ -38,4 +38,4 @@ private:
} // namespace lldb_private
-#endif // LLDB_PLUGIN_ARCHITECTURE_PPC64_H
+#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_PPC64_ARCHITECTUREPPC64_H
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index dbdb3520087e..6427d8d176c8 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -1,4 +1,4 @@
-//===-- DisassemblerLLVMC.cpp -----------------------------------*- C++ -*-===//
+//===-- DisassemblerLLVMC.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -43,6 +43,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(DisassemblerLLVMC)
+
class DisassemblerLLVMC::MCDisasmInstance {
public:
static std::unique_ptr<MCDisasmInstance>
@@ -86,76 +88,18 @@ public:
: Instruction(address, addr_class),
m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>(
disasm.shared_from_this())),
- m_does_branch(eLazyBoolCalculate), m_has_delay_slot(eLazyBoolCalculate),
- m_is_call(eLazyBoolCalculate), m_is_valid(false),
m_using_file_addr(false) {}
~InstructionLLVMC() override = default;
bool DoesBranch() override {
- if (m_does_branch == eLazyBoolCalculate) {
- DisassemblerScope disasm(*this);
- if (disasm) {
- DataExtractor data;
- if (m_opcode.GetData(data)) {
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa, disasm);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size =
- mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
- // Be conservative, if we didn't understand the instruction, say it
- // might branch...
- if (inst_size == 0)
- m_does_branch = eLazyBoolYes;
- else {
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
- }
- }
- }
- }
- return m_does_branch == eLazyBoolYes;
+ VisitInstruction();
+ return m_does_branch;
}
bool HasDelaySlot() override {
- if (m_has_delay_slot == eLazyBoolCalculate) {
- DisassemblerScope disasm(*this);
- if (disasm) {
- DataExtractor data;
- if (m_opcode.GetData(data)) {
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa, disasm);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size =
- mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
- // if we didn't understand the instruction, say it doesn't have a
- // delay slot...
- if (inst_size == 0)
- m_has_delay_slot = eLazyBoolNo;
- else {
- const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
- if (has_delay_slot)
- m_has_delay_slot = eLazyBoolYes;
- else
- m_has_delay_slot = eLazyBoolNo;
- }
- }
- }
- }
- return m_has_delay_slot == eLazyBoolYes;
+ VisitInstruction();
+ return m_has_delay_slot;
}
DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) {
@@ -367,16 +311,8 @@ public:
}
break;
}
- m_mnemonics = mnemonic_strm.GetString();
+ m_mnemonics = std::string(mnemonic_strm.GetString());
return;
- } else {
- if (m_does_branch == eLazyBoolCalculate) {
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
- }
}
static RegularExpression s_regex(
@@ -774,7 +710,7 @@ public:
s.PutCString(")");
break;
case Operand::Type::Register:
- s.PutCString(op.m_register.AsCString());
+ s.PutCString(op.m_register.GetStringRef());
break;
case Operand::Type::Sum:
s.PutCString("(");
@@ -866,42 +802,54 @@ public:
}
bool IsCall() override {
- if (m_is_call == eLazyBoolCalculate) {
- DisassemblerScope disasm(*this);
- if (disasm) {
- DataExtractor data;
- if (m_opcode.GetData(data)) {
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa, disasm);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size =
- mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
- if (inst_size == 0) {
- m_is_call = eLazyBoolNo;
- } else {
- if (mc_disasm_ptr->IsCall(inst))
- m_is_call = eLazyBoolYes;
- else
- m_is_call = eLazyBoolNo;
- }
- }
- }
- }
- return m_is_call == eLazyBoolYes;
+ VisitInstruction();
+ return m_is_call;
}
protected:
std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
- LazyBool m_does_branch;
- LazyBool m_has_delay_slot;
- LazyBool m_is_call;
- bool m_is_valid;
+
+ bool m_is_valid = false;
bool m_using_file_addr;
+ bool m_has_visited_instruction = false;
+
+ // Be conservative. If we didn't understand the instruction, say it:
+ // - Might branch
+ // - Does not have a delay slot
+ // - Is not a call
+ bool m_does_branch = true;
+ bool m_has_delay_slot = false;
+ bool m_is_call = false;
+
+ void VisitInstruction() {
+ if (m_has_visited_instruction)
+ return;
+
+ DisassemblerScope disasm(*this);
+ if (!disasm)
+ return;
+
+ DataExtractor data;
+ if (!m_opcode.GetData(data))
+ return;
+
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+ DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
+ GetDisasmToUse(is_alternate_isa, disasm);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size =
+ mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
+ if (inst_size == 0)
+ return;
+
+ m_has_visited_instruction = true;
+ m_does_branch = mc_disasm_ptr->CanBranch(inst);
+ m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
+ m_is_call = mc_disasm_ptr->IsCall(inst);
+ }
private:
DisassemblerLLVMC::MCDisasmInstance *
@@ -1414,7 +1362,7 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
// If Address::Dump returned a multi-line description, most commonly
// seen when we have multiple levels of inlined functions at an
// address, only show the first line.
- std::string str = ss.GetString();
+ std::string str = std::string(ss.GetString());
size_t first_eol_char = str.find_first_of("\r\n");
if (first_eol_char != std::string::npos) {
str.erase(first_eol_char);
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h
index fd5775056d33..9b3741bdd18f 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DisassemblerLLVMC_h_
-#define liblldb_DisassemblerLLVMC_h_
+#ifndef LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H
+#define LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H
#include <memory>
#include <mutex>
@@ -82,4 +82,4 @@ protected:
std::unique_ptr<MCDisasmInstance> m_alternate_disasm_up;
};
-#endif // liblldb_DisassemblerLLVM_h_
+#endif // LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 5b19647a27ba..fe86b2929073 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderHexagonDYLD.cpp ----------------------------*- C++ -*-===//
+//===-- DynamicLoaderHexagonDYLD.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,6 +25,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(DynamicLoaderHexagonDYLD)
+
// Aidan 21/05/2014
//
// Notes about hexagon dynamic loading:
@@ -418,8 +420,8 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread,
if (sym == nullptr || !sym->IsTrampoline())
return thread_plan_sp;
- const ConstString sym_name = sym->GetMangled().GetName(
- lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+ const ConstString sym_name =
+ sym->GetMangled().GetName(Mangled::ePreferMangled);
if (!sym_name)
return thread_plan_sp;
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index c171513c5499..2d39ce06a8d9 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DynamicLoaderHexagonDYLD_h_
-#define liblldb_DynamicLoaderHexagonDYLD_h_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Target/DynamicLoader.h"
@@ -132,7 +132,9 @@ private:
const lldb_private::SectionList *
GetSectionListFromModule(const lldb::ModuleSP module) const;
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD);
+ DynamicLoaderHexagonDYLD(const DynamicLoaderHexagonDYLD &) = delete;
+ const DynamicLoaderHexagonDYLD &
+ operator=(const DynamicLoaderHexagonDYLD &) = delete;
};
-#endif // liblldb_DynamicLoaderHexagonDYLD_h_
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index f4788816d4ea..af76056af684 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -1,4 +1,4 @@
-//===-- HexagonDYLDRendezvous.cpp -------------------------------*- C++ -*-===//
+//===-- HexagonDYLDRendezvous.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index 70fc12b7fab7..5707f8858f6c 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_HexagonDYLDRendezvous_H_
-#define liblldb_HexagonDYLDRendezvous_H_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
#include <limits.h>
#include <list>
@@ -243,4 +243,4 @@ protected:
bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
};
-#endif // liblldb_HexagonDYLDRendezvous_H_
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 737599303a60..15b3805003a5 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -1,4 +1,4 @@
-//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===//
+//===-- DYLDRendezvous.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 536eeeaaf334..b028120eb0d4 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Rendezvous_H_
-#define liblldb_Rendezvous_H_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYLDRENDEZVOUS_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYLDRENDEZVOUS_H
#include <list>
#include <string>
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 9d61c8feb923..ac60af5336ed 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderPOSIXDYLD.cpp ------------------------------*- C++ -*-===//
+//===-- DynamicLoaderPOSIXDYLD.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -29,6 +29,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD)
+
void DynamicLoaderPOSIXDYLD::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance);
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index 0630d1eb11d1..a7fcdfbadeaf 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DynamicLoaderPOSIXDYLD_h_
-#define liblldb_DynamicLoaderPOSIXDYLD_h_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H
#include <map>
#include <memory>
@@ -136,7 +136,7 @@ protected:
void LoadVDSO();
- // Loading an interpreter module (if present) assumming m_interpreter_base
+ // Loading an interpreter module (if present) assuming m_interpreter_base
// already points to its base address.
lldb::ModuleSP LoadInterpreterModule();
@@ -159,7 +159,9 @@ protected:
bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
+ DynamicLoaderPOSIXDYLD(const DynamicLoaderPOSIXDYLD &) = delete;
+ const DynamicLoaderPOSIXDYLD &
+ operator=(const DynamicLoaderPOSIXDYLD &) = delete;
};
-#endif // liblldb_DynamicLoaderPOSIXDYLD_h_
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYNAMICLOADERPOSIXDYLD_H
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index 6bc951c4d35b..48762fe6e0c3 100644
--- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===//
+//===-- DynamicLoaderStatic.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,6 +17,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(DynamicLoaderStatic)
+
// Create an instance of this class. This function is filled into the plugin
// info class that gets handed out by the plugin factory and allows the lldb to
// instantiate an instance of this class.
@@ -27,8 +29,19 @@ DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
const llvm::Triple &triple_ref =
process->GetTarget().GetArchitecture().GetTriple();
const llvm::Triple::OSType os_type = triple_ref.getOS();
- if ((os_type == llvm::Triple::UnknownOS))
- create = true;
+ const llvm::Triple::ArchType arch_type = triple_ref.getArch();
+ if (os_type == llvm::Triple::UnknownOS) {
+ // The WASM and Hexagon plugin check the ArchType rather than the OSType,
+ // so explicitly reject those here.
+ switch(arch_type) {
+ case llvm::Triple::hexagon:
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ break;
+ default:
+ create = true;
+ }
+ }
}
if (!create) {
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index fa9aded7286c..ce78804f9a92 100644
--- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DynamicLoaderStatic_h_
-#define liblldb_DynamicLoaderStatic_h_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
@@ -53,7 +53,8 @@ public:
private:
void LoadAllImagesAtFileAddresses();
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderStatic);
+ DynamicLoaderStatic(const DynamicLoaderStatic &) = delete;
+ const DynamicLoaderStatic &operator=(const DynamicLoaderStatic &) = delete;
};
-#endif // liblldb_DynamicLoaderStatic_h_
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 25ab30e9db9c..7f9504b9b3a9 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -1,5 +1,4 @@
-//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++
-//-*-===//
+//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -24,6 +23,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(DynamicLoaderWindowsDYLD)
+
DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
: DynamicLoader(process) {}
@@ -191,9 +192,8 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
// Max size of an instruction in x86 is 15 bytes.
AddressRange range(pc, 2 * 15);
- ExecutionContext exe_ctx(m_process->GetTarget());
DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
- arch, nullptr, nullptr, exe_ctx, range, true);
+ arch, nullptr, nullptr, m_process->GetTarget(), range, true);
if (!disassembler_sp) {
return ThreadPlanSP();
}
@@ -212,6 +212,7 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
auto first_insn = insn_list->GetInstructionAtIndex(0);
auto second_insn = insn_list->GetInstructionAtIndex(1);
+ ExecutionContext exe_ctx(m_process->GetTarget());
if (first_insn == nullptr || second_insn == nullptr ||
strcmp(first_insn->GetMnemonic(&exe_ctx), "jmpl") != 0 ||
strcmp(second_insn->GetMnemonic(&exe_ctx), "nop") != 0) {
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 100689a63128..502a4c160ddd 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_
-#define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H
#include "lldb/Target/DynamicLoader.h"
#include "lldb/lldb-forward.h"
@@ -51,4 +51,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_WINDOWS_DYLD_DYNAMICLOADERWINDOWSDYLD_H
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
new file mode 100644
index 000000000000..ae7e011eaa52
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -0,0 +1,70 @@
+//===-- DynamicLoaderWasmDYLD.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DynamicLoaderWasmDYLD.h"
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(DynamicLoaderWasmDYLD)
+
+DynamicLoaderWasmDYLD::DynamicLoaderWasmDYLD(Process *process)
+ : DynamicLoader(process) {}
+
+void DynamicLoaderWasmDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+ConstString DynamicLoaderWasmDYLD::GetPluginNameStatic() {
+ static ConstString g_plugin_name("wasm-dyld");
+ return g_plugin_name;
+}
+
+const char *DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in WebAssembly engines.";
+}
+
+DynamicLoader *DynamicLoaderWasmDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool should_create = force;
+ if (!should_create) {
+ should_create =
+ (process->GetTarget().GetArchitecture().GetTriple().getArch() ==
+ llvm::Triple::wasm32);
+ }
+
+ if (should_create)
+ return new DynamicLoaderWasmDYLD(process);
+
+ return nullptr;
+}
+
+void DynamicLoaderWasmDYLD::DidAttach() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ LLDB_LOGF(log, "DynamicLoaderWasmDYLD::%s()", __FUNCTION__);
+
+ // Ask the process for the list of loaded WebAssembly modules.
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
+}
+
+ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ return ThreadPlanSP();
+}
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
new file mode 100644
index 000000000000..4a18972bb848
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
@@ -0,0 +1,48 @@
+//===-- DynamicLoaderWasmDYLD.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_DynamicLoaderWasmDYLD_h_
+#define liblldb_Plugins_DynamicLoaderWasmDYLD_h_
+
+#include "lldb/Target/DynamicLoader.h"
+
+namespace lldb_private {
+namespace wasm {
+
+class DynamicLoaderWasmDYLD : public DynamicLoader {
+public:
+ DynamicLoaderWasmDYLD(Process *process);
+
+ static void Initialize();
+ static void Terminate() {}
+
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic();
+
+ static DynamicLoader *CreateInstance(Process *process, bool force);
+
+ /// DynamicLoader
+ /// \{
+ void DidAttach() override;
+ void DidLaunch() override {}
+ Status CanLoadImage() override { return Status(); }
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) override;
+ /// \}
+
+ /// PluginInterface protocol.
+ /// \{
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+ uint32_t GetPluginVersion() override { return 1; }
+ /// \}
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif // liblldb_Plugins_DynamicLoaderWasmDYLD_h_
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 77bb9544ea40..39ba5f4e9e4f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -1,4 +1,4 @@
-//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===//
+//===-- ASTResultSynthesizer.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "ASTResultSynthesizer.h"
+#include "ClangASTImporter.h"
#include "ClangPersistentVariables.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
@@ -248,48 +248,37 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
// For Lvalues
//
// - In AST result synthesis (here!) the expression E is transformed into an
- // initialization
- // T *$__lldb_expr_result_ptr = &E.
+ // initialization T *$__lldb_expr_result_ptr = &E.
//
// - In structure allocation, a pointer-sized slot is allocated in the
- // struct that is to be
- // passed into the expression.
+ // struct that is to be passed into the expression.
//
// - In IR transformations, reads and writes to $__lldb_expr_result_ptr are
- // redirected at
- // an entry in the struct ($__lldb_arg) passed into the expression.
- // (Other persistent
- // variables are treated similarly, having been materialized as
- // references, but in those
- // cases the value of the reference itself is never modified.)
+ // redirected at an entry in the struct ($__lldb_arg) passed into the
+ // expression. (Other persistent variables are treated similarly, having
+ // been materialized as references, but in those cases the value of the
+ // reference itself is never modified.)
//
// - During materialization, $0 (the result persistent variable) is ignored.
//
// - During dematerialization, $0 is marked up as a load address with value
- // equal to the
- // contents of the structure entry.
+ // equal to the contents of the structure entry.
//
// For Rvalues
//
// - In AST result synthesis the expression E is transformed into an
- // initialization
- // static T $__lldb_expr_result = E.
+ // initialization static T $__lldb_expr_result = E.
//
// - In structure allocation, a pointer-sized slot is allocated in the
- // struct that is to be
- // passed into the expression.
+ // struct that is to be passed into the expression.
//
// - In IR transformations, an instruction is inserted at the beginning of
- // the function to
- // dereference the pointer resident in the slot. Reads and writes to
- // $__lldb_expr_result
- // are redirected at that dereferenced version. Guard variables for the
- // static variable
- // are excised.
+ // the function to dereference the pointer resident in the slot. Reads and
+ // writes to $__lldb_expr_result are redirected at that dereferenced
+ // version. Guard variables for the static variable are excised.
//
// - During materialization, $0 (the result persistent variable) is
- // populated with the location
- // of a newly-allocated area of memory.
+ // populated with the location of a newly-allocated area of memory.
//
// - During dematerialization, $0 is ignored.
@@ -325,7 +314,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
else
result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
- m_sema->RequireCompleteType(SourceLocation(), expr_qual_type,
+ m_sema->RequireCompleteType(last_expr->getSourceRange().getBegin(),
+ expr_qual_type,
clang::diag::err_incomplete_type);
QualType ptr_qual_type;
@@ -453,13 +443,13 @@ void ASTResultSynthesizer::CommitPersistentDecls() {
return;
auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
- ClangASTContext *scratch_ctx = ClangASTContext::GetScratch(m_target);
+ TypeSystemClang *scratch_ctx = TypeSystemClang::GetScratch(m_target);
for (clang::NamedDecl *decl : m_decls) {
StringRef name = decl->getName();
ConstString name_cs(name.str().c_str());
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
+ Decl *D_scratch = persistent_vars->GetClangASTImporter()->DeportDecl(
&scratch_ctx->getASTContext(), decl);
if (!D_scratch) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index 0b0f3b97705d..9de823bc75a7 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -6,13 +6,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTResultSynthesizer_h_
-#define liblldb_ASTResultSynthesizer_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Target/Target.h"
#include "clang/Sema/SemaConsumer.h"
+namespace clang {
+class CompoundStmt;
+class DeclContext;
+class NamedDecl;
+class ObjCMethodDecl;
+class TypeDecl;
+} // namespace clang
+
namespace lldb_private {
/// \class ASTResultSynthesizer ASTResultSynthesizer.h
@@ -163,4 +170,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ASTResultSynthesizer_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index a164d48ae3e0..40f0de40da52 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -1,4 +1,4 @@
-//===-- ASTStructExtractor.cpp ----------------------------------*- C++ -*-===//
+//===-- ASTStructExtractor.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
index 078cf095975f..c285f6408895 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTStructExtractor_h_
-#define liblldb_ASTStructExtractor_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
#include "ClangExpressionVariable.h"
#include "ClangFunctionCaller.h"
-#include "lldb/Core/ClangForward.h"
#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
@@ -129,4 +128,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ASTStructExtractor_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
index bbdf4e31c5a4..1e438ed9d73e 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
@@ -1,4 +1,4 @@
-//===-- ASTUtils.cpp --------------------------------------------*- C++ -*-===//
+//===-- ASTUtils.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
index d429e8c3855f..3787c572d45b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
@@ -6,9 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTUtils_h_
-#define liblldb_ASTUtils_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
+#include "clang/Basic/Module.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/MultiplexExternalSemaSource.h"
#include "clang/Sema/Sema.h"
@@ -71,7 +72,7 @@ public:
return m_Source->getModule(ID);
}
- llvm::Optional<ASTSourceDescriptor>
+ llvm::Optional<clang::ASTSourceDescriptor>
getSourceDescriptor(unsigned ID) override {
return m_Source->getSourceDescriptor(ID);
}
@@ -576,4 +577,4 @@ public:
};
} // namespace lldb_private
-#endif // liblldb_ASTUtils_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
new file mode 100644
index 000000000000..ac16738933ac
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -0,0 +1,1212 @@
+//===-- ClangASTImporter.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Module.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include <memory>
+
+using namespace lldb_private;
+using namespace clang;
+
+CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast,
+ const CompilerType &src_type) {
+ clang::ASTContext &dst_clang_ast = dst_ast.getASTContext();
+
+ TypeSystemClang *src_ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
+ if (!src_ast)
+ return CompilerType();
+
+ clang::ASTContext &src_clang_ast = src_ast->getASTContext();
+
+ clang::QualType src_qual_type = ClangUtil::GetQualType(src_type);
+
+ ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast));
+ if (!delegate_sp)
+ return CompilerType();
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast);
+
+ llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type);
+ if (!ret_or_error) {
+ Log *log =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG_ERROR(log, ret_or_error.takeError(),
+ "Couldn't import type: {0}");
+ return CompilerType();
+ }
+
+ lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr();
+
+ if (dst_clang_type)
+ return CompilerType(&dst_ast, dst_clang_type);
+ return CompilerType();
+}
+
+clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
+ clang::Decl *decl) {
+ ImporterDelegateSP delegate_sp;
+
+ clang::ASTContext *src_ast = &decl->getASTContext();
+ delegate_sp = GetDelegate(dst_ast, src_ast);
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);
+
+ if (!delegate_sp)
+ return nullptr;
+
+ llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl);
+ if (!result) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}");
+ if (log) {
+ lldb::user_id_t user_id = LLDB_INVALID_UID;
+ ClangASTMetadata *metadata = GetDeclMetadata(decl);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
+ if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
+ LLDB_LOG(log,
+ " [ClangASTImporter] WARNING: Failed to import a {0} "
+ "'{1}', metadata {2}",
+ decl->getDeclKindName(), named_decl->getNameAsString(),
+ user_id);
+ else
+ LLDB_LOG(log,
+ " [ClangASTImporter] WARNING: Failed to import a {0}, "
+ "metadata {1}",
+ decl->getDeclKindName(), user_id);
+ }
+ return nullptr;
+ }
+
+ return *result;
+}
+
+class DeclContextOverride {
+private:
+ struct Backup {
+ clang::DeclContext *decl_context;
+ clang::DeclContext *lexical_decl_context;
+ };
+
+ llvm::DenseMap<clang::Decl *, Backup> m_backups;
+
+ void OverrideOne(clang::Decl *decl) {
+ if (m_backups.find(decl) != m_backups.end()) {
+ return;
+ }
+
+ m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()};
+
+ decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
+ decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
+ }
+
+ bool ChainPassesThrough(
+ clang::Decl *decl, clang::DeclContext *base,
+ clang::DeclContext *(clang::Decl::*contextFromDecl)(),
+ clang::DeclContext *(clang::DeclContext::*contextFromContext)()) {
+ for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx;
+ decl_ctx = (decl_ctx->*contextFromContext)()) {
+ if (decl_ctx == base) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ clang::Decl *GetEscapedChild(clang::Decl *decl,
+ clang::DeclContext *base = nullptr) {
+ if (base) {
+ // decl's DeclContext chains must pass through base.
+
+ if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext,
+ &clang::DeclContext::getParent) ||
+ !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext,
+ &clang::DeclContext::getLexicalParent)) {
+ return decl;
+ }
+ } else {
+ base = clang::dyn_cast<clang::DeclContext>(decl);
+
+ if (!base) {
+ return nullptr;
+ }
+ }
+
+ if (clang::DeclContext *context =
+ clang::dyn_cast<clang::DeclContext>(decl)) {
+ for (clang::Decl *decl : context->decls()) {
+ if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+ return escaped_child;
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+ void Override(clang::Decl *decl) {
+ if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeclContextOverride couldn't "
+ "override ({0}Decl*){1} - its child ({2}Decl*){3} escapes",
+ decl->getDeclKindName(), decl, escaped_child->getDeclKindName(),
+ escaped_child);
+ lldbassert(0 && "Couldn't override!");
+ }
+
+ OverrideOne(decl);
+ }
+
+public:
+ DeclContextOverride() {}
+
+ void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
+ for (DeclContext *decl_context = decl->getLexicalDeclContext();
+ decl_context; decl_context = decl_context->getLexicalParent()) {
+ DeclContext *redecl_context = decl_context->getRedeclContext();
+
+ if (llvm::isa<FunctionDecl>(redecl_context) &&
+ llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) {
+ for (clang::Decl *child_decl : decl_context->decls()) {
+ Override(child_decl);
+ }
+ }
+ }
+ }
+
+ ~DeclContextOverride() {
+ for (const std::pair<clang::Decl *, Backup> &backup : m_backups) {
+ backup.first->setDeclContext(backup.second.decl_context);
+ backup.first->setLexicalDeclContext(backup.second.lexical_decl_context);
+ }
+ }
+};
+
+namespace {
+/// Completes all imported TagDecls at the end of the scope.
+///
+/// While in a CompleteTagDeclsScope, every decl that could be completed will
+/// be completed at the end of the scope (including all Decls that are
+/// imported while completing the original Decls).
+class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener {
+ ClangASTImporter::ImporterDelegateSP m_delegate;
+ llvm::SmallVector<NamedDecl *, 32> m_decls_to_complete;
+ llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed;
+ clang::ASTContext *m_dst_ctx;
+ clang::ASTContext *m_src_ctx;
+ ClangASTImporter &importer;
+
+public:
+ /// Constructs a CompleteTagDeclsScope.
+ /// \param importer The ClangASTImporter that we should observe.
+ /// \param dst_ctx The ASTContext to which Decls are imported.
+ /// \param src_ctx The ASTContext from which Decls are imported.
+ explicit CompleteTagDeclsScope(ClangASTImporter &importer,
+ clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx)
+ : m_delegate(importer.GetDelegate(dst_ctx, src_ctx)), m_dst_ctx(dst_ctx),
+ m_src_ctx(src_ctx), importer(importer) {
+ m_delegate->SetImportListener(this);
+ }
+
+ virtual ~CompleteTagDeclsScope() {
+ ClangASTImporter::ASTContextMetadataSP to_context_md =
+ importer.GetContextMetadata(m_dst_ctx);
+
+ // Complete all decls we collected until now.
+ while (!m_decls_to_complete.empty()) {
+ NamedDecl *decl = m_decls_to_complete.pop_back_val();
+ m_decls_already_completed.insert(decl);
+
+ // We should only complete decls coming from the source context.
+ assert(to_context_md->m_origins[decl].ctx == m_src_ctx);
+
+ Decl *original_decl = to_context_md->m_origins[decl].decl;
+
+ // Complete the decl now.
+ TypeSystemClang::GetCompleteDecl(m_src_ctx, original_decl);
+ if (auto *tag_decl = dyn_cast<TagDecl>(decl)) {
+ if (auto *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
+ if (original_tag_decl->isCompleteDefinition()) {
+ m_delegate->ImportDefinitionTo(tag_decl, original_tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
+
+ tag_decl->setHasExternalLexicalStorage(false);
+ tag_decl->setHasExternalVisibleStorage(false);
+ } else if (auto *container_decl = dyn_cast<ObjCContainerDecl>(decl)) {
+ container_decl->setHasExternalLexicalStorage(false);
+ container_decl->setHasExternalVisibleStorage(false);
+ }
+
+ to_context_md->m_origins.erase(decl);
+ }
+
+ // Stop listening to imported decls. We do this after clearing the
+ // Decls we needed to import to catch all Decls they might have pulled in.
+ m_delegate->RemoveImportListener();
+ }
+
+ void NewDeclImported(clang::Decl *from, clang::Decl *to) override {
+ // Filter out decls that we can't complete later.
+ if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to))
+ return;
+ RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
+ // We don't need to complete injected class name decls.
+ if (from_record_decl && from_record_decl->isInjectedClassName())
+ return;
+
+ NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+ // Check if we already completed this type.
+ if (m_decls_already_completed.count(to_named_decl) != 0)
+ return;
+ m_decls_to_complete.push_back(to_named_decl);
+ }
+};
+} // namespace
+
+CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst,
+ const CompilerType &src_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ TypeSystemClang *src_ctxt =
+ llvm::cast<TypeSystemClang>(src_type.GetTypeSystem());
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportType called on ({0}Type*){1} "
+ "from (ASTContext*){2} to (ASTContext*){3}",
+ src_type.GetTypeName(), src_type.GetOpaqueQualType(),
+ &src_ctxt->getASTContext(), &dst.getASTContext());
+
+ DeclContextOverride decl_context_override;
+
+ if (auto *t = ClangUtil::GetQualType(src_type)->getAs<TagType>())
+ decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl());
+
+ CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(),
+ &src_ctxt->getASTContext());
+ return CopyType(dst, src_type);
+}
+
+clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
+ clang::Decl *decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ clang::ASTContext *src_ctx = &decl->getASTContext();
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportDecl called on ({0}Decl*){1} from "
+ "(ASTContext*){2} to (ASTContext*){3}",
+ decl->getDeclKindName(), decl, src_ctx, dst_ctx);
+
+ DeclContextOverride decl_context_override;
+
+ decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
+
+ clang::Decl *result;
+ {
+ CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
+ result = CopyDecl(dst_ctx, decl);
+ }
+
+ if (!result)
+ return nullptr;
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportDecl deported ({0}Decl*){1} to "
+ "({2}Decl*){3}",
+ decl->getDeclKindName(), decl, result->getDeclKindName(), result);
+
+ return result;
+}
+
+bool ClangASTImporter::CanImport(const CompilerType &type) {
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(
+ ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (GetDeclOrigin(cxx_record_decl).Valid())
+ return true;
+ }
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ if (GetDeclOrigin(enum_decl).Valid())
+ return true;
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (GetDeclOrigin(class_interface_decl).Valid())
+ return true;
+ }
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ClangASTImporter::Import(const CompilerType &type) {
+ if (!ClangUtil::IsClangType(type))
+ return false;
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(
+ ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (GetDeclOrigin(cxx_record_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ if (GetDeclOrigin(enum_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (GetDeclOrigin(class_interface_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return Import(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) {
+ if (!CanImport(compiler_type))
+ return false;
+
+ if (Import(compiler_type)) {
+ TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+
+ TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
+ false);
+ return false;
+}
+
+bool ClangASTImporter::LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &bit_size,
+ uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets) {
+ RecordDeclToLayoutMap::iterator pos =
+ m_record_decl_to_layout_map.find(record_decl);
+ bool success = false;
+ base_offsets.clear();
+ vbase_offsets.clear();
+ if (pos != m_record_decl_to_layout_map.end()) {
+ bit_size = pos->second.bit_size;
+ alignment = pos->second.alignment;
+ field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap(pos->second.base_offsets);
+ vbase_offsets.swap(pos->second.vbase_offsets);
+ m_record_decl_to_layout_map.erase(pos);
+ success = true;
+ } else {
+ bit_size = 0;
+ alignment = 0;
+ field_offsets.clear();
+ }
+ return success;
+}
+
+void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl,
+ const LayoutInfo &layout) {
+ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
+bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&decl->getASTContext(), decl_origin.ctx));
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
+ &decl->getASTContext());
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(decl, decl_origin.decl);
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
+ clang::TagDecl *origin_decl) {
+ clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
+
+ if (!TypeSystemClang::GetCompleteDecl(origin_ast_ctx, origin_decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&decl->getASTContext(), origin_ast_ctx));
+
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(decl, origin_decl);
+
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteObjCInterfaceDecl(
+ clang::ObjCInterfaceDecl *interface_decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx));
+
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
+
+ if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
+ RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) {
+ if (!RequireCompleteType(type))
+ return false;
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ if (const TagType *tag_type = type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ DeclOrigin decl_origin = GetDeclOrigin(tag_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx));
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
+ &tag_decl->getASTContext());
+
+ TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
+
+ for (Decl *origin_child_decl : origin_tag_decl->decls()) {
+ llvm::Expected<Decl *> imported_or_err =
+ delegate_sp->Import(origin_child_decl);
+ if (!imported_or_err) {
+ LLDB_LOG_ERROR(log, imported_or_err.takeError(),
+ "Couldn't import decl: {0}");
+ return false;
+ }
+ }
+
+ if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl))
+ record_decl->setHasLoadedFieldsFromExternalStorage(true);
+
+ return true;
+ }
+
+ if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+ if (ObjCInterfaceDecl *objc_interface_decl =
+ objc_object_type->getInterface()) {
+ DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx));
+
+ ObjCInterfaceDecl *origin_interface_decl =
+ llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
+
+ for (Decl *origin_child_decl : origin_interface_decl->decls()) {
+ llvm::Expected<Decl *> imported_or_err =
+ delegate_sp->Import(origin_child_decl);
+ if (!imported_or_err) {
+ LLDB_LOG_ERROR(log, imported_or_err.takeError(),
+ "Couldn't import decl: {0}");
+ return false;
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ClangASTImporter::RequireCompleteType(clang::QualType type) {
+ if (type.isNull())
+ return false;
+
+ if (const TagType *tag_type = type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
+ return true;
+
+ return CompleteTagDecl(tag_decl);
+ }
+ if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+ if (ObjCInterfaceDecl *objc_interface_decl =
+ objc_object_type->getInterface())
+ return CompleteObjCInterfaceDecl(objc_interface_decl);
+ return false;
+ }
+ if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
+ return RequireCompleteType(array_type->getElementType());
+ if (const AtomicType *atomic_type = type->getAs<AtomicType>())
+ return RequireCompleteType(atomic_type->getPointeeType());
+
+ return true;
+}
+
+ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(decl);
+
+ if (decl_origin.Valid()) {
+ TypeSystemClang *ast = TypeSystemClang::GetASTContext(decl_origin.ctx);
+ return ast->GetMetadata(decl_origin.decl);
+ }
+ TypeSystemClang *ast = TypeSystemClang::GetASTContext(&decl->getASTContext());
+ return ast->GetMetadata(decl);
+}
+
+ClangASTImporter::DeclOrigin
+ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ OriginMap::iterator iter = origins.find(decl);
+
+ if (iter != origins.end())
+ return iter->second;
+ return DeclOrigin();
+}
+
+void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
+ clang::Decl *original_decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ OriginMap::iterator iter = origins.find(decl);
+
+ if (iter != origins.end()) {
+ iter->second.decl = original_decl;
+ iter->second.ctx = &original_decl->getASTContext();
+ return;
+ }
+ origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+}
+
+void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ context_md->m_namespace_maps[decl] = namespace_map;
+}
+
+ClangASTImporter::NamespaceMapSP
+ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
+
+ NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
+
+ if (iter != namespace_maps.end())
+ return iter->second;
+ return NamespaceMapSP();
+}
+
+void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
+ assert(decl);
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ const DeclContext *parent_context = decl->getDeclContext();
+ const NamespaceDecl *parent_namespace =
+ dyn_cast<NamespaceDecl>(parent_context);
+ NamespaceMapSP parent_map;
+
+ if (parent_namespace)
+ parent_map = GetNamespaceMap(parent_namespace);
+
+ NamespaceMapSP new_map;
+
+ new_map = std::make_shared<NamespaceMap>();
+
+ if (context_md->m_map_completer) {
+ std::string namespace_string = decl->getDeclName().getAsString();
+
+ context_md->m_map_completer->CompleteNamespaceMap(
+ new_map, ConstString(namespace_string.c_str()), parent_map);
+ }
+
+ context_md->m_namespace_maps[decl] = new_map;
+}
+
+void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Forgetting destination (ASTContext*){0}",
+ dst_ast);
+
+ m_metadata_map.erase(dst_ast);
+}
+
+void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
+ clang::ASTContext *src_ast) {
+ ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Forgetting source->dest "
+ "(ASTContext*){0}->(ASTContext*){1}",
+ src_ast, dst_ast);
+
+ if (!md)
+ return;
+
+ md->m_delegates.erase(src_ast);
+
+ for (OriginMap::iterator iter = md->m_origins.begin();
+ iter != md->m_origins.end();) {
+ if (iter->second.ctx == src_ast)
+ md->m_origins.erase(iter++);
+ else
+ ++iter;
+ }
+}
+
+ClangASTImporter::MapCompleter::~MapCompleter() { return; }
+
+llvm::Expected<Decl *>
+ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
+ if (m_std_handler) {
+ llvm::Optional<Decl *> D = m_std_handler->Import(From);
+ if (D) {
+ // Make sure we don't use this decl later to map it back to it's original
+ // decl. The decl the CxxModuleHandler created has nothing to do with
+ // the one from debug info, and linking those two would just cause the
+ // ASTImporter to try 'updating' the module decl with the minimal one from
+ // the debug info.
+ m_decls_to_ignore.insert(*D);
+ return *D;
+ }
+ }
+
+ // Check which ASTContext this declaration originally came from.
+ DeclOrigin origin = m_master.GetDeclOrigin(From);
+ // If it originally came from the target ASTContext then we can just
+ // pretend that the original is the one we imported. This can happen for
+ // example when inspecting a persistent declaration from the scratch
+ // ASTContext (which will provide the declaration when parsing the
+ // expression and then we later try to copy the declaration back to the
+ // scratch ASTContext to store the result).
+ // Without this check we would ask the ASTImporter to import a declaration
+ // into the same ASTContext where it came from (which doesn't make a lot of
+ // sense).
+ if (origin.Valid() && origin.ctx == &getToContext()) {
+ RegisterImportedDecl(From, origin.decl);
+ return origin.decl;
+ }
+
+ // This declaration came originally from another ASTContext. Instead of
+ // copying our potentially incomplete 'From' Decl we instead go to the
+ // original ASTContext and copy the original to the target. This is not
+ // only faster than first completing our current decl and then copying it
+ // to the target, but it also prevents that indirectly copying the same
+ // declaration to the same target requires the ASTImporter to merge all
+ // the different decls that appear to come from different ASTContexts (even
+ // though all these different source ASTContexts just got a copy from
+ // one source AST).
+ if (origin.Valid()) {
+ auto R = m_master.CopyDecl(&getToContext(), origin.decl);
+ if (R) {
+ RegisterImportedDecl(From, R);
+ return R;
+ }
+ }
+
+ // If we have a forcefully completed type, try to find an actual definition
+ // for it in other modules.
+ const ClangASTMetadata *md = m_master.GetDeclMetadata(From);
+ auto *td = dyn_cast<TagDecl>(From);
+ if (td && md && md->IsForcefullyCompleted()) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG(log,
+ "[ClangASTImporter] Searching for a complete definition of {0} in "
+ "other modules",
+ td->getName());
+ Expected<DeclContext *> dc_or_err = ImportContext(td->getDeclContext());
+ if (!dc_or_err)
+ return dc_or_err.takeError();
+ Expected<DeclarationName> dn_or_err = Import(td->getDeclName());
+ if (!dn_or_err)
+ return dn_or_err.takeError();
+ DeclContext *dc = *dc_or_err;
+ DeclContext::lookup_result lr = dc->lookup(*dn_or_err);
+ if (lr.size()) {
+ clang::Decl *lookup_found = lr.front();
+ RegisterImportedDecl(From, lookup_found);
+ m_decls_to_ignore.insert(lookup_found);
+ return lookup_found;
+ } else
+ LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
+ }
+
+ return ASTImporter::ImportImpl(From);
+}
+
+void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
+ clang::Decl *to, clang::Decl *from) {
+ // We might have a forward declaration from a shared library that we
+ // gave external lexical storage so that Clang asks us about the full
+ // definition when it needs it. In this case the ASTImporter isn't aware
+ // that the forward decl from the shared library is the actual import
+ // target but would create a second declaration that would then be defined.
+ // We want that 'to' is actually complete after this function so let's
+ // tell the ASTImporter that 'to' was imported from 'from'.
+ MapImported(from, to);
+ ASTImporter::Imported(from, to);
+
+ /*
+ if (to_objc_interface)
+ to_objc_interface->startDefinition();
+
+ CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
+
+ if (to_cxx_record)
+ to_cxx_record->startDefinition();
+ */
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ if (llvm::Error err = ImportDefinition(from)) {
+ LLDB_LOG_ERROR(log, std::move(err),
+ "[ClangASTImporter] Error during importing definition: {0}");
+ return;
+ }
+
+ if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) {
+ if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) {
+ to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
+
+ if (Log *log_ast =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+ std::string name_string;
+ if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
+ llvm::raw_string_ostream name_stream(name_string);
+ from_named_decl->printName(name_stream);
+ name_stream.flush();
+ }
+ LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported "
+ "({1}Decl*){2}, named {3} (from "
+ "(Decl*){4})",
+ static_cast<void *>(to->getTranslationUnitDecl()),
+ from->getDeclKindName(), static_cast<void *>(to), name_string,
+ static_cast<void *>(from));
+
+ // Log the AST of the TU.
+ std::string ast_string;
+ llvm::raw_string_ostream ast_stream(ast_string);
+ to->getTranslationUnitDecl()->dump(ast_stream);
+ LLDB_LOG(log_ast, "{0}", ast_string);
+ }
+ }
+ }
+
+ // If we're dealing with an Objective-C class, ensure that the inheritance
+ // has been set up correctly. The ASTImporter may not do this correctly if
+ // the class was originally sourced from symbols.
+
+ if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
+ do {
+ ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
+
+ if (to_superclass)
+ break; // we're not going to override it if it's set
+
+ ObjCInterfaceDecl *from_objc_interface =
+ dyn_cast<ObjCInterfaceDecl>(from);
+
+ if (!from_objc_interface)
+ break;
+
+ ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
+
+ if (!from_superclass)
+ break;
+
+ llvm::Expected<Decl *> imported_from_superclass_decl =
+ Import(from_superclass);
+
+ if (!imported_from_superclass_decl) {
+ LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(),
+ "Couldn't import decl: {0}");
+ break;
+ }
+
+ ObjCInterfaceDecl *imported_from_superclass =
+ dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl);
+
+ if (!imported_from_superclass)
+ break;
+
+ if (!to_objc_interface->hasDefinition())
+ to_objc_interface->startDefinition();
+
+ to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo(
+ m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
+ } while (false);
+ }
+}
+
+/// Takes a CXXMethodDecl and completes the return type if necessary. This
+/// is currently only necessary for virtual functions with covariant return
+/// types where Clang's CodeGen expects that the underlying records are already
+/// completed.
+static void MaybeCompleteReturnType(ClangASTImporter &importer,
+ CXXMethodDecl *to_method) {
+ if (!to_method->isVirtual())
+ return;
+ QualType return_type = to_method->getReturnType();
+ if (!return_type->isPointerType() && !return_type->isReferenceType())
+ return;
+
+ clang::RecordDecl *rd = return_type->getPointeeType()->getAsRecordDecl();
+ if (!rd)
+ return;
+ if (rd->getDefinition())
+ return;
+
+ importer.CompleteTagDecl(rd);
+}
+
+/// Recreate a module with its parents in \p to_source and return its id.
+static OptionalClangModuleID
+RemapModule(OptionalClangModuleID from_id,
+ ClangExternalASTSourceCallbacks &from_source,
+ ClangExternalASTSourceCallbacks &to_source) {
+ if (!from_id.HasValue())
+ return {};
+ clang::Module *module = from_source.getModule(from_id.GetValue());
+ OptionalClangModuleID parent = RemapModule(
+ from_source.GetIDForModule(module->Parent), from_source, to_source);
+ TypeSystemClang &to_ts = to_source.GetTypeSystem();
+ return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework,
+ module->IsExplicit);
+}
+
+void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
+ clang::Decl *to) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // Some decls shouldn't be tracked here because they were not created by
+ // copying 'from' to 'to'. Just exit early for those.
+ if (m_decls_to_ignore.count(to))
+ return clang::ASTImporter::Imported(from, to);
+
+ // Transfer module ownership information.
+ auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getFromContext().getExternalSource());
+ // Can also be a ClangASTSourceProxy.
+ auto *to_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getToContext().getExternalSource());
+ if (from_source && to_source) {
+ OptionalClangModuleID from_id(from->getOwningModuleID());
+ OptionalClangModuleID to_id =
+ RemapModule(from_id, *from_source, *to_source);
+ TypeSystemClang &to_ts = to_source->GetTypeSystem();
+ to_ts.SetOwningModule(to, to_id);
+ }
+
+ lldb::user_id_t user_id = LLDB_INVALID_UID;
+ ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
+ if (log) {
+ if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
+ std::string name_string;
+ llvm::raw_string_ostream name_stream(name_string);
+ from_named_decl->printName(name_stream);
+ name_stream.flush();
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Imported ({0}Decl*){1}, named {2} (from "
+ "(Decl*){3}), metadata {4}",
+ from->getDeclKindName(), to, name_string, from, user_id);
+ } else {
+ LLDB_LOG(log,
+ " [ClangASTImporter] Imported ({0}Decl*){1} (from "
+ "(Decl*){2}), metadata {3}",
+ from->getDeclKindName(), to, from, user_id);
+ }
+ }
+
+ ASTContextMetadataSP to_context_md =
+ m_master.GetContextMetadata(&to->getASTContext());
+ ASTContextMetadataSP from_context_md =
+ m_master.MaybeGetContextMetadata(m_source_ctx);
+
+ if (from_context_md) {
+ OriginMap &origins = from_context_md->m_origins;
+
+ OriginMap::iterator origin_iter = origins.find(from);
+
+ if (origin_iter != origins.end()) {
+ if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+ user_id != LLDB_INVALID_UID) {
+ if (origin_iter->second.ctx != &to->getASTContext())
+ to_context_md->m_origins[to] = origin_iter->second;
+ }
+
+ ImporterDelegateSP direct_completer =
+ m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);
+
+ if (direct_completer.get() != this)
+ direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Propagated origin "
+ "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
+ "(ASTContext*){3}",
+ origin_iter->second.decl, origin_iter->second.ctx,
+ &from->getASTContext(), &to->getASTContext());
+ } else {
+ if (m_new_decl_listener)
+ m_new_decl_listener->NewDeclImported(from, to);
+
+ if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+ user_id != LLDB_INVALID_UID) {
+ to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+ }
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Decl has no origin information in "
+ "(ASTContext*){0}",
+ &from->getASTContext());
+ }
+
+ if (auto *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) {
+ auto *from_namespace = cast<clang::NamespaceDecl>(from);
+
+ NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
+
+ NamespaceMetaMap::iterator namespace_map_iter =
+ namespace_maps.find(from_namespace);
+
+ if (namespace_map_iter != namespace_maps.end())
+ to_context_md->m_namespace_maps[to_namespace] =
+ namespace_map_iter->second;
+ }
+ } else {
+ to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Sourced origin "
+ "(Decl*){0}/(ASTContext*){1} into (ASTContext*){2}",
+ from, m_source_ctx, &to->getASTContext());
+ }
+
+ if (auto *to_tag_decl = dyn_cast<TagDecl>(to)) {
+ to_tag_decl->setHasExternalLexicalStorage();
+ to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();
+ auto from_tag_decl = cast<TagDecl>(from);
+
+ LLDB_LOG(
+ log,
+ " [ClangASTImporter] To is a TagDecl - attributes {0}{1} [{2}->{3}]",
+ (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
+ (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
+ }
+
+ if (auto *to_namespace_decl = dyn_cast<NamespaceDecl>(to)) {
+ m_master.BuildNamespaceMap(to_namespace_decl);
+ to_namespace_decl->setHasExternalVisibleStorage();
+ }
+
+ if (auto *to_container_decl = dyn_cast<ObjCContainerDecl>(to)) {
+ to_container_decl->setHasExternalLexicalStorage();
+ to_container_decl->setHasExternalVisibleStorage();
+
+ if (log) {
+ if (ObjCInterfaceDecl *to_interface_decl =
+ llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
+ LLDB_LOG(
+ log,
+ " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
+ "{0}{1}{2}",
+ (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ } else {
+ LLDB_LOG(
+ log, " [ClangASTImporter] To is an {0}Decl - attributes {1}{2}",
+ ((Decl *)to_container_decl)->getDeclKindName(),
+ (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+ }
+ }
+ }
+
+ if (clang::CXXMethodDecl *to_method = dyn_cast<CXXMethodDecl>(to))
+ MaybeCompleteReturnType(m_master, to_method);
+}
+
+clang::Decl *
+ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) {
+ return m_master.GetDeclOrigin(To).decl;
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
new file mode 100644
index 000000000000..6ceec774914b
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -0,0 +1,328 @@
+//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
+
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/lldb-types.h"
+
+#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata;
+class TypeSystemClang;
+
+class ClangASTImporter {
+public:
+ struct LayoutInfo {
+ LayoutInfo() = default;
+ typedef llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ OffsetMap;
+
+ uint64_t bit_size = 0;
+ uint64_t alignment = 0;
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
+ OffsetMap base_offsets;
+ OffsetMap vbase_offsets;
+ };
+
+ ClangASTImporter()
+ : m_file_manager(clang::FileSystemOptions(),
+ FileSystem::Instance().GetVirtualFileSystem()) {}
+
+ CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type);
+
+ clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
+
+ CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type);
+
+ clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
+
+ /// Sets the layout for the given RecordDecl. The layout will later be
+ /// used by Clang's during code generation. Not calling this function for
+ /// a RecordDecl will cause that Clang's codegen tries to layout the
+ /// record by itself.
+ ///
+ /// \param decl The RecordDecl to set the layout for.
+ /// \param layout The layout for the record.
+ void SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout);
+
+ bool LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &bit_size,
+ uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets);
+
+ bool CanImport(const CompilerType &type);
+
+ bool Import(const CompilerType &type);
+
+ bool CompleteType(const CompilerType &compiler_type);
+
+ bool CompleteTagDecl(clang::TagDecl *decl);
+
+ bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin);
+
+ bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl);
+
+ bool CompleteAndFetchChildren(clang::QualType type);
+
+ bool RequireCompleteType(clang::QualType type);
+
+ void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);
+
+ ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);
+
+ //
+ // Namespace maps
+ //
+
+ typedef std::pair<lldb::ModuleSP, CompilerDeclContext> NamespaceMapItem;
+ typedef std::vector<NamespaceMapItem> NamespaceMap;
+ typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
+
+ void RegisterNamespaceMap(const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map);
+
+ NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl);
+
+ void BuildNamespaceMap(const clang::NamespaceDecl *decl);
+
+ //
+ // Completers for maps
+ //
+
+ class MapCompleter {
+ public:
+ virtual ~MapCompleter();
+
+ virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map,
+ ConstString name,
+ NamespaceMapSP &parent_map) const = 0;
+ };
+
+ void InstallMapCompleter(clang::ASTContext *dst_ctx,
+ MapCompleter &completer) {
+ ASTContextMetadataSP context_md;
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end()) {
+ context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ } else {
+ context_md = context_md_iter->second;
+ }
+
+ context_md->m_map_completer = &completer;
+ }
+
+ void ForgetDestination(clang::ASTContext *dst_ctx);
+ void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
+
+ struct DeclOrigin {
+ DeclOrigin() : ctx(nullptr), decl(nullptr) {}
+
+ DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
+ : ctx(_ctx), decl(_decl) {}
+
+ DeclOrigin(const DeclOrigin &rhs) {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ void operator=(const DeclOrigin &rhs) {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ bool Valid() { return (ctx != nullptr || decl != nullptr); }
+
+ clang::ASTContext *ctx;
+ clang::Decl *decl;
+ };
+
+ typedef llvm::DenseMap<const clang::Decl *, DeclOrigin> OriginMap;
+
+ /// Listener interface used by the ASTImporterDelegate to inform other code
+ /// about decls that have been imported the first time.
+ struct NewDeclListener {
+ virtual ~NewDeclListener() = default;
+ /// A decl has been imported for the first time.
+ virtual void NewDeclImported(clang::Decl *from, clang::Decl *to) = 0;
+ };
+
+ /// ASTImporter that intercepts and records the import process of the
+ /// underlying ASTImporter.
+ ///
+ /// This class updates the map from declarations to their original
+ /// declarations and can record declarations that have been imported in a
+ /// certain interval.
+ ///
+ /// When intercepting a declaration import, the ASTImporterDelegate uses the
+ /// CxxModuleHandler to replace any missing or malformed declarations with
+ /// their counterpart from a C++ module.
+ struct ASTImporterDelegate : public clang::ASTImporter {
+ ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx,
+ clang::ASTContext *source_ctx)
+ : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
+ master.m_file_manager, true /*minimal*/),
+ m_master(master), m_source_ctx(source_ctx) {
+ setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal);
+ }
+
+ /// Scope guard that attaches a CxxModuleHandler to an ASTImporterDelegate
+ /// and deattaches it at the end of the scope. Supports being used multiple
+ /// times on the same ASTImporterDelegate instance in nested scopes.
+ class CxxModuleScope {
+ /// The handler we attach to the ASTImporterDelegate.
+ CxxModuleHandler m_handler;
+ /// The ASTImporterDelegate we are supposed to attach the handler to.
+ ASTImporterDelegate &m_delegate;
+ /// True iff we attached the handler to the ASTImporterDelegate.
+ bool m_valid = false;
+
+ public:
+ CxxModuleScope(ASTImporterDelegate &delegate, clang::ASTContext *dst_ctx)
+ : m_delegate(delegate) {
+ // If the delegate doesn't have a CxxModuleHandler yet, create one
+ // and attach it.
+ if (!delegate.m_std_handler) {
+ m_handler = CxxModuleHandler(delegate, dst_ctx);
+ m_valid = true;
+ delegate.m_std_handler = &m_handler;
+ }
+ }
+ ~CxxModuleScope() {
+ if (m_valid) {
+ // Make sure no one messed with the handler we placed.
+ assert(m_delegate.m_std_handler == &m_handler);
+ m_delegate.m_std_handler = nullptr;
+ }
+ }
+ };
+
+ void ImportDefinitionTo(clang::Decl *to, clang::Decl *from);
+
+ void Imported(clang::Decl *from, clang::Decl *to) override;
+
+ clang::Decl *GetOriginalDecl(clang::Decl *To) override;
+
+ void SetImportListener(NewDeclListener *listener) {
+ assert(m_new_decl_listener == nullptr && "Already attached a listener?");
+ m_new_decl_listener = listener;
+ }
+ void RemoveImportListener() { m_new_decl_listener = nullptr; }
+
+ protected:
+ llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override;
+
+ private:
+ /// Decls we should ignore when mapping decls back to their original
+ /// ASTContext. Used by the CxxModuleHandler to mark declarations that
+ /// were created from the 'std' C++ module to prevent that the Importer
+ /// tries to sync them with the broken equivalent in the debug info AST.
+ llvm::SmallPtrSet<clang::Decl *, 16> m_decls_to_ignore;
+ ClangASTImporter &m_master;
+ clang::ASTContext *m_source_ctx;
+ CxxModuleHandler *m_std_handler = nullptr;
+ /// The currently attached listener.
+ NewDeclListener *m_new_decl_listener = nullptr;
+ };
+
+ typedef std::shared_ptr<ASTImporterDelegate> ImporterDelegateSP;
+ typedef llvm::DenseMap<clang::ASTContext *, ImporterDelegateSP> DelegateMap;
+ typedef llvm::DenseMap<const clang::NamespaceDecl *, NamespaceMapSP>
+ NamespaceMetaMap;
+
+ struct ASTContextMetadata {
+ ASTContextMetadata(clang::ASTContext *dst_ctx)
+ : m_dst_ctx(dst_ctx), m_delegates(), m_origins(), m_namespace_maps(),
+ m_map_completer(nullptr) {}
+
+ clang::ASTContext *m_dst_ctx;
+ DelegateMap m_delegates;
+ OriginMap m_origins;
+
+ NamespaceMetaMap m_namespace_maps;
+ MapCompleter *m_map_completer;
+ };
+
+ typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
+ typedef llvm::DenseMap<const clang::ASTContext *, ASTContextMetadataSP>
+ ContextMetadataMap;
+
+ ContextMetadataMap m_metadata_map;
+
+ ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end()) {
+ ASTContextMetadataSP context_md =
+ ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ return context_md;
+ }
+ return context_md_iter->second;
+ }
+
+ ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter != m_metadata_map.end())
+ return context_md_iter->second;
+ return ASTContextMetadataSP();
+ }
+
+ ImporterDelegateSP GetDelegate(clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx) {
+ ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
+
+ DelegateMap &delegates = context_md->m_delegates;
+ DelegateMap::iterator delegate_iter = delegates.find(src_ctx);
+
+ if (delegate_iter == delegates.end()) {
+ ImporterDelegateSP delegate =
+ ImporterDelegateSP(new ASTImporterDelegate(*this, dst_ctx, src_ctx));
+ delegates[src_ctx] = delegate;
+ return delegate;
+ }
+ return delegate_iter->second;
+ }
+
+ DeclOrigin GetDeclOrigin(const clang::Decl *decl);
+
+ clang::FileManager m_file_manager;
+ typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo>
+ RecordDeclToLayoutMap;
+
+ RecordDeclToLayoutMap m_record_decl_to_layout_map;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
new file mode 100644
index 000000000000..42933c78b027
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
@@ -0,0 +1,35 @@
+//===-- ClangASTMetadata.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb_private;
+
+void ClangASTMetadata::Dump(Stream *s) {
+ lldb::user_id_t uid = GetUserID();
+
+ if (uid != LLDB_INVALID_UID) {
+ s->Printf("uid=0x%" PRIx64, uid);
+ }
+
+ uint64_t isa_ptr = GetISAPtr();
+ if (isa_ptr != 0) {
+ s->Printf("isa_ptr=0x%" PRIx64, isa_ptr);
+ }
+
+ const char *obj_ptr_name = GetObjectPtrName();
+ if (obj_ptr_name) {
+ s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name);
+ }
+
+ if (m_is_dynamic_cxx) {
+ s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
+ }
+ s->EOL();
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h
new file mode 100644
index 000000000000..d3bcde2ced79
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h
@@ -0,0 +1,110 @@
+//===-- ClangASTMetadata.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
+
+#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata {
+public:
+ ClangASTMetadata()
+ : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false),
+ m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true),
+ m_is_forcefully_completed(false) {}
+
+ bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; }
+
+ void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; }
+
+ void SetUserID(lldb::user_id_t user_id) {
+ m_user_id = user_id;
+ m_union_is_user_id = true;
+ m_union_is_isa_ptr = false;
+ }
+
+ lldb::user_id_t GetUserID() const {
+ if (m_union_is_user_id)
+ return m_user_id;
+ else
+ return LLDB_INVALID_UID;
+ }
+
+ void SetISAPtr(uint64_t isa_ptr) {
+ m_isa_ptr = isa_ptr;
+ m_union_is_user_id = false;
+ m_union_is_isa_ptr = true;
+ }
+
+ uint64_t GetISAPtr() const {
+ if (m_union_is_isa_ptr)
+ return m_isa_ptr;
+ else
+ return 0;
+ }
+
+ void SetObjectPtrName(const char *name) {
+ m_has_object_ptr = true;
+ if (strcmp(name, "self") == 0)
+ m_is_self = true;
+ else if (strcmp(name, "this") == 0)
+ m_is_self = false;
+ else
+ m_has_object_ptr = false;
+ }
+
+ lldb::LanguageType GetObjectPtrLanguage() const {
+ if (m_has_object_ptr) {
+ if (m_is_self)
+ return lldb::eLanguageTypeObjC;
+ else
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+ return lldb::eLanguageTypeUnknown;
+ }
+
+ const char *GetObjectPtrName() const {
+ if (m_has_object_ptr) {
+ if (m_is_self)
+ return "self";
+ else
+ return "this";
+ } else
+ return nullptr;
+ }
+
+ bool HasObjectPtr() const { return m_has_object_ptr; }
+
+ /// A type is "forcefully completed" if it was declared complete to satisfy an
+ /// AST invariant (e.g. base classes must be complete types), but in fact we
+ /// were not able to find a actual definition for it.
+ bool IsForcefullyCompleted() const { return m_is_forcefully_completed; }
+
+ void SetIsForcefullyCompleted(bool value = true) {
+ m_is_forcefully_completed = true;
+ }
+
+ void Dump(Stream *s);
+
+private:
+ union {
+ lldb::user_id_t m_user_id;
+ uint64_t m_isa_ptr;
+ };
+
+ bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1,
+ m_is_self : 1, m_is_dynamic_cxx : 1, m_is_forcefully_completed : 1;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 42927ab6cc8a..6fe85a1298fc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -1,4 +1,4 @@
-//===-- ClangASTSource.cpp ---------------------------------------*- C++-*-===//
+//===-- ClangASTSource.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,8 +13,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -23,8 +21,11 @@
#include "lldb/Utility/Log.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/SourceManager.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include <memory>
#include <vector>
@@ -49,14 +50,16 @@ private:
};
}
-ClangASTSource::ClangASTSource(const lldb::TargetSP &target,
- const lldb::ClangASTImporterSP &importer)
- : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
- m_ast_context(nullptr), m_active_lexical_decls(), m_active_lookups() {
- m_ast_importer_sp = importer;
+ClangASTSource::ClangASTSource(
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer)
+ : m_lookups_enabled(false), m_target(target), m_ast_context(nullptr),
+ m_ast_importer_sp(importer), m_active_lexical_decls(),
+ m_active_lookups() {
+ assert(m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?");
}
-void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) {
+void ClangASTSource::InstallASTContext(TypeSystemClang &clang_ast_context) {
m_ast_context = &clang_ast_context.getASTContext();
m_clang_ast_context = &clang_ast_context;
m_file_manager = &m_ast_context->getSourceManager().getFileManager();
@@ -64,18 +67,15 @@ void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) {
}
ClangASTSource::~ClangASTSource() {
- if (!m_ast_importer_sp)
- return;
-
m_ast_importer_sp->ForgetDestination(m_ast_context);
if (!m_target)
return;
// We are in the process of destruction, don't create clang ast context on
// demand by passing false to
- // Target::GetScratchClangASTContext(create_on_demand).
- ClangASTContext *scratch_clang_ast_context =
- ClangASTContext::GetScratch(*m_target, false);
+ // Target::GetScratchTypeSystemClang(create_on_demand).
+ TypeSystemClang *scratch_clang_ast_context =
+ TypeSystemClang::GetScratch(*m_target, false);
if (!scratch_clang_ast_context)
return;
@@ -103,16 +103,8 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
return false;
}
- if (GetImportInProgress()) {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
-
std::string decl_name(clang_decl_name.getAsString());
- // if (m_decl_map.DoingASTImport ())
- // return DeclContext::lookup_result();
- //
switch (clang_decl_name.getNameKind()) {
// Normal identifiers.
case DeclarationName::Identifier: {
@@ -141,7 +133,7 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
case DeclarationName::ObjCMultiArgSelector: {
llvm::SmallVector<NamedDecl *, 1> method_decls;
- NameSearchContext method_search_context(*this, method_decls,
+ NameSearchContext method_search_context(*m_clang_ast_context, method_decls,
clang_decl_name, decl_ctx);
FindObjCMethodDecls(method_search_context);
@@ -179,154 +171,134 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
return false;
}
m_active_lookups.insert(uniqued_const_decl_name);
- // static uint32_t g_depth = 0;
- // ++g_depth;
- // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth,
- // uniqued_const_decl_name);
llvm::SmallVector<NamedDecl *, 4> name_decls;
- NameSearchContext name_search_context(*this, name_decls, clang_decl_name,
- decl_ctx);
+ NameSearchContext name_search_context(*m_clang_ast_context, name_decls,
+ clang_decl_name, decl_ctx);
FindExternalVisibleDecls(name_search_context);
SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
- // --g_depth;
m_active_lookups.erase(uniqued_const_decl_name);
return (name_decls.size() != 0);
}
-void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
- if (log) {
- LLDB_LOGF(log,
- " CompleteTagDecl[%u] on (ASTContext*)%p Completing "
- "(TagDecl*)%p named %s",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<void *>(tag_decl), tag_decl->getName().str().c_str());
-
- LLDB_LOG(log, " CTD[%u] Before:\n{0}", current_id,
- ClangUtil::DumpDecl(tag_decl));
- }
-
- auto iter = m_active_lexical_decls.find(tag_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(tag_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(decl->getDeclContext())) {
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- if (!m_ast_importer_sp) {
- return;
- }
+ LLDB_LOGV(log, " CTD Inspecting namespace map{0} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
- if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
- // We couldn't complete the type. Maybe there's a definition somewhere
- // else that can be completed.
-
- LLDB_LOGF(log,
- " CTD[%u] Type could not be completed in the module in "
- "which it was first found.",
- current_id);
+ if (!namespace_map)
+ return nullptr;
- bool found = false;
+ for (const ClangASTImporter::NamespaceMapItem &item : *namespace_map) {
+ LLDB_LOG(log, " CTD Searching namespace {0} in module {1}",
+ item.second.GetName(), item.first->GetFileSpec().GetFilename());
- DeclContext *decl_ctx = tag_decl->getDeclContext();
+ TypeList types;
- if (const NamespaceDecl *namespace_context =
- dyn_cast<NamespaceDecl>(decl_ctx)) {
- ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ ConstString name(decl->getName());
- if (log && log->GetVerbose())
- LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types);
- if (!namespace_map)
- return;
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e && !found; ++i) {
- LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ if (!type)
+ continue;
- TypeList types;
+ CompilerType clang_type(type->GetFullCompilerType());
- ConstString name(tag_decl->getName().str().c_str());
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- i->first->FindTypesInNamespace(name, &i->second, UINT32_MAX, types);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ if (!tag_type)
+ continue;
- if (!type)
- continue;
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- CompilerType clang_type(type->GetFullCompilerType());
+ if (TypeSystemClang::GetCompleteDecl(
+ &candidate_tag_decl->getASTContext(), candidate_tag_decl))
+ return candidate_tag_decl;
+ }
+ }
+ } else {
+ TypeList types;
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ ConstString name(decl->getName());
- const TagType *tag_type =
- ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ const ModuleList &module_list = m_target->GetImages();
- if (!tag_type)
- continue;
+ bool exact_match = false;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
+ searched_symbol_files, types);
- TagDecl *candidate_tag_decl =
- const_cast<TagDecl *>(tag_type->getDecl());
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
- candidate_tag_decl))
- found = true;
- }
- }
- } else {
- TypeList types;
+ if (!type)
+ continue;
- ConstString name(tag_decl->getName().str().c_str());
+ CompilerType clang_type(type->GetFullCompilerType());
- const ModuleList &module_list = m_target->GetImages();
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
- searched_symbol_files, types);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ if (!tag_type)
+ continue;
- if (!type)
- continue;
+ TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
- CompilerType clang_type(type->GetFullCompilerType());
+ // We have found a type by basename and we need to make sure the decl
+ // contexts are the same before we can try to complete this type with
+ // another
+ if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
+ candidate_tag_decl))
+ continue;
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
+ candidate_tag_decl))
+ return candidate_tag_decl;
+ }
+ }
+ return nullptr;
+}
- const TagType *tag_type =
- ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!tag_type)
- continue;
+ if (log) {
+ LLDB_LOG(log,
+ " CompleteTagDecl on (ASTContext*){0} Completing "
+ "(TagDecl*){1} named {2}",
+ m_clang_ast_context->getDisplayName(), tag_decl,
+ tag_decl->getName());
- TagDecl *candidate_tag_decl =
- const_cast<TagDecl *>(tag_type->getDecl());
+ LLDB_LOG(log, " CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl));
+ }
- // We have found a type by basename and we need to make sure the decl
- // contexts are the same before we can try to complete this type with
- // another
- if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl))
- continue;
+ auto iter = m_active_lexical_decls.find(tag_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(tag_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
- candidate_tag_decl))
- found = true;
- }
- }
+ if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
+ // We couldn't complete the type. Maybe there's a definition somewhere
+ // else that can be completed.
+ if (TagDecl *alternate = FindCompleteType(tag_decl))
+ m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate);
}
LLDB_LOG(log, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl));
@@ -335,19 +307,14 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOGF(log,
- " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
- "an ObjCInterfaceDecl named %s",
- static_cast<void *>(m_ast_context),
- interface_decl->getName().str().c_str());
+ LLDB_LOG(log,
+ " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
+ "Completing an ObjCInterfaceDecl named {1}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ interface_decl->getName());
LLDB_LOG(log, " [COID] Before:\n{0}",
ClangUtil::DumpDecl(interface_decl));
- if (!m_ast_importer_sp) {
- lldbassert(0 && "No mechanism for completing a type!");
- return;
- }
-
ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
if (original.Valid()) {
@@ -368,10 +335,8 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
interface_decl->getSuperClass() != interface_decl)
CompleteType(interface_decl->getSuperClass());
- if (log) {
- LLDB_LOGF(log, " [COID] After:");
- LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl));
- }
+ LLDB_LOG(log, " [COID] After:");
+ LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl));
}
clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
@@ -420,9 +385,6 @@ void ClangASTSource::FindExternalLexicalDecls(
llvm::function_ref<bool(Decl::Kind)> predicate,
llvm::SmallVectorImpl<Decl *> &decls) {
- if (!m_ast_importer_sp)
- return;
-
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
const Decl *context_decl = dyn_cast<Decl>(decl_context);
@@ -436,29 +398,27 @@ void ClangASTSource::FindExternalLexicalDecls(
m_active_lexical_decls.insert(context_decl);
ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- LLDB_LOGF(
- log,
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
- current_id, static_cast<void *>(m_ast_context),
- context_named_decl->getNameAsString().c_str(),
- context_decl->getDeclKindName(),
- static_cast<const void *>(context_decl));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
+ "'{2}' (%sDecl*){3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ context_named_decl->getNameAsString().c_str(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
else if (context_decl)
- LLDB_LOGF(
- log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
- current_id, static_cast<void *>(m_ast_context),
- context_decl->getDeclKindName(),
- static_cast<const void *>(context_decl));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
+ "({2}Decl*){3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
else
- LLDB_LOGF(
- log,
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
- current_id, static_cast<const void *>(m_ast_context));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
+ "NULL context",
+ m_ast_context, m_clang_ast_context->getDisplayName());
}
ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl);
@@ -466,10 +426,10 @@ void ClangASTSource::FindExternalLexicalDecls(
if (!original.Valid())
return;
- LLDB_LOG(
- log, " FELD[{0}] Original decl (ASTContext*){1:x} (Decl*){2:x}:\n{3}",
- current_id, static_cast<void *>(original.ctx),
- static_cast<void *>(original.decl), ClangUtil::DumpDecl(original.decl));
+ LLDB_LOG(log, " FELD Original decl {0} (Decl*){1:x}:\n{2}",
+ static_cast<void *>(original.ctx),
+ static_cast<void *>(original.decl),
+ ClangUtil::DumpDecl(original.decl));
if (ObjCInterfaceDecl *original_iface_decl =
dyn_cast<ObjCInterfaceDecl>(original.decl)) {
@@ -499,10 +459,7 @@ void ClangASTSource::FindExternalLexicalDecls(
// Indicates whether we skipped any Decls of the original DeclContext.
bool SkippedDecls = false;
- for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
- iter != original_decl_context->decls_end(); ++iter) {
- Decl *decl = *iter;
-
+ for (Decl *decl : original_decl_context->decls()) {
// The predicate function returns true if the passed declaration kind is
// the one we are looking for.
// See clang::ExternalASTSource::FindExternalLexicalDecls()
@@ -511,13 +468,13 @@ void ClangASTSource::FindExternalLexicalDecls(
std::string ast_dump = ClangUtil::DumpDecl(decl);
if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context_decl))
- LLDB_LOGF(log, " FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
- current_id, context_named_decl->getDeclKindName(),
- context_named_decl->getNameAsString().c_str(),
- decl->getDeclKindName(), ast_dump.c_str());
+ LLDB_LOG(log, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}",
+ context_named_decl->getDeclKindName(),
+ context_named_decl->getName(), decl->getDeclKindName(),
+ ast_dump);
else
- LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id,
- decl->getDeclKindName(), ast_dump.c_str());
+ LLDB_LOG(log, " FELD Adding lexical {0}Decl {1}",
+ decl->getDeclKindName(), ast_dump);
}
Decl *copied_decl = CopyDecl(decl);
@@ -556,56 +513,29 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (!context.m_decl_context)
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a NULL DeclContext",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name);
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in '{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ context_named_decl->getName());
else
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(), context.m_decl_context->getDeclKindName());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in a '{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ context.m_decl_context->getDeclKindName());
}
- context.m_namespace_map = std::make_shared<ClangASTImporter::NamespaceMap>();
-
- if (const NamespaceDecl *namespace_context =
- dyn_cast<NamespaceDecl>(context.m_decl_context)) {
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ?
- m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
-
- if (log && log->GetVerbose())
- LLDB_LOGF(log, " CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
-
- if (!namespace_map)
- return;
-
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e; ++i) {
- LLDB_LOGF(log, " CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context, i->first, i->second, current_id);
- }
+ if (isa<NamespaceDecl>(context.m_decl_context)) {
+ LookupInNamespace(context);
} else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
FindObjCPropertyAndIvarDecls(context);
} else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
@@ -614,18 +544,15 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
} else {
CompilerDeclContext namespace_decl;
- LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOG(log, " CAS::FEVD Searching the root namespace");
- FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
}
if (!context.m_namespace_map->empty()) {
if (log && log->GetVerbose())
- LLDB_LOGF(log,
- " CAS::FEVD[%u] Registering namespace map %p (%d entries)",
- current_id, static_cast<void *>(context.m_namespace_map.get()),
- static_cast<int>(context.m_namespace_map->size()));
+ LLDB_LOG(log, " CAS::FEVD Registering namespace map {0} ({1} entries)",
+ context.m_namespace_map.get(), context.m_namespace_map->size());
NamespaceDecl *clang_namespace_decl =
AddNamespace(context, context.m_namespace_map);
@@ -658,7 +585,7 @@ bool ClangASTSource::IgnoreName(const ConstString name,
void ClangASTSource::FindExternalVisibleDecls(
NameSearchContext &context, lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ CompilerDeclContext &namespace_decl) {
assert(m_ast_context);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -672,196 +599,113 @@ void ClangASTSource::FindExternalVisibleDecls(
if (!m_target)
return;
- if (module_sp && namespace_decl) {
- CompilerDeclContext found_namespace_decl;
-
- if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
- found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
+ FillNamespaceMap(context, module_sp, namespace_decl);
- if (found_namespace_decl) {
- context.m_namespace_map->push_back(
- std::pair<lldb::ModuleSP, CompilerDeclContext>(
- module_sp, found_namespace_decl));
-
- LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
- }
- }
- } else {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+ if (context.m_found_type)
+ return;
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ TypeList types;
+ const bool exact_match = true;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ if (module_sp && namespace_decl)
+ module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
+ else {
+ m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
+ searched_symbol_files, types);
+ }
- if (!image)
- continue;
+ if (size_t num_types = types.GetSize()) {
+ for (size_t ti = 0; ti < num_types; ++ti) {
+ lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
- CompilerDeclContext found_namespace_decl;
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- SymbolFile *symbol_file = image->GetSymbolFile();
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
+ (name_string ? name_string : "<anonymous>"));
+ }
- if (!symbol_file)
- continue;
+ CompilerType full_type = type_sp->GetFullCompilerType();
- found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- if (found_namespace_decl) {
- context.m_namespace_map->push_back(
- std::pair<lldb::ModuleSP, CompilerDeclContext>(
- image, found_namespace_decl));
+ if (!copied_clang_type) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
- LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ continue;
}
- }
- }
- do {
- if (context.m_found.type)
- break;
+ context.AddTypeDecl(copied_clang_type);
- TypeList types;
- const bool exact_match = true;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(name, &namespace_decl, 1, types);
- else {
- m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
- searched_symbol_files, types);
+ context.m_found_type = true;
+ break;
}
+ }
- if (size_t num_types = types.GetSize()) {
- for (size_t ti = 0; ti < num_types; ++ti) {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- if (log) {
- const char *name_string = type_sp->GetName().GetCString();
+ if (!context.m_found_type) {
+ // Try the modules next.
+ FindDeclInModules(context, name);
+ }
- LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id, name.GetCString(),
- (name_string ? name_string : "<anonymous>"));
- }
+ if (!context.m_found_type) {
+ FindDeclInObjCRuntime(context, name);
+ }
+}
- CompilerType full_type = type_sp->GetFullCompilerType();
+void ClangASTSource::FillNamespaceMap(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ const CompilerDeclContext &namespace_decl) {
+ const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (IgnoreName(name, true))
+ return;
- CompilerType copied_clang_type(GuardedCopyType(full_type));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!copied_clang_type) {
- LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type",
- current_id);
+ if (module_sp && namespace_decl) {
+ CompilerDeclContext found_namespace_decl;
- continue;
- }
+ if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
+ found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
- context.AddTypeDecl(copied_clang_type);
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
- context.m_found.type = true;
- break;
+ LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,
+ module_sp->GetFileSpec().GetFilename());
}
}
+ return;
+ }
- if (!context.m_found.type) {
- // Try the modules next.
-
- do {
- if (ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor()) {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
- break;
-
- if (log) {
- LLDB_LOGF(log,
- " CAS::FEVD[%u] Matching entity found for \"%s\" in "
- "the modules",
- current_id, name.GetCString());
- }
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
- llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
- llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
- clang::Decl *copied_decl = CopyDecl(decl_from_modules);
- clang::NamedDecl *copied_named_decl =
- copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl) {
- LLDB_LOGF(
- log,
- " CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
-
- context.m_found.type = true;
- }
- }
- } while (false);
- }
-
- if (!context.m_found.type) {
- do {
- // Couldn't find any types elsewhere. Try the Objective-C runtime if
- // one exists.
-
- lldb::ProcessSP process(m_target->GetProcessSP());
-
- if (!process)
- break;
-
- ObjCLanguageRuntime *language_runtime(
- ObjCLanguageRuntime::Get(*process));
-
- if (!language_runtime)
- break;
-
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- if (!decl_vendor)
- break;
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
+ lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
- bool append = false;
- uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
+ if (!image)
+ continue;
- auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
- if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
- break;
+ CompilerDeclContext found_namespace_decl;
- if (log) {
- LLDB_LOGF(
- log,
- " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
- current_id, name.GetCString());
- }
+ SymbolFile *symbol_file = image->GetSymbolFile();
- clang::Decl *copied_decl = CopyDecl(decls[0]);
- clang::NamedDecl *copied_named_decl =
- copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+ if (!symbol_file)
+ continue;
- if (!copied_named_decl) {
- LLDB_LOGF(log,
- " CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
+ found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
- break;
- }
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(image,
+ found_namespace_decl));
- context.AddNamedDecl(copied_named_decl);
- } while (false);
+ LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,
+ image->GetFileSpec().GetFilename());
}
-
- } while (false);
+ }
}
template <class D> class TaggedASTDecl {
@@ -915,8 +759,8 @@ DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
}
bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl, const char *log_info) {
+ NameSearchContext &context, ObjCInterfaceDecl *original_interface_decl,
+ const char *log_info) {
const DeclarationName &decl_name(context.m_decl_name);
clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
@@ -951,7 +795,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
llvm::SmallVector<NamedDecl *, 1> methods;
- ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
+ TypeSystemClang::GetCompleteDecl(original_ctx, original_interface_decl);
if (ObjCMethodDecl *instance_method_decl =
original_interface_decl->lookupInstanceMethod(original_selector)) {
@@ -987,7 +831,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOG(log, " CAS::FOMD[{0}] found ({1}) {2}", current_id, log_info,
+ LLDB_LOG(log, " CAS::FOMD found ({0}) {1}", log_info,
ClangUtil::DumpDecl(copied_method_decl));
context.AddNamedDecl(copied_method_decl);
@@ -996,11 +840,91 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
return true;
}
-void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
+void ClangASTSource::FindDeclInModules(NameSearchContext &context,
+ ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
+ if (!modules_decl_vendor)
+ return;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+ return;
+
+ LLDB_LOG(log, " CAS::FEVD Matching entity found for \"{0}\" in the modules",
+ name);
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
+ llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
+ llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the modules");
+
+ return;
+ }
+
+ context.AddNamedDecl(copied_named_decl);
+
+ context.m_found_type = true;
+ }
+}
+
+void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context,
+ ConstString name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ return;
+
+ ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
+
+ if (!language_runtime)
+ return;
+
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+
+ if (!decl_vendor)
+ return;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
+ return;
+
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\" in the runtime",
+ name);
+
+ clang::Decl *copied_decl = CopyDecl(decls[0]);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the runtime");
+
+ return;
+ }
+
+ context.AddNamedDecl(copied_named_decl);
+}
+
+void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
const DeclarationName &decl_name(context.m_decl_name);
const DeclContext *decl_ctx(context.m_decl_context);
@@ -1020,8 +944,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ObjCInterfaceDecl *original_interface_decl =
dyn_cast<ObjCInterfaceDecl>(original.decl);
- if (FindObjCMethodDeclsWithOrigin(current_id, context,
- original_interface_decl, "at origin"))
+ if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl,
+ "at origin"))
return; // found it, no need to look any further
} while (false);
@@ -1046,12 +970,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString selector_name(ss.GetString());
- LLDB_LOGF(log,
- "ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
- "for selector [%s %s]",
- current_id, static_cast<void *>(m_ast_context),
- interface_decl->getNameAsString().c_str(),
- selector_name.AsCString());
+ LLDB_LOG(log,
+ "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
+ "for selector [{2} {3}]",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ interface_decl->getName(), selector_name);
SymbolContextList sc_list;
const bool include_symbols = false;
@@ -1148,7 +1071,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
continue;
ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
if (!method_decl)
continue;
@@ -1171,7 +1094,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!copied_method_decl)
continue;
- LLDB_LOG(log, " CAS::FOMD[{0}] found (in symbols)\n{1}", current_id,
+ LLDB_LOG(log, " CAS::FOMD found (in symbols)\n{0}",
ClangUtil::DumpDecl(copied_method_decl));
context.AddNamedDecl(copied_method_decl);
@@ -1199,13 +1122,12 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (complete_interface_decl == interface_decl)
break; // already checked this one
- LLDB_LOGF(log,
- "CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<void *>(complete_interface_decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD trying origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ complete_interface_decl, &complete_iface_decl->getASTContext());
- FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
+ FindObjCMethodDeclsWithOrigin(context, complete_interface_decl,
"in debug info");
return;
@@ -1232,8 +1154,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!interface_decl_from_modules)
break;
- if (FindObjCMethodDeclsWithOrigin(
- current_id, context, interface_decl_from_modules, "in modules"))
+ if (FindObjCMethodDeclsWithOrigin(context, interface_decl_from_modules,
+ "in modules"))
return;
}
} while (false);
@@ -1273,13 +1195,13 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!runtime_interface_decl)
break;
- FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
+ FindObjCMethodDeclsWithOrigin(context, runtime_interface_decl,
"in runtime");
} while (false);
}
static bool FindObjCPropertyAndIvarDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context, ClangASTSource &source,
+ NameSearchContext &context, ClangASTSource &source,
DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1301,7 +1223,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
DeclFromParser<ObjCPropertyDecl> parser_property_decl(
origin_property_decl.Import(source));
if (parser_property_decl.IsValid()) {
- LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id,
+ LLDB_LOG(log, " CAS::FOPD found\n{0}",
ClangUtil::DumpDecl(parser_property_decl.decl));
context.AddNamedDecl(parser_property_decl.decl);
@@ -1316,10 +1238,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
origin_ivar_decl.Import(source));
if (parser_ivar_decl.IsValid()) {
- if (log) {
- LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id,
- ClangUtil::DumpDecl(parser_ivar_decl.decl));
- }
+ LLDB_LOG(log, " CAS::FOPD found\n{0}",
+ ClangUtil::DumpDecl(parser_ivar_decl.decl));
context.AddNamedDecl(parser_ivar_decl.decl);
found = true;
@@ -1332,9 +1252,6 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
@@ -1342,23 +1259,20 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- LLDB_LOGF(log,
- "ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
- "(ASTContext*)%p for '%s.%s'",
- current_id, static_cast<void *>(m_ast_context),
- parser_iface_decl->getNameAsString().c_str(),
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOG(log,
+ "ClangASTSource::FindObjCPropertyAndIvarDecls on "
+ "(ASTContext*){0} '{1}' for '{2}.{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ parser_iface_decl->getName(), context.m_decl_name.getAsString());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *this, origin_iface_decl))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, origin_iface_decl))
return;
- LLDB_LOGF(log,
- "CAS::FOPD[%d] couldn't find the property on origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
- "elsewhere...",
- current_id, static_cast<const void *>(origin_iface_decl.decl),
- static_cast<void *>(&origin_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD couldn't find the property on origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching "
+ "elsewhere...",
+ origin_iface_decl.decl, &origin_iface_decl->getASTContext());
SymbolContext null_sc;
TypeList type_list;
@@ -1379,14 +1293,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (complete_iface_decl.decl == origin_iface_decl.decl)
break; // already checked this one
- LLDB_LOGF(log,
- "CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(complete_iface_decl.decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD trying origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ complete_iface_decl.decl, &complete_iface_decl->getASTContext());
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
- complete_iface_decl);
+ FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, complete_iface_decl);
return;
} while (false);
@@ -1414,14 +1326,13 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_modules.IsValid())
break;
- LLDB_LOGF(
- log,
- "CAS::FOPD[%d] trying module "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(interface_decl_from_modules.decl),
- static_cast<void *>(&interface_decl_from_modules->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD[{0}] trying module "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ interface_decl_from_modules.decl,
+ &interface_decl_from_modules->getASTContext());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
interface_decl_from_modules))
return;
} while (false);
@@ -1459,19 +1370,43 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_runtime.IsValid())
break;
- LLDB_LOGF(
- log,
- "CAS::FOPD[%d] trying runtime "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(interface_decl_from_runtime.decl),
- static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD[{0}] trying runtime "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ interface_decl_from_runtime.decl,
+ &interface_decl_from_runtime->getASTContext());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *this, interface_decl_from_runtime))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
+ interface_decl_from_runtime))
return;
} while (false);
}
+void ClangASTSource::LookupInNamespace(NameSearchContext &context) {
+ const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(context.m_decl_context);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
+
+ LLDB_LOGV(log, " CAS::FEVD Inspecting namespace map {0} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
+
+ if (!namespace_map)
+ return;
+
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e; ++i) {
+ LLDB_LOG(log, " CAS::FEVD Searching namespace {0} in module {1}",
+ i->second.GetName(), i->first->GetFileSpec().GetFilename());
+
+ FindExternalVisibleDecls(context, i->first, i->second);
+ }
+}
+
typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
@@ -1557,17 +1492,14 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
FieldOffsetMap &field_offsets,
BaseOffsetMap &base_offsets,
BaseOffsetMap &virtual_base_offsets) {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOGF(log,
- "LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
- "[name = '%s']",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<const void *>(record),
- record->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
+ "{3} [name = '{4}']",
+ m_ast_context, m_clang_ast_context->getDisplayName(), record,
+ record->getName());
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
@@ -1580,7 +1512,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
BaseOffsetMap origin_base_offsets;
BaseOffsetMap origin_virtual_base_offsets;
- ClangASTContext::GetCompleteDecl(
+ TypeSystemClang::GetCompleteDecl(
&origin_record->getASTContext(),
const_cast<RecordDecl *>(origin_record.decl));
@@ -1631,25 +1563,23 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
m_ast_context->getCharWidth();
if (log) {
- LLDB_LOGF(log, "LRT[%u] returned:", current_id);
- LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id,
- static_cast<const void *>(origin_record.decl));
- LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size);
- LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment);
- LLDB_LOGF(log, "LRT[%u] Fields:", current_id);
+ LLDB_LOG(log, "LRT returned:");
+ LLDB_LOG(log, "LRT Original = (RecordDecl*)%p",
+ static_cast<const void *>(origin_record.decl));
+ LLDB_LOG(log, "LRT Size = %" PRId64, size);
+ LLDB_LOG(log, "LRT Alignment = %" PRId64, alignment);
+ LLDB_LOG(log, "LRT Fields:");
for (RecordDecl::field_iterator fi = record->field_begin(),
fe = record->field_end();
fi != fe; ++fi) {
- LLDB_LOGF(log,
- "LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
- " bits",
- current_id, static_cast<void *>(*fi),
- fi->getNameAsString().c_str(), field_offsets[*fi]);
+ LLDB_LOG(log,
+ "LRT (FieldDecl*){0}, Name = '{1}', Offset = {2} bits",
+ *fi, fi->getName(), field_offsets[*fi]);
}
DeclFromParser<const CXXRecordDecl> parser_cxx_record =
DynCast<const CXXRecordDecl>(parser_record);
if (parser_cxx_record.IsValid()) {
- LLDB_LOGF(log, "LRT[%u] Bases:", current_id);
+ LLDB_LOG(log, "LRT Bases:");
for (CXXRecordDecl::base_class_const_iterator
bi = parser_cxx_record->bases_begin(),
be = parser_cxx_record->bases_end();
@@ -1662,19 +1592,17 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
DeclFromParser<CXXRecordDecl> base_cxx_record =
DynCast<CXXRecordDecl>(base_record);
- LLDB_LOGF(
- log,
- "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64
- " chars",
- current_id, (is_virtual ? "Virtual " : ""),
- static_cast<void *>(base_cxx_record.decl),
- base_cxx_record.decl->getNameAsString().c_str(),
- (is_virtual
- ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
- : base_offsets[base_cxx_record.decl].getQuantity()));
+ LLDB_LOG(log,
+ "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
+ "{3} chars",
+ (is_virtual ? "Virtual " : ""), base_cxx_record.decl,
+ base_cxx_record.decl->getName(),
+ (is_virtual
+ ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
+ : base_offsets[base_cxx_record.decl].getQuantity()));
}
} else {
- LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id);
+ LLDB_LOG(log, "LRD Not a CXXRecord, so no bases");
}
}
@@ -1684,25 +1612,21 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
void ClangASTSource::CompleteNamespaceMap(
ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
ClangASTImporter::NamespaceMapSP &parent_map) const {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
if (parent_map && parent_map->size())
- LLDB_LOGF(log,
- "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s in namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- parent_map->begin()->second.GetName().AsCString());
+ LLDB_LOG(log,
+ "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
+ "for namespace {2} in namespace {3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ parent_map->begin()->second.GetName());
else
- LLDB_LOGF(log,
- "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOG(log,
+ "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
+ "for namespace {2}",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name);
}
if (parent_map) {
@@ -1720,7 +1644,7 @@ void ClangASTSource::CompleteNamespaceMap(
continue;
found_namespace_decl =
- symbol_file->FindNamespace(name, &module_parent_namespace_decl);
+ symbol_file->FindNamespace(name, module_parent_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1728,9 +1652,8 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOG(log, " CMN Found namespace {0} in module {1}", name,
+ module_sp->GetFileSpec().GetFilename());
}
} else {
const ModuleList &target_images = m_target->GetImages();
@@ -1752,7 +1675,7 @@ void ClangASTSource::CompleteNamespaceMap(
continue;
found_namespace_decl =
- symbol_file->FindNamespace(name, &null_namespace_decl);
+ symbol_file->FindNamespace(name, null_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1760,9 +1683,8 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOG(log, " CMN[{0}] Found namespace {0} in module {1}", name,
+ image->GetFileSpec().GetFilename());
}
}
}
@@ -1776,11 +1698,11 @@ NamespaceDecl *ClangASTSource::AddNamespace(
const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
clang::ASTContext *src_ast =
- ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
+ TypeSystemClang::DeclContextGetTypeSystemClang(namespace_decl);
if (!src_ast)
return nullptr;
clang::NamespaceDecl *src_namespace_decl =
- ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
+ TypeSystemClang::DeclContextGetAsNamespaceDecl(namespace_decl);
if (!src_namespace_decl)
return nullptr;
@@ -1804,42 +1726,21 @@ NamespaceDecl *ClangASTSource::AddNamespace(
}
clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
- if (m_ast_importer_sp) {
- return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
- } else {
- lldbassert(0 && "No mechanism for copying a decl!");
- return nullptr;
- }
+ return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
}
ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) {
- if (m_ast_importer_sp) {
- return m_ast_importer_sp->GetDeclOrigin(decl);
- } else {
- // this can happen early enough that no ExternalASTSource is installed.
- return ClangASTImporter::DeclOrigin();
- }
+ return m_ast_importer_sp->GetDeclOrigin(decl);
}
CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
- ClangASTContext *src_ast =
- llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+ TypeSystemClang *src_ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
if (src_ast == nullptr)
return CompilerType();
- SetImportInProgress(true);
-
- QualType copied_qual_type;
-
- if (m_ast_importer_sp) {
- copied_qual_type = ClangUtil::GetQualType(
- m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
- } else {
- lldbassert(0 && "No mechanism for copying a type!");
- return CompilerType();
- }
-
- SetImportInProgress(false);
+ QualType copied_qual_type = ClangUtil::GetQualType(
+ m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
if (copied_qual_type.getAsOpaquePtr() &&
copied_qual_type->getCanonicalTypeInternal().isNull())
@@ -1849,170 +1750,3 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
return m_clang_ast_context->GetType(copied_qual_type);
}
-
-clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
- assert(type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return nullptr;
-
- ClangASTContext *lldb_ast =
- llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return nullptr;
-
- IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
-
- clang::ASTContext &ast = lldb_ast->getASTContext();
-
- clang::NamedDecl *Decl = VarDecl::Create(
- ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
- SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
- m_decls.push_back(Decl);
-
- return Decl;
-}
-
-clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
- bool extern_c) {
- assert(type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return nullptr;
-
- if (m_function_types.count(type))
- return nullptr;
-
- ClangASTContext *lldb_ast =
- llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return nullptr;
-
- m_function_types.insert(type);
-
- QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::ASTContext &ast = lldb_ast->getASTContext();
-
- const bool isInlineSpecified = false;
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
-
- clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
-
- if (extern_c) {
- context = LinkageSpecDecl::Create(
- ast, context, SourceLocation(), SourceLocation(),
- clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
- }
-
- // Pass the identifier info for functions the decl_name is needed for
- // operators
- clang::DeclarationName decl_name =
- m_decl_name.getNameKind() == DeclarationName::Identifier
- ? m_decl_name.getAsIdentifierInfo()
- : m_decl_name;
-
- clang::FunctionDecl *func_decl = FunctionDecl::Create(
- ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
- nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
- isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
-
- // We have to do more than just synthesize the FunctionDecl. We have to
- // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
- // this, we raid the function's FunctionProtoType for types.
-
- const FunctionProtoType *func_proto_type =
- qual_type.getTypePtr()->getAs<FunctionProtoType>();
-
- if (func_proto_type) {
- unsigned NumArgs = func_proto_type->getNumParams();
- unsigned ArgIndex;
-
- SmallVector<ParmVarDecl *, 5> parm_var_decls;
-
- for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
- QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
-
- parm_var_decls.push_back(
- ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
- SourceLocation(), SourceLocation(), nullptr,
- arg_qual_type, nullptr, SC_Static, nullptr));
- }
-
- func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
- } else {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- LLDB_LOGF(log, "Function type wasn't a FunctionProtoType");
- }
-
- // If this is an operator (e.g. operator new or operator==), only insert the
- // declaration we inferred from the symbol if we can provide the correct
- // number of arguments. We shouldn't really inject random decl(s) for
- // functions that are analyzed semantically in a special way, otherwise we
- // will crash in clang.
- clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
- if (func_proto_type &&
- ClangASTContext::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
- if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
- false, op_kind, func_proto_type->getNumParams()))
- return nullptr;
- }
- m_decls.push_back(func_decl);
-
- return func_decl;
-}
-
-clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
- FunctionProtoType::ExtProtoInfo proto_info;
-
- proto_info.Variadic = true;
-
- QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType(
- m_ast_source.m_ast_context->UnknownAnyTy, // result
- ArrayRef<QualType>(), // argument types
- proto_info));
-
- return AddFunDecl(
- m_ast_source.m_clang_ast_context->GetType(generic_function_type), true);
-}
-
-clang::NamedDecl *
-NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
- if (ClangUtil::IsClangType(clang_type)) {
- QualType qual_type = ClangUtil::GetQualType(clang_type);
-
- if (const TypedefType *typedef_type =
- llvm::dyn_cast<TypedefType>(qual_type)) {
- TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
-
- m_decls.push_back(typedef_name_decl);
-
- return (NamedDecl *)typedef_name_decl;
- } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
- TagDecl *tag_decl = tag_type->getDecl();
-
- m_decls.push_back(tag_decl);
-
- return tag_decl;
- } else if (const ObjCObjectType *objc_object_type =
- qual_type->getAs<ObjCObjectType>()) {
- ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
-
- m_decls.push_back((NamedDecl *)interface_decl);
-
- return (NamedDecl *)interface_decl;
- }
- }
- return nullptr;
-}
-
-void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
- for (clang::NamedDecl *decl : result)
- m_decls.push_back(decl);
-}
-
-void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
- m_decls.push_back(decl);
-}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 3149b4266b2f..14761fbeb26b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangASTSource_h_
-#define liblldb_ClangASTSource_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
#include <set>
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "clang/AST/ExternalASTSource.h"
@@ -42,7 +43,7 @@ public:
/// \param[in] importer
/// The ClangASTImporter to use.
ClangASTSource(const lldb::TargetSP &target,
- const lldb::ClangASTImporterSP &importer);
+ const std::shared_ptr<ClangASTImporter> &importer);
/// Destructor
~ClangASTSource() override;
@@ -60,7 +61,7 @@ public:
}
void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
- void InstallASTContext(ClangASTContext &ast_context);
+ void InstallASTContext(TypeSystemClang &ast_context);
//
// APIs for ExternalASTSource
@@ -196,11 +197,6 @@ public:
clang::Sema *getSema();
- void SetImportInProgress(bool import_in_progress) {
- m_import_in_progress = import_in_progress;
- }
- bool GetImportInProgress() { return m_import_in_progress; }
-
void SetLookupsEnabled(bool lookups_enabled) {
m_lookups_enabled = lookups_enabled;
}
@@ -282,14 +278,9 @@ protected:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void FindExternalVisibleDecls(NameSearchContext &context,
lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
+ CompilerDeclContext &namespace_decl);
/// Find all Objective-C methods matching a given selector.
///
@@ -307,7 +298,13 @@ protected:
/// is the containing object.
void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
- /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// Performs lookup into a namespace.
+ ///
+ /// \param context
+ /// The NameSearchContext for a lookup inside a namespace.
+ void LookupInNamespace(NameSearchContext &context);
+
+ /// A wrapper for TypeSystemClang::CopyType that sets a flag that
/// indicates that we should not respond to queries during import.
///
/// \param[in] src_type
@@ -331,7 +328,6 @@ public:
/// global lookup for performance reasons.
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
-public:
/// Copies a single Decl into the parser's AST context.
///
/// \param[in] src_decl
@@ -346,139 +342,51 @@ public:
/// \param[in] decl
/// The Decl whose origin is to be found.
///
- /// \param[out] original_decl
- /// A pointer whose target is filled in with the original Decl.
- ///
- /// \param[in] original_ctx
- /// A pointer whose target is filled in with the original's ASTContext.
- ///
/// \return
/// True if lookup succeeded; false otherwise.
ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
+ /// Returns the TypeSystem that uses this ClangASTSource instance as it's
+ /// ExternalASTSource.
+ TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }
+
protected:
bool FindObjCMethodDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
+ NameSearchContext &context,
clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+ void FindDeclInModules(NameSearchContext &context, ConstString name);
+ void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);
+
+ /// Fills the namespace map of the given NameSearchContext.
+ ///
+ /// \param context The NameSearchContext with the namespace map to fill.
+ /// \param module_sp The module to search for namespaces or a nullptr if
+ /// the current target should be searched.
+ /// \param namespace_decl The DeclContext in which to search for namespaces.
+ void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
+ const CompilerDeclContext &namespace_decl);
+
+ clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
+
friend struct NameSearchContext;
- bool m_import_in_progress;
bool m_lookups_enabled;
/// The target to use in finding variables and types.
const lldb::TargetSP m_target;
/// The AST context requests are coming in for.
clang::ASTContext *m_ast_context;
- /// The ClangASTContext for m_ast_context.
- ClangASTContext *m_clang_ast_context;
+ /// The TypeSystemClang for m_ast_context.
+ TypeSystemClang *m_clang_ast_context;
/// The file manager paired with the AST context.
clang::FileManager *m_file_manager;
/// The target's AST importer.
- lldb::ClangASTImporterSP m_ast_importer_sp;
+ std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};
-/// \class NameSearchContext ClangASTSource.h
-/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
-/// single name lookup
-///
-/// LLDB needs to create Decls for entities it finds. This class communicates
-/// what name is being searched for and provides helper functions to construct
-/// Decls given appropriate type information.
-struct NameSearchContext {
- /// The AST source making the request.
- ClangASTSource &m_ast_source;
- /// The list of declarations already constructed.
- llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
- /// The mapping of all namespaces found for this request back to their
- /// modules.
- ClangASTImporter::NamespaceMapSP m_namespace_map;
- /// The name being looked for.
- const clang::DeclarationName &m_decl_name;
- /// The DeclContext to put declarations into.
- const clang::DeclContext *m_decl_context;
- /// All the types of functions that have been reported, so we don't
- /// report conflicts.
- llvm::SmallSet<CompilerType, 5> m_function_types;
-
- struct {
- bool variable : 1;
- bool function_with_type_info : 1;
- bool function : 1;
- bool local_vars_nsp : 1;
- bool type : 1;
- } m_found;
-
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// \param[in] astSource
- /// A reference to the AST source making a request.
- ///
- /// \param[in] decls
- /// A reference to a list into which new Decls will be placed. This
- /// list is typically empty when the function is called.
- ///
- /// \param[in] name
- /// The name being searched for (always an Identifier).
- ///
- /// \param[in] dc
- /// The DeclContext to register Decls in.
- NameSearchContext(ClangASTSource &astSource,
- llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
- clang::DeclarationName &name, const clang::DeclContext *dc)
- : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
- m_decl_context(dc) {
- memset(&m_found, 0, sizeof(m_found));
- }
-
- /// Create a VarDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] type
- /// The opaque QualType for the VarDecl being registered.
- clang::NamedDecl *AddVarDecl(const CompilerType &type);
-
- /// Create a FunDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] type
- /// The opaque QualType for the FunDecl being registered.
- ///
- /// \param[in] extern_c
- /// If true, build an extern "C" linkage specification for this.
- clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
-
- /// Create a FunDecl with the name being searched for and generic type (i.e.
- /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
- clang::NamedDecl *AddGenericFunDecl();
-
- /// Create a TypeDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] compiler_type
- /// The opaque QualType for the TypeDecl being registered.
- clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
-
- /// Add Decls from the provided DeclContextLookupResult to the list of
- /// results.
- ///
- /// \param[in] result
- /// The DeclContextLookupResult, usually returned as the result
- /// of querying a DeclContext.
- void AddLookupResult(clang::DeclContextLookupResult result);
-
- /// Add a NamedDecl to the list of results.
- ///
- /// \param[in] decl
- /// The NamedDecl, usually returned as the result
- /// of querying a DeclContext.
- void AddNamedDecl(clang::NamedDecl *decl);
-};
-
} // namespace lldb_private
-#endif // liblldb_ClangASTSource_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
index c87507a25855..867d4ff0a907 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
@@ -1,4 +1,4 @@
-//===-- ClangDeclVendor.cpp -------------------------------------*- C++ -*-===//
+//===-- ClangDeclVendor.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,9 @@
//===----------------------------------------------------------------------===//
#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Utility/ConstString.h"
using namespace lldb_private;
@@ -22,7 +23,7 @@ uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append,
std::vector<CompilerDecl> compiler_decls;
uint32_t ret = FindDecls(name, /*append*/ false, max_matches, compiler_decls);
for (CompilerDecl compiler_decl : compiler_decls) {
- clang::Decl *d = static_cast<clang::Decl *>(compiler_decl.GetOpaqueDecl());
+ clang::Decl *d = ClangUtil::GetDecl(compiler_decl);
clang::NamedDecl *nd = llvm::cast<clang::NamedDecl>(d);
decls.push_back(nd);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
index 0c888de08841..bf52bec4b1fa 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangDeclVendor_h_
-#define liblldb_ClangDeclVendor_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/DeclVendor.h"
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
// A clang specialized extension to DeclVendor.
@@ -32,7 +35,8 @@ public:
}
private:
- DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor);
+ ClangDeclVendor(const ClangDeclVendor &) = delete;
+ const ClangDeclVendor &operator=(const ClangDeclVendor &) = delete;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index 48cd1c4b99fa..7459b715dbe2 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ClangDiagnostic_h
-#define lldb_ClangDiagnostic_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
#include <vector>
@@ -47,4 +47,4 @@ private:
};
} // namespace lldb_private
-#endif /* lldb_ClangDiagnostic_h */
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index bf3023be5f60..8c49898e1d6c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
+//===-- ClangExpressionDeclMap.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,15 +11,15 @@
#include "ClangASTSource.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
+#include "ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
@@ -65,8 +65,8 @@ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
ClangExpressionDeclMap::ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
- const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer,
- ValueObject *ctx_obj)
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
: ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
m_keep_result_in_memory(keep_result_in_memory),
m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
@@ -109,7 +109,7 @@ bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
- if (!ClangASTContext::GetScratch(*target))
+ if (!TypeSystemClang::GetScratch(*target))
return false;
}
@@ -174,19 +174,14 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
return ret;
}
-TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
- ClangASTContext &source,
+TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
+ TypeSystemClang &source,
TypeFromParser parser_type) {
- assert(&target == ClangASTContext::GetScratch(*m_target));
+ assert(&target == TypeSystemClang::GetScratch(*m_target));
assert((TypeSystem *)&source == parser_type.GetTypeSystem());
assert(&source.getASTContext() == m_ast_context);
- if (m_ast_importer_sp) {
- return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
- } else {
- lldbassert(0 && "No mechanism for deporting a type!");
- return TypeFromUser();
- }
+ return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
}
bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
@@ -196,8 +191,8 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
bool is_lvalue) {
assert(m_parser_vars.get());
- ClangASTContext *ast =
- llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(parser_type.GetTypeSystem());
if (ast == nullptr)
return false;
@@ -209,7 +204,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- auto *clang_ast_context = ClangASTContext::GetScratch(*target);
+ auto *clang_ast_context = TypeSystemClang::GetScratch(*target);
if (!clang_ast_context)
return false;
@@ -231,7 +226,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
var->EnableJITVars(GetParserID());
@@ -248,14 +242,14 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- ClangASTContext *context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *context = TypeSystemClang::GetScratch(*target);
if (!context)
return false;
TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
- LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully");
+ LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");
return false;
}
@@ -297,7 +291,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
- LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags);
+ LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);
var->EnableParserVars(GetParserID());
@@ -305,7 +299,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
return true;
}
@@ -339,9 +332,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!var)
return false;
- LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void *>(decl), name.GetCString(),
- var->GetName().GetCString());
+ LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ decl, name, var->GetName());
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
@@ -355,8 +347,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
// We already laid this out; do not touch
- LLDB_LOGF(log, "Already placed at 0x%llx",
- (unsigned long long)jit_vars->m_offset);
+ LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);
}
llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
@@ -391,7 +382,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!err.Success())
return false;
- LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset);
+ LLDB_LOG(log, "Placed at {0:x}", offset);
jit_vars->m_offset =
offset; // TODO DoStructLayout() should not change this.
@@ -600,7 +591,7 @@ addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
Target &target, ModuleSP &module, ConstString name,
- CompilerDeclContext *namespace_decl) {
+ const CompilerDeclContext &namespace_decl) {
VariableList vars;
if (module && namespace_decl)
@@ -613,7 +604,7 @@ lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
return vars.GetVariableAtIndex(0);
}
-ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
+TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
if (frame == nullptr)
return nullptr;
@@ -627,7 +618,7 @@ ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
if (!frame_decl_context)
return nullptr;
- return llvm::dyn_cast_or_null<ClangASTContext>(
+ return llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
}
@@ -641,34 +632,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (GetImportInProgress()) {
- if (log && log->GetVerbose())
- LLDB_LOGF(log, "Ignoring a query during an import");
- return;
- }
-
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (!context.m_decl_context)
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a NULL DeclContext",
- current_id, name.GetCString());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in a NULL DeclContext",
+ name);
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in '%s'",
- current_id, name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in '{1}'",
+ name, context_named_decl->getNameAsString());
else
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a '%s'",
- current_id, name.GetCString(),
- context.m_decl_context->getDeclKindName());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in a '{1}'",
+ name, context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context =
@@ -678,42 +658,31 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
CompilerDeclContext compiler_decl_ctx =
m_clang_ast_context->CreateDeclContext(
const_cast<clang::DeclContext *>(context.m_decl_context));
- FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
return;
}
ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp
- ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
- : ClangASTImporter::NamespaceMapSP();
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (!namespace_map)
return;
- if (log && log->GetVerbose())
- log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- (int)namespace_map->size());
+ LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e; ++i) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {
+ LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",
+ n.second.GetName(), n.first->GetFileSpec().GetFilename());
- FindExternalVisibleDecls(context, i->first, i->second, current_id);
+ FindExternalVisibleDecls(context, n.first, n.second);
}
} else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
CompilerDeclContext namespace_decl;
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");
- FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
}
ClangASTSource::FindExternalVisibleDecls(context);
@@ -734,7 +703,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
if (!target)
return nullptr;
- ClangASTContext::GetScratch(*target);
+ TypeSystemClang::GetScratch(*target);
if (!m_parser_vars->m_persistent_vars)
return nullptr;
@@ -742,8 +711,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
}
void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
- const ConstString name,
- unsigned int current_id) {
+ const ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
NamedDecl *persistent_decl = GetPersistentDecl(name);
@@ -766,14 +734,12 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
MaybeRegisterFunctionBody(parser_function_decl);
}
- LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id,
- name.GetCString());
+ LLDB_LOG(log, " CEDM::FEVD Found persistent decl %s", name);
context.AddNamedDecl(parser_named_decl);
}
-void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
- unsigned int current_id) {
+void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
@@ -788,8 +754,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
if (!ctx_obj_ptr || status.Fail())
return;
- AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
- current_id);
+ AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -814,7 +779,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
return;
clang::CXXMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
if (method_decl) {
clang::CXXRecordDecl *class_decl = method_decl->getParent();
@@ -824,10 +789,10 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(),
function_decl_ctx.GetTypeSystem());
- LLDB_LOG(log, " CEDM::FEVD[{0}] Adding type for $__lldb_class: {1}",
- current_id, class_qual_type.getAsString());
+ LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {1}",
+ class_qual_type.getAsString());
- AddThisType(context, class_user_type, current_id);
+ AddContextClassType(context, class_user_type);
if (method_decl->isInstance()) {
// self is a pointer to the object
@@ -866,17 +831,16 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
TypeFromUser pointee_type =
this_type->GetForwardCompilerType().GetPointeeType();
- LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_class: {1}", current_id,
+ LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {1}",
ClangUtil::GetQualType(pointee_type).getAsString());
- AddThisType(context, pointee_type, current_id);
+ AddContextClassType(context, pointee_type);
TypeFromUser this_user_type(this_type->GetFullCompilerType());
m_struct_vars->m_object_pointer_type = this_user_type;
}
}
-void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
- unsigned int current_id) {
+void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
@@ -887,7 +851,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
if (!ctx_obj_ptr || status.Fail())
return;
- AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), current_id);
+ AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -915,7 +879,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
return;
clang::ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
if (method_decl) {
ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
@@ -933,9 +897,9 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
function_decl_ctx.GetTypeSystem());
LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
- current_id, ClangUtil::ToString(interface_type));
+ ClangUtil::ToString(interface_type));
- AddOneType(context, class_user_type, current_id);
+ AddOneType(context, class_user_type);
if (method_decl->isInstanceMethod()) {
// self is a pointer to the object
@@ -984,10 +948,10 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
CompilerType self_clang_type = self_type->GetFullCompilerType();
- if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
return;
}
- if (!ClangASTContext::IsObjCObjectPointerType(self_clang_type))
+ if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))
return;
self_clang_type = self_clang_type.GetPointeeType();
@@ -995,11 +959,11 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
return;
LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
- current_id, ClangUtil::ToString(self_type->GetFullCompilerType()));
+ ClangUtil::ToString(self_type->GetFullCompilerType()));
TypeFromUser class_user_type(self_clang_type);
- AddOneType(context, class_user_type, current_id);
+ AddOneType(context, class_user_type);
TypeFromUser self_user_type(self_type->GetFullCompilerType());
@@ -1015,25 +979,25 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace(
if (!frame_decl_context)
return;
- ClangASTContext *frame_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
if (!frame_ast)
return;
clang::NamespaceDecl *namespace_decl =
m_clang_ast_context->GetUniqueNamespaceDeclaration(
- g_lldb_local_vars_namespace_cstr, nullptr);
+ g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
if (!namespace_decl)
return;
name_context.AddNamedDecl(namespace_decl);
clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);
ctxt->setHasExternalVisibleStorage(true);
- name_context.m_found.local_vars_nsp = true;
+ name_context.m_found_local_vars_nsp = true;
}
void ClangExpressionDeclMap::LookupInModulesDeclVendor(
- NameSearchContext &context, ConstString name, unsigned current_id) {
+ NameSearchContext &context, ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (!m_target)
@@ -1054,16 +1018,14 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
clang::NamedDecl *const decl_from_modules = decls[0];
LLDB_LOG(log,
- " CAS::FEVD[{0}] Matching decl found for "
+ " CAS::FEVD Matching decl found for "
"\"{1}\" in the modules",
- current_id, name);
+ name);
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
if (!copied_decl) {
- LLDB_LOG(log,
- " CAS::FEVD[{0}] - Couldn't export a "
- "declaration from the modules",
- current_id);
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a "
+ "declaration from the modules");
return;
}
@@ -1072,17 +1034,17 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
context.AddNamedDecl(copied_function);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
+ context.m_found_function_with_type_info = true;
+ context.m_found_function = true;
} else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
context.AddNamedDecl(copied_var);
- context.m_found.variable = true;
+ context.m_found_variable = true;
}
}
bool ClangExpressionDeclMap::LookupLocalVariable(
- NameSearchContext &context, ConstString name, unsigned current_id,
- SymbolContext &sym_ctx, CompilerDeclContext &namespace_decl) {
+ NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,
+ const CompilerDeclContext &namespace_decl) {
if (sym_ctx.block == nullptr)
return false;
@@ -1117,8 +1079,8 @@ bool ClangExpressionDeclMap::LookupLocalVariable(
if (var && !variable_found) {
variable_found = true;
ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
+ AddOneVariable(context, var, valobj);
+ context.m_found_variable = true;
}
}
return variable_found;
@@ -1148,7 +1110,7 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
decl_infos.reserve(num_indices);
clang::DeclContext *frame_decl_ctx =
(clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
for (uint32_t index = 0; index < num_indices; ++index) {
@@ -1222,11 +1184,9 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
return sc_func_list;
}
-void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
- lldb::ModuleSP module_sp,
- ConstString name,
- CompilerDeclContext &namespace_decl,
- unsigned current_id) {
+void ClangExpressionDeclMap::LookupFunction(
+ NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,
+ const CompilerDeclContext &namespace_decl) {
if (!m_parser_vars)
return;
@@ -1246,7 +1206,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
if (namespace_decl && module_sp) {
const bool include_symbols = false;
- module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
+ module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
include_symbols, include_inlines, sc_list);
} else if (target && !namespace_decl) {
const bool include_symbols = true;
@@ -1304,9 +1264,9 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
continue;
- AddOneFunction(context, sym_ctx.function, nullptr, current_id);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
+ AddOneFunction(context, sym_ctx.function, nullptr);
+ context.m_found_function_with_type_info = true;
+ context.m_found_function = true;
} else if (sym_ctx.symbol) {
if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
@@ -1321,26 +1281,26 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
}
}
- if (!context.m_found.function_with_type_info) {
+ if (!context.m_found_function_with_type_info) {
for (clang::NamedDecl *decl : decls_from_modules) {
if (llvm::isa<clang::FunctionDecl>(decl)) {
clang::NamedDecl *copied_decl =
llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
if (copied_decl) {
context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
+ context.m_found_function_with_type_info = true;
}
}
}
}
- if (!context.m_found.function_with_type_info) {
+ if (!context.m_found_function_with_type_info) {
if (extern_symbol) {
- AddOneFunction(context, nullptr, extern_symbol, current_id);
- context.m_found.function = true;
+ AddOneFunction(context, nullptr, extern_symbol);
+ context.m_found_function = true;
} else if (non_extern_symbol) {
- AddOneFunction(context, nullptr, non_extern_symbol, current_id);
- context.m_found.function = true;
+ AddOneFunction(context, nullptr, non_extern_symbol);
+ context.m_found_function = true;
}
}
}
@@ -1348,7 +1308,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
void ClangExpressionDeclMap::FindExternalVisibleDecls(
NameSearchContext &context, lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ const CompilerDeclContext &namespace_decl) {
assert(m_ast_context);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1373,16 +1333,16 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
// Try the persistent decls, which take precedence over all else.
if (!namespace_decl)
- SearchPersistenDecls(context, name, current_id);
+ SearchPersistenDecls(context, name);
if (name.GetStringRef().startswith("$") && !namespace_decl) {
if (name == "$__lldb_class") {
- LookUpLldbClass(context, current_id);
+ LookUpLldbClass(context);
return;
}
if (name == "$__lldb_objc_class") {
- LookUpLldbObjCClass(context, current_id);
+ LookUpLldbObjCClass(context);
return;
}
if (name == g_lldb_local_vars_namespace_cstr) {
@@ -1402,7 +1362,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
m_parser_vars->m_persistent_vars->GetVariable(name));
if (pvar_sp) {
- AddOneVariable(context, pvar_sp, current_id);
+ AddOneVariable(context, pvar_sp);
return;
}
@@ -1415,10 +1375,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
reg_name));
if (reg_info) {
- LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id,
- reg_info->name);
+ LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);
- AddOneRegister(context, reg_info, current_id);
+ AddOneRegister(context, reg_info);
}
}
return;
@@ -1427,29 +1386,29 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==
g_lldb_local_vars_namespace_cstr);
if (frame && local_var_lookup)
- if (LookupLocalVariable(context, name, current_id, sym_ctx, namespace_decl))
+ if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))
return;
if (target) {
ValueObjectSP valobj;
VariableSP var;
- var = FindGlobalVariable(*target, module_sp, name, &namespace_decl);
+ var = FindGlobalVariable(*target, module_sp, name, namespace_decl);
if (var) {
valobj = ValueObjectVariable::Create(target, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
+ AddOneVariable(context, var, valobj);
+ context.m_found_variable = true;
return;
}
}
- LookupFunction(context, module_sp, name, namespace_decl, current_id);
+ LookupFunction(context, module_sp, name, namespace_decl);
// Try the modules next.
- if (!context.m_found.function_with_type_info)
- LookupInModulesDeclVendor(context, name, current_id);
+ if (!context.m_found_function_with_type_info)
+ LookupInModulesDeclVendor(context, name);
- if (target && !context.m_found.variable && !namespace_decl) {
+ if (target && !context.m_found_variable && !namespace_decl) {
// We couldn't find a non-symbol variable for this. Now we'll hunt for a
// generic data symbol, and -- if it is found -- treat it as a variable.
Status error;
@@ -1471,8 +1430,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
m_ast_context->getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Level::Warning, "%0");
m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
- AddOneGenericVariable(context, *data_symbol, current_id);
- context.m_found.variable = true;
+ AddOneGenericVariable(context, *data_symbol);
+ context.m_found_variable = true;
}
}
}
@@ -1486,25 +1445,22 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
Type *var_type = var->GetType();
if (!var_type) {
- if (log)
- log->PutCString("Skipped a definition because it has no type");
+ LLDB_LOG(log, "Skipped a definition because it has no type");
return false;
}
CompilerType var_clang_type = var_type->GetFullCompilerType();
if (!var_clang_type) {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang type");
+ LLDB_LOG(log, "Skipped a definition because it has no Clang type");
return false;
}
- ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *clang_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
var_type->GetForwardCompilerType().GetTypeSystem());
if (!clang_ast) {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang AST");
+ LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
return false;
}
@@ -1521,7 +1477,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
const_value_extractor.GetByteSize());
var_location.SetValueType(Value::eValueTypeHostAddress);
} else {
- LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString());
+ LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
return false;
}
}
@@ -1529,8 +1485,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
CompilerType type_to_use = GuardedCopyType(var_clang_type);
if (!type_to_use) {
- LLDB_LOGF(log,
- "Couldn't copy a variable's type into the parser's AST context");
+ LLDB_LOG(log,
+ "Couldn't copy a variable's type into the parser's AST context");
return false;
}
@@ -1567,8 +1523,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
VariableSP var,
- ValueObjectSP valobj,
- unsigned int current_id) {
+ ValueObjectSP valobj) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1611,7 +1566,6 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars =
entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = pt;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value = var_location;
@@ -1620,15 +1574,12 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (is_reference)
entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
- LLDB_LOG(log,
- " CEDM::FEVD[{0}] Found variable {1}, returned\n{2} (original {3})",
- current_id, decl_name, ClangUtil::DumpDecl(var_decl),
- ClangUtil::ToString(ut));
+ LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2} (original {3})",
+ decl_name, ClangUtil::DumpDecl(var_decl), ClangUtil::ToString(ut));
}
void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
- ExpressionVariableSP &pvar_sp,
- unsigned int current_id) {
+ ExpressionVariableSP &pvar_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
TypeFromUser user_type(
@@ -1637,8 +1588,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
TypeFromParser parser_type(GuardedCopyType(user_type));
if (!parser_type.GetOpaqueQualType()) {
- LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s",
- current_id, pvar_sp->GetName().GetCString());
+ LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",
+ pvar_sp->GetName());
return;
}
@@ -1650,18 +1601,16 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
ClangExpressionVariable::ParserVars *parser_vars =
llvm::cast<ClangExpressionVariable>(pvar_sp.get())
->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value.Clear();
- LLDB_LOG(log, " CEDM::FEVD[{0}] Added pvar {1}, returned\n{2}", current_id,
+ LLDB_LOG(log, " CEDM::FEVD Added pvar {1}, returned\n{2}",
pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id) {
+ const Symbol &symbol) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1671,7 +1620,7 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
if (target == nullptr)
return;
- ClangASTContext *scratch_ast_context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *scratch_ast_context = TypeSystemClang::GetScratch(*target);
if (!scratch_ast_context)
return;
@@ -1704,18 +1653,16 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
- parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_sym = &symbol;
- LLDB_LOG(log, " CEDM::FEVD[{0}] Found variable {1}, returned\n{2}",
- current_id, decl_name, ClangUtil::DumpDecl(var_decl));
+ LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2}", decl_name,
+ ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id) {
+ const RegisterInfo *reg_info) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
CompilerType clang_type =
@@ -1723,8 +1670,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
reg_info->encoding, reg_info->byte_size * 8);
if (!clang_type) {
- LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one",
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",
+ context.m_decl_name.getAsString());
return;
}
@@ -1744,20 +1691,18 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars =
entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_clang_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value.Clear();
entity->m_flags |= ClangExpressionVariable::EVBareRegister;
- LLDB_LOG(log, " CEDM::FEVD[{0}] Added register {1}, returned\n{2}",
- current_id, context.m_decl_name.getAsString(),
- ClangUtil::DumpDecl(var_decl));
+ LLDB_LOG(log, " CEDM::FEVD Added register {1}, returned\n{2}",
+ context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
- Function *function, Symbol *symbol,
- unsigned int current_id) {
+ Function *function,
+ Symbol *symbol) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1780,7 +1725,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (!extern_c) {
TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
- if (llvm::isa<ClangASTContext>(type_system)) {
+ if (llvm::isa<TypeSystemClang>(type_system)) {
clang::DeclContext *src_decl_context =
(clang::DeclContext *)function->GetDeclContext()
.GetOpaqueDeclContext();
@@ -1800,9 +1745,9 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
LLDB_LOG(log,
- " CEDM::FEVD[{0}] Imported decl for function template"
+ " CEDM::FEVD Imported decl for function template"
" {1} (description {2}), returned\n{3}",
- current_id, copied_function_template->getNameAsString(),
+ copied_function_template->getNameAsString(),
ss.GetData(),
ClangUtil::DumpDecl(copied_function_template));
}
@@ -1819,35 +1764,31 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
LLDB_LOG(log,
- " CEDM::FEVD[{0}]] Imported decl for function {1} "
+ " CEDM::FEVD Imported decl for function {1} "
"(description {2}), returned\n{3}",
- current_id, copied_function_decl->getNameAsString(),
- ss.GetData(), ClangUtil::DumpDecl(copied_function_decl));
+ copied_function_decl->getNameAsString(), ss.GetData(),
+ ClangUtil::DumpDecl(copied_function_decl));
}
context.AddNamedDecl(copied_function_decl);
return;
} else {
- if (log) {
- LLDB_LOGF(log, " Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
- }
+ LLDB_LOG(log, " Failed to import the function decl for '{0}'",
+ src_function_decl->getName());
}
}
}
}
if (!function_type) {
- if (log)
- log->PutCString(" Skipped a function because it has no type");
+ LLDB_LOG(log, " Skipped a function because it has no type");
return;
}
function_clang_type = function_type->GetFullCompilerType();
if (!function_clang_type) {
- if (log)
- log->PutCString(" Skipped a function because it has no Clang type");
+ LLDB_LOG(log, " Skipped a function because it has no Clang type");
return;
}
@@ -1858,24 +1799,17 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function_decl = context.AddFunDecl(copied_function_type, extern_c);
if (!function_decl) {
- if (log) {
- LLDB_LOGF(
- log,
- " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
- function_type->GetName().GetCString(), function_type->GetID());
- }
+ LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",
+ function_type->GetName(), function_type->GetID());
return;
}
} else {
// We failed to copy the type we found
- if (log) {
- LLDB_LOGF(log,
- " Failed to import the function type '%s' {0x%8.8" PRIx64
- "} into the expression parser AST contenxt",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
+ LLDB_LOG(log,
+ " Failed to import the function type '{0}' ({1:x})"
+ " into the expression parser AST contenxt",
+ function_type->GetName(), function_type->GetID());
return;
}
@@ -1884,8 +1818,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function_decl = context.AddGenericFunDecl();
is_indirect_function = symbol->IsIndirect();
} else {
- if (log)
- log->PutCString(" AddOneFunction called with no function and no symbol");
+ LLDB_LOG(log, " AddOneFunction called with no function and no symbol");
return;
}
@@ -1931,25 +1864,22 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Address::DumpStyleResolvedDescription);
LLDB_LOG(log,
- " CEDM::FEVD[{0}] Found {1} function {2} (description {3}), "
+ " CEDM::FEVD Found {1} function {2} (description {3}), "
"returned\n{4}",
- current_id, (function ? "specific" : "generic"), decl_name,
- ss.GetData(), ClangUtil::DumpDecl(function_decl));
+ (function ? "specific" : "generic"), decl_name, ss.GetData(),
+ ClangUtil::DumpDecl(function_decl));
}
}
-void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
- const TypeFromUser &ut,
- unsigned int current_id) {
+void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
+ const TypeFromUser &ut) {
CompilerType copied_clang_type = GuardedCopyType(ut);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (!copied_clang_type) {
- if (log)
- LLDB_LOGF(
- log,
- "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
return;
}
@@ -2009,16 +1939,14 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
}
void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- const TypeFromUser &ut,
- unsigned int current_id) {
+ const TypeFromUser &ut) {
CompilerType copied_clang_type = GuardedCopyType(ut);
if (!copied_clang_type) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- LLDB_LOGF(
- log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
return;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 722f5e15a2aa..6974535a8993 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionDeclMap_h_
-#define liblldb_ClangExpressionDeclMap_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
#include <signal.h>
#include <stdint.h>
@@ -17,7 +17,6 @@
#include "ClangASTSource.h"
#include "ClangExpressionVariable.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -29,6 +28,8 @@
namespace lldb_private {
+class ClangPersistentVariables;
+
/// \class ClangExpressionDeclMap ClangExpressionDeclMap.h
/// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are
/// defined in LLDB's debug information.
@@ -79,8 +80,8 @@ public:
ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
- const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer,
- ValueObject *ctx_obj);
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);
/// Destructor
~ClangExpressionDeclMap() override;
@@ -274,14 +275,9 @@ public:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void FindExternalVisibleDecls(NameSearchContext &context,
lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
+ const CompilerDeclContext &namespace_decl);
protected:
/// Retrieves the declaration with the given name from the storage of
@@ -335,7 +331,8 @@ private:
///that receives new top-level
///functions.
private:
- DISALLOW_COPY_AND_ASSIGN(ParserVars);
+ ParserVars(const ParserVars &) = delete;
+ const ParserVars &operator=(const ParserVars &) = delete;
};
std::unique_ptr<ParserVars> m_parser_vars;
@@ -394,32 +391,19 @@ private:
///
/// \param[in] name
/// The name of the entities that need to be found.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void SearchPersistenDecls(NameSearchContext &context, const ConstString name,
- unsigned int current_id);
+ void SearchPersistenDecls(NameSearchContext &context, const ConstString name);
/// Handles looking up $__lldb_class which requires special treatment.
///
/// \param[in] context
/// The NameSearchContext that can construct Decls for this name.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookUpLldbClass(NameSearchContext &context, unsigned int current_id);
+ void LookUpLldbClass(NameSearchContext &context);
/// Handles looking up $__lldb_objc_class which requires special treatment.
///
/// \param[in] context
/// The NameSearchContext that can construct Decls for this name.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookUpLldbObjCClass(NameSearchContext &context, unsigned int current_id);
+ void LookUpLldbObjCClass(NameSearchContext &context);
/// Handles looking up the synthetic namespace that contains our local
/// variables for the current frame.
@@ -438,12 +422,7 @@ private:
///
/// \param[in] name
/// The name of the entities that need to be found.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name,
- unsigned current_id);
+ void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name);
/// Looks up a local variable.
///
@@ -453,10 +432,6 @@ private:
/// \param[in] name
/// The name of the entities that need to be found.
///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
/// \param[in] sym_ctx
/// The current SymbolContext of this frame.
///
@@ -466,8 +441,8 @@ private:
/// \return
/// True iff a local variable was found.
bool LookupLocalVariable(NameSearchContext &context, ConstString name,
- unsigned current_id, SymbolContext &sym_ctx,
- CompilerDeclContext &namespace_decl);
+ SymbolContext &sym_ctx,
+ const CompilerDeclContext &namespace_decl);
/// Searches for functions in the given SymbolContextList.
///
@@ -499,13 +474,9 @@ private:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void LookupFunction(NameSearchContext &context, lldb::ModuleSP module_sp,
- ConstString name, CompilerDeclContext &namespace_decl,
- unsigned current_id);
+ ConstString name,
+ const CompilerDeclContext &namespace_decl);
/// Given a target, find a variable that matches the given name and type.
///
@@ -523,9 +494,9 @@ private:
///
/// \return
/// The LLDB Variable found, or NULL if none was found.
- lldb::VariableSP FindGlobalVariable(Target &target, lldb::ModuleSP &module,
- ConstString name,
- CompilerDeclContext *namespace_decl);
+ lldb::VariableSP
+ FindGlobalVariable(Target &target, lldb::ModuleSP &module, ConstString name,
+ const CompilerDeclContext &namespace_decl);
/// Get the value of a variable in a given execution context and return the
/// associated Types if needed.
@@ -565,7 +536,7 @@ private:
/// \param[in] valobj
/// The LLDB ValueObject for that variable.
void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,
- lldb::ValueObjectSP valobj, unsigned int current_id);
+ lldb::ValueObjectSP valobj);
/// Use the NameSearchContext to generate a Decl for the given persistent
/// variable, and put it in the list of found entities.
@@ -575,18 +546,12 @@ private:
///
/// \param[in] pvar_sp
/// The persistent variable that needs a Decl.
- ///
- /// \param[in] current_id
- /// The ID of the current invocation of FindExternalVisibleDecls
- /// for logging purposes.
void AddOneVariable(NameSearchContext &context,
- lldb::ExpressionVariableSP &pvar_sp,
- unsigned int current_id);
+ lldb::ExpressionVariableSP &pvar_sp);
/// Use the NameSearchContext to generate a Decl for the given LLDB symbol
/// (treated as a variable), and put it in the list of found entities.
- void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol,
- unsigned int current_id);
+ void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol);
/// Use the NameSearchContext to generate a Decl for the given function.
/// (Functions are not placed in the Tuple list.) Can handle both fully
@@ -602,8 +567,7 @@ private:
/// \param[in] sym
/// The Symbol that corresponds to a function that needs to be
/// created with generic type (unitptr_t foo(...)).
- void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym,
- unsigned int current_id);
+ void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);
/// Use the NameSearchContext to generate a Decl for the given register.
///
@@ -612,8 +576,7 @@ private:
///
/// \param[in] reg_info
/// The information corresponding to that register.
- void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info,
- unsigned int current_id);
+ void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info);
/// Use the NameSearchContext to generate a Decl for the given type. (Types
/// are not placed in the Tuple list.)
@@ -623,38 +586,40 @@ private:
///
/// \param[in] type
/// The type that needs to be created.
- void AddOneType(NameSearchContext &context, const TypeFromUser &type,
- unsigned int current_id);
+ void AddOneType(NameSearchContext &context, const TypeFromUser &type);
- /// Generate a Decl for "*this" and add a member function declaration to it
- /// for the expression, then report it.
+ /// Adds the class in which the expression is evaluated to the lookup and
+ /// prepares the class to be used as a context for expression evaluation (for
+ /// example, it creates a fake member function that will contain the
+ /// expression LLDB is trying to evaluate).
///
/// \param[in] context
- /// The NameSearchContext to use when constructing the Decl.
+ /// The NameSearchContext to which the class should be added as a lookup
+ /// result.
///
/// \param[in] type
- /// The type for *this.
- void AddThisType(NameSearchContext &context, const TypeFromUser &type,
- unsigned int current_id);
+ /// The type of the class that serves as the evaluation context.
+ void AddContextClassType(NameSearchContext &context,
+ const TypeFromUser &type);
/// Move a type out of the current ASTContext into another, but make sure to
/// export all components of the type also.
///
/// \param[in] target
- /// The ClangASTContext to move to.
+ /// The TypeSystemClang to move to.
/// \param[in] source
- /// The ClangASTContext to move from. This is assumed to be going away.
+ /// The TypeSystemClang to move from. This is assumed to be going away.
/// \param[in] parser_type
/// The type as it appears in the source context.
///
/// \return
/// Returns the moved type, or an empty type if there was a problem.
- TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
+ TypeFromUser DeportType(TypeSystemClang &target, TypeSystemClang &source,
TypeFromParser parser_type);
- ClangASTContext *GetClangASTContext();
+ TypeSystemClang *GetTypeSystemClang();
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionDeclMap_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index 48da5abb9126..e33e5df22236 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -6,21 +6,24 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpression_h_
-#define liblldb_ClangExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
#include <map>
#include <string>
#include <vector>
-
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
+namespace clang {
+class ASTConsumer;
+}
+
namespace lldb_private {
+class ClangExpressionDeclMap;
class RecordingMemoryManager;
// ClangExpressionHelper
@@ -57,4 +60,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_ClangExpression_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 8abd14942885..6ff028cf6980 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionParser.cpp -------------------------------*- C++ -*-===//
+//===-- ClangExpressionParser.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -67,6 +67,7 @@
#include "IRForTarget.h"
#include "ModuleDependencyCollector.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -75,7 +76,6 @@
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/File.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
@@ -91,6 +91,7 @@
#include "lldb/Utility/StringList.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include <cctype>
#include <memory>
@@ -146,21 +147,40 @@ public:
llvm::StringRef getErrorString() { return m_error_stream.GetString(); }
};
+static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info) {
+ for (auto &fix_it : Info.getFixItHints()) {
+ if (fix_it.isNull())
+ continue;
+ diag->AddFixitHint(fix_it);
+ }
+}
+
class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
public:
ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) {
- DiagnosticOptions *m_options = new DiagnosticOptions(opts);
- m_options->ShowPresumedLoc = true;
- m_options->ShowLevel = false;
- m_os.reset(new llvm::raw_string_ostream(m_output));
- m_passthrough.reset(
- new clang::TextDiagnosticPrinter(*m_os, m_options, false));
+ DiagnosticOptions *options = new DiagnosticOptions(opts);
+ options->ShowPresumedLoc = true;
+ options->ShowLevel = false;
+ m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
+ m_passthrough =
+ std::make_shared<clang::TextDiagnosticPrinter>(*m_os, options);
}
void ResetManager(DiagnosticManager *manager = nullptr) {
m_manager = manager;
}
+ /// Returns the last ClangDiagnostic message that the DiagnosticManager
+ /// received or a nullptr if the DiagnosticMangager hasn't seen any
+ /// Clang diagnostics yet.
+ ClangDiagnostic *MaybeGetLastClangDiag() const {
+ if (m_manager->Diagnostics().empty())
+ return nullptr;
+ lldb_private::Diagnostic *diag = m_manager->Diagnostics().back().get();
+ ClangDiagnostic *clang_diag = dyn_cast<ClangDiagnostic>(diag);
+ return clang_diag;
+ }
+
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) override {
if (!m_manager) {
@@ -180,6 +200,9 @@ public:
return;
}
+ // Update error/warning counters.
+ DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+
// Render diagnostic message to m_output.
m_output.clear();
m_passthrough->HandleDiagnostic(DiagLevel, Info);
@@ -203,11 +226,29 @@ public:
case DiagnosticsEngine::Level::Note:
m_manager->AppendMessageToDiagnostic(m_output);
make_new_diagnostic = false;
+
+ // 'note:' diagnostics for errors and warnings can also contain Fix-Its.
+ // We add these Fix-Its to the last error diagnostic to make sure
+ // that we later have all Fix-Its related to an 'error' diagnostic when
+ // we apply them to the user expression.
+ auto *clang_diag = MaybeGetLastClangDiag();
+ // If we don't have a previous diagnostic there is nothing to do.
+ // If the previous diagnostic already has its own Fix-Its, assume that
+ // the 'note:' Fix-It is just an alternative way to solve the issue and
+ // ignore these Fix-Its.
+ if (!clang_diag || clang_diag->HasFixIts())
+ break;
+ // Ignore all Fix-Its that are not associated with an error.
+ if (clang_diag->GetSeverity() != eDiagnosticSeverityError)
+ break;
+ AddAllFixIts(clang_diag, Info);
+ break;
}
if (make_new_diagnostic) {
// ClangDiagnostic messages are expected to have no whitespace/newlines
// around them.
- std::string stripped_output = llvm::StringRef(m_output).trim();
+ std::string stripped_output =
+ std::string(llvm::StringRef(m_output).trim());
auto new_diagnostic = std::make_unique<ClangDiagnostic>(
stripped_output, severity, Info.getID());
@@ -216,20 +257,18 @@ public:
// enough context in an expression for the warning to be useful.
// FIXME: Should we try to filter out FixIts that apply to our generated
// code, and not the user's expression?
- if (severity == eDiagnosticSeverityError) {
- size_t num_fixit_hints = Info.getNumFixItHints();
- for (size_t i = 0; i < num_fixit_hints; i++) {
- const clang::FixItHint &fixit = Info.getFixItHint(i);
- if (!fixit.isNull())
- new_diagnostic->AddFixitHint(fixit);
- }
- }
+ if (severity == eDiagnosticSeverityError)
+ AddAllFixIts(new_diagnostic.get(), Info);
m_manager->AddDiagnostic(std::move(new_diagnostic));
}
}
- clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); }
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
+ m_passthrough->BeginSourceFile(LO, PP);
+ }
+
+ void EndSourceFile() override { m_passthrough->EndSourceFile(); }
private:
DiagnosticManager *m_manager = nullptr;
@@ -253,9 +292,9 @@ static void SetupModuleHeaderPaths(CompilerInstance *compiler,
}
llvm::SmallString<128> module_cache;
- auto props = ModuleList::GetGlobalModuleListProperties();
+ const auto &props = ModuleList::GetGlobalModuleListProperties();
props.GetClangModulesCachePath().GetPath(module_cache);
- search_opts.ModuleCachePath = module_cache.str();
+ search_opts.ModuleCachePath = std::string(module_cache.str());
LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str());
search_opts.ResourceDir = GetClangResourceDir().GetPath();
@@ -279,28 +318,27 @@ ClangExpressionParser::ClangExpressionParser(
// We can't compile expressions without a target. So if the exe_scope is
// null or doesn't have a target, then we just need to get out of here. I'll
- // lldb_assert and not make any of the compiler objects since
+ // lldbassert and not make any of the compiler objects since
// I can't return errors directly from the constructor. Further calls will
// check if the compiler was made and
// bag out if it wasn't.
if (!exe_scope) {
- lldb_assert(exe_scope, "Can't make an expression parser with a null scope.",
- __FUNCTION__, __FILE__, __LINE__);
+ lldbassert(exe_scope &&
+ "Can't make an expression parser with a null scope.");
return;
}
lldb::TargetSP target_sp;
target_sp = exe_scope->CalculateTarget();
if (!target_sp) {
- lldb_assert(target_sp.get(),
- "Can't make an expression parser with a null target.",
- __FUNCTION__, __FILE__, __LINE__);
+ lldbassert(target_sp.get() &&
+ "Can't make an expression parser with a null target.");
return;
}
// 1. Create a new compiler instance.
- m_compiler.reset(new CompilerInstance());
+ m_compiler = std::make_unique<CompilerInstance>();
// When capturing a reproducer, hook up the file collector with clang to
// collector modules and headers.
@@ -391,9 +429,13 @@ ClangExpressionParser::ClangExpressionParser(
// target. In this case, a specialized language runtime is available and we
// can query it for extra options. For 99% of use cases, this will not be
// needed and should be provided when basic platform detection is not enough.
- if (lang_rt)
+ // FIXME: Generalize this. Only RenderScriptRuntime currently supports this
+ // currently. Hardcoding this isn't ideal but it's better than LanguageRuntime
+ // having knowledge of clang::TargetOpts.
+ if (auto *renderscript_rt =
+ llvm::dyn_cast_or_null<RenderScriptRuntime>(lang_rt))
overridden_target_opts =
- lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
+ renderscript_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
if (overridden_target_opts)
if (log && log->GetVerbose()) {
@@ -606,11 +648,12 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->createASTContext();
clang::ASTContext &ast_context = m_compiler->getASTContext();
- m_ast_context.reset(new ClangASTContext(ast_context));
+ m_ast_context = std::make_unique<TypeSystemClang>(
+ "Expression ASTContext for '" + m_filename + "'", ast_context);
std::string module_name("$__lldb_module");
- m_llvm_context.reset(new LLVMContext());
+ m_llvm_context = std::make_unique<LLVMContext>();
m_code_generator.reset(CreateLLVMCodeGen(
m_compiler->getDiagnostics(), module_name,
m_compiler->getHeaderSearchOpts(), m_compiler->getPreprocessorOpts(),
@@ -631,11 +674,33 @@ class CodeComplete : public CodeCompleteConsumer {
std::string m_expr;
unsigned m_position = 0;
- CompletionRequest &m_request;
/// The printing policy we use when printing declarations for our completion
/// descriptions.
clang::PrintingPolicy m_desc_policy;
+ struct CompletionWithPriority {
+ CompletionResult::Completion completion;
+ /// See CodeCompletionResult::Priority;
+ unsigned Priority;
+
+ /// Establishes a deterministic order in a list of CompletionWithPriority.
+ /// The order returned here is the order in which the completions are
+ /// displayed to the user.
+ bool operator<(const CompletionWithPriority &o) const {
+ // High priority results should come first.
+ if (Priority != o.Priority)
+ return Priority > o.Priority;
+
+ // Identical priority, so just make sure it's a deterministic order.
+ return completion.GetUniqueKey() < o.completion.GetUniqueKey();
+ }
+ };
+
+ /// The stored completions.
+ /// Warning: These are in a non-deterministic order until they are sorted
+ /// and returned back to the caller.
+ std::vector<CompletionWithPriority> m_completions;
+
/// Returns true if the given character can be used in an identifier.
/// This also returns true for numbers because for completion we usually
/// just iterate backwards over iterators.
@@ -652,7 +717,7 @@ class CodeComplete : public CodeCompleteConsumer {
/// Drops all tokens in front of the expression that are unrelated for
/// the completion of the cmd line. 'unrelated' means here that the token
/// is not interested for the lldb completion API result.
- StringRef dropUnrelatedFrontTokens(StringRef cmd) {
+ StringRef dropUnrelatedFrontTokens(StringRef cmd) const {
if (cmd.empty())
return cmd;
@@ -673,18 +738,18 @@ class CodeComplete : public CodeCompleteConsumer {
}
/// Removes the last identifier token from the given cmd line.
- StringRef removeLastToken(StringRef cmd) {
+ StringRef removeLastToken(StringRef cmd) const {
while (!cmd.empty() && IsIdChar(cmd.back())) {
cmd = cmd.drop_back();
}
return cmd;
}
- /// Attemps to merge the given completion from the given position into the
+ /// Attempts to merge the given completion from the given position into the
/// existing command. Returns the completion string that can be returned to
/// the lldb completion API.
std::string mergeCompletion(StringRef existing, unsigned pos,
- StringRef completion) {
+ StringRef completion) const {
StringRef existing_command = existing.substr(0, pos);
// We rewrite the last token with the completion, so let's drop that
// token from the command.
@@ -706,11 +771,10 @@ public:
/// \param[out] position
/// The character position of the user cursor in the `expr` parameter.
///
- CodeComplete(CompletionRequest &request, clang::LangOptions ops,
- std::string expr, unsigned position)
+ CodeComplete(clang::LangOptions ops, std::string expr, unsigned position)
: CodeCompleteConsumer(CodeCompleteOptions()),
m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
- m_position(position), m_request(request), m_desc_policy(ops) {
+ m_position(position), m_desc_policy(ops) {
// Ensure that the printing policy is producing a description that is as
// short as possible.
@@ -723,9 +787,6 @@ public:
m_desc_policy.Bool = true;
}
- /// Deregisters and destroys this code-completion consumer.
- ~CodeComplete() override {}
-
/// \name Code-completion filtering
/// Check if the result should be filtered out.
bool isResultFilteredOut(StringRef Filter,
@@ -753,6 +814,85 @@ public:
return true;
}
+private:
+ /// Generate the completion strings for the given CodeCompletionResult.
+ /// Note that this function has to process results that could come in
+ /// non-deterministic order, so this function should have no side effects.
+ /// To make this easier to enforce, this function and all its parameters
+ /// should always be const-qualified.
+ /// \return Returns llvm::None if no completion should be provided for the
+ /// given CodeCompletionResult.
+ llvm::Optional<CompletionWithPriority>
+ getCompletionForResult(const CodeCompletionResult &R) const {
+ std::string ToInsert;
+ std::string Description;
+ // Handle the different completion kinds that come from the Sema.
+ switch (R.Kind) {
+ case CodeCompletionResult::RK_Declaration: {
+ const NamedDecl *D = R.Declaration;
+ ToInsert = R.Declaration->getNameAsString();
+ // If we have a function decl that has no arguments we want to
+ // complete the empty parantheses for the user. If the function has
+ // arguments, we at least complete the opening bracket.
+ if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
+ if (F->getNumParams() == 0)
+ ToInsert += "()";
+ else
+ ToInsert += "(";
+ raw_string_ostream OS(Description);
+ F->print(OS, m_desc_policy, false);
+ OS.flush();
+ } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
+ Description = V->getType().getAsString(m_desc_policy);
+ } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
+ Description = F->getType().getAsString(m_desc_policy);
+ } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
+ // If we try to complete a namespace, then we can directly append
+ // the '::'.
+ if (!N->isAnonymousNamespace())
+ ToInsert += "::";
+ }
+ break;
+ }
+ case CodeCompletionResult::RK_Keyword:
+ ToInsert = R.Keyword;
+ break;
+ case CodeCompletionResult::RK_Macro:
+ ToInsert = R.Macro->getName().str();
+ break;
+ case CodeCompletionResult::RK_Pattern:
+ ToInsert = R.Pattern->getTypedText();
+ break;
+ }
+ // We also filter some internal lldb identifiers here. The user
+ // shouldn't see these.
+ if (llvm::StringRef(ToInsert).startswith("$__lldb_"))
+ return llvm::None;
+ if (ToInsert.empty())
+ return llvm::None;
+ // Merge the suggested Token into the existing command line to comply
+ // with the kind of result the lldb API expects.
+ std::string CompletionSuggestion =
+ mergeCompletion(m_expr, m_position, ToInsert);
+
+ CompletionResult::Completion completion(CompletionSuggestion, Description,
+ CompletionMode::Normal);
+ return {{completion, R.Priority}};
+ }
+
+public:
+ /// Adds the completions to the given CompletionRequest.
+ void GetCompletions(CompletionRequest &request) {
+ // Bring m_completions into a deterministic order and pass it on to the
+ // CompletionRequest.
+ llvm::sort(m_completions);
+
+ for (const CompletionWithPriority &C : m_completions)
+ request.AddCompletion(C.completion.GetCompletion(),
+ C.completion.GetDescription(),
+ C.completion.GetMode());
+ }
+
/// \name Code-completion callbacks
/// Process the finalized code-completion results.
void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
@@ -771,59 +911,11 @@ public:
continue;
CodeCompletionResult &R = Results[I];
- std::string ToInsert;
- std::string Description;
- // Handle the different completion kinds that come from the Sema.
- switch (R.Kind) {
- case CodeCompletionResult::RK_Declaration: {
- const NamedDecl *D = R.Declaration;
- ToInsert = R.Declaration->getNameAsString();
- // If we have a function decl that has no arguments we want to
- // complete the empty parantheses for the user. If the function has
- // arguments, we at least complete the opening bracket.
- if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
- if (F->getNumParams() == 0)
- ToInsert += "()";
- else
- ToInsert += "(";
- raw_string_ostream OS(Description);
- F->print(OS, m_desc_policy, false);
- OS.flush();
- } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
- Description = V->getType().getAsString(m_desc_policy);
- } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
- Description = F->getType().getAsString(m_desc_policy);
- } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
- // If we try to complete a namespace, then we can directly append
- // the '::'.
- if (!N->isAnonymousNamespace())
- ToInsert += "::";
- }
- break;
- }
- case CodeCompletionResult::RK_Keyword:
- ToInsert = R.Keyword;
- break;
- case CodeCompletionResult::RK_Macro:
- ToInsert = R.Macro->getName().str();
- break;
- case CodeCompletionResult::RK_Pattern:
- ToInsert = R.Pattern->getTypedText();
- break;
- }
- // At this point all information is in the ToInsert string.
-
- // We also filter some internal lldb identifiers here. The user
- // shouldn't see these.
- if (StringRef(ToInsert).startswith("$__lldb_"))
+ llvm::Optional<CompletionWithPriority> CompletionAndPriority =
+ getCompletionForResult(R);
+ if (!CompletionAndPriority)
continue;
- if (!ToInsert.empty()) {
- // Merge the suggested Token into the existing command line to comply
- // with the kind of result the lldb API expects.
- std::string CompletionSuggestion =
- mergeCompletion(m_expr, m_position, ToInsert);
- m_request.AddCompletion(CompletionSuggestion, Description);
- }
+ m_completions.push_back(*CompletionAndPriority);
}
}
@@ -860,12 +952,13 @@ bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line,
// the LLVMUserExpression which exposes the right API. This should never fail
// as we always have a ClangUserExpression whenever we call this.
ClangUserExpression *llvm_expr = cast<ClangUserExpression>(&m_expr);
- CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr->GetUserText(),
+ CodeComplete CC(m_compiler->getLangOpts(), llvm_expr->GetUserText(),
typed_pos);
// We don't need a code generator for parsing.
m_code_generator.reset();
// Start parsing the expression with our custom code completion consumer.
ParseInternal(mgr, &CC, line, pos);
+ CC.GetCompletions(request);
return true;
}
@@ -881,7 +974,6 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
ClangDiagnosticManagerAdapter *adapter =
static_cast<ClangDiagnosticManagerAdapter *>(
m_compiler->getDiagnostics().getClient());
- auto diag_buf = adapter->GetPassthrough();
adapter->ResetManager(&diagnostic_manager);
@@ -936,8 +1028,8 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
}
- diag_buf->BeginSourceFile(m_compiler->getLangOpts(),
- &m_compiler->getPreprocessor());
+ adapter->BeginSourceFile(m_compiler->getLangOpts(),
+ &m_compiler->getPreprocessor());
ClangExpressionHelper *type_system_helper =
dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
@@ -961,11 +1053,11 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
std::unique_ptr<clang::ASTConsumer> Consumer;
if (ast_transformer) {
- Consumer.reset(new ASTConsumerForwarder(ast_transformer));
+ Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
} else if (m_code_generator) {
- Consumer.reset(new ASTConsumerForwarder(m_code_generator.get()));
+ Consumer = std::make_unique<ASTConsumerForwarder>(m_code_generator.get());
} else {
- Consumer.reset(new ASTConsumer());
+ Consumer = std::make_unique<ASTConsumer>();
}
clang::ASTContext &ast_context = m_compiler->getASTContext();
@@ -1022,9 +1114,9 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
// original behavior of ParseAST (which also destroys the Sema after parsing).
m_compiler->setSema(nullptr);
- diag_buf->EndSourceFile();
+ adapter->EndSourceFile();
- unsigned num_errors = diag_buf->getNumErrors();
+ unsigned num_errors = adapter->getNumErrors();
if (m_pp_callbacks && m_pp_callbacks->hasErrors()) {
num_errors++;
@@ -1065,6 +1157,28 @@ ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) {
return abi;
}
+/// Applies the given Fix-It hint to the given commit.
+static void ApplyFixIt(const FixItHint &fixit, clang::edit::Commit &commit) {
+ // This is cobbed from clang::Rewrite::FixItRewriter.
+ if (fixit.CodeToInsert.empty()) {
+ if (fixit.InsertFromRange.isValid()) {
+ commit.insertFromRange(fixit.RemoveRange.getBegin(),
+ fixit.InsertFromRange, /*afterToken=*/false,
+ fixit.BeforePreviousInsertions);
+ return;
+ }
+ commit.remove(fixit.RemoveRange);
+ return;
+ }
+ if (fixit.RemoveRange.isTokenRange() ||
+ fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
+ commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
+ return;
+ }
+ commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
+ /*afterToken=*/false, fixit.BeforePreviousInsertions);
+}
+
bool ClangExpressionParser::RewriteExpression(
DiagnosticManager &diagnostic_manager) {
clang::SourceManager &source_manager = m_compiler->getSourceManager();
@@ -1096,26 +1210,12 @@ bool ClangExpressionParser::RewriteExpression(
for (const auto &diag : diagnostic_manager.Diagnostics()) {
const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
- if (diagnostic && diagnostic->HasFixIts()) {
- for (const FixItHint &fixit : diagnostic->FixIts()) {
- // This is cobbed from clang::Rewrite::FixItRewriter.
- if (fixit.CodeToInsert.empty()) {
- if (fixit.InsertFromRange.isValid()) {
- commit.insertFromRange(fixit.RemoveRange.getBegin(),
- fixit.InsertFromRange, /*afterToken=*/false,
- fixit.BeforePreviousInsertions);
- } else
- commit.remove(fixit.RemoveRange);
- } else {
- if (fixit.RemoveRange.isTokenRange() ||
- fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
- commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
- else
- commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
- /*afterToken=*/false, fixit.BeforePreviousInsertions);
- }
- }
- }
+ if (!diagnostic)
+ continue;
+ if (!diagnostic->HasFixIts())
+ continue;
+ for (const FixItHint &fixit : diagnostic->FixIts())
+ ApplyFixIt(fixit, commit);
}
// FIXME - do we want to try to propagate specific errors here?
@@ -1230,18 +1330,13 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
type_system_helper->DeclMap(); // result can be NULL
if (decl_map) {
- Target *target = exe_ctx.GetTargetPtr();
- auto &error_stream = target->GetDebugger().GetErrorStream();
+ StreamString error_stream;
IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
*execution_unit_sp, error_stream,
function_name.AsCString());
- bool ir_can_run =
- ir_for_target.runOnModule(*execution_unit_sp->GetModule());
-
- if (!ir_can_run) {
- err.SetErrorString(
- "The expression could not be prepared to run in the target");
+ if (!ir_for_target.runOnModule(*execution_unit_sp->GetModule())) {
+ err.SetErrorString(error_stream.GetString());
return err;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 4a410cecb94a..6afee22da8d1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -6,10 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionParser_h_
-#define liblldb_ClangExpressionParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionParser.h"
#include "lldb/Utility/ArchSpec.h"
@@ -19,13 +18,20 @@
#include <string>
#include <vector>
+namespace llvm {
+class LLVMContext;
+}
+
namespace clang {
+class CodeGenerator;
class CodeCompleteConsumer;
-}
+class CompilerInstance;
+} // namespace clang
namespace lldb_private {
class IRExecutionUnit;
+class TypeSystemClang;
/// \class ClangExpressionParser ClangExpressionParser.h
/// "lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of
@@ -171,7 +177,7 @@ private:
class LLDBPreprocessorCallbacks;
LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor
///encounters module imports
- std::unique_ptr<ClangASTContext> m_ast_context;
+ std::unique_ptr<TypeSystemClang> m_ast_context;
std::vector<std::string> m_include_directories;
/// File name used for the user expression.
@@ -179,4 +185,4 @@ private:
};
}
-#endif // liblldb_ClangExpressionParser_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 7ebb5fee1ec6..a429963277d1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionSourceCode.cpp ---------------------------*- C++ -*-===//
+//===-- ClangExpressionSourceCode.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,6 +9,7 @@
#include "ClangExpressionSourceCode.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringRef.h"
@@ -173,8 +174,8 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit,
lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode(
llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix,
- llvm::StringRef body, Wrapping wrap)
- : ExpressionSourceCode(name, prefix, body, wrap) {
+ llvm::StringRef body, Wrapping wrap, WrapKind wrap_kind)
+ : ExpressionSourceCode(name, prefix, body, wrap), m_wrap_kind(wrap_kind) {
// Use #line markers to pretend that we have a single-line source file
// containing only the user expression. This will hide our wrapper code
// from the user when we render diagnostics with Clang.
@@ -260,10 +261,9 @@ TokenVerifier::TokenVerifier(std::string body) {
}
}
-static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
- StreamString &stream,
- const std::string &expr,
- lldb::LanguageType wrapping_language) {
+void ClangExpressionSourceCode::AddLocalVariableDecls(
+ const lldb::VariableListSP &var_list_sp, StreamString &stream,
+ const std::string &expr) const {
TokenVerifier tokens(expr);
for (size_t i = 0; i < var_list_sp->GetSize(); i++) {
@@ -280,13 +280,12 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
if (!expr.empty() && !tokens.hasToken(var_name.GetStringRef()))
continue;
- if ((var_name == "self" || var_name == "_cmd") &&
- (wrapping_language == lldb::eLanguageTypeObjC ||
- wrapping_language == lldb::eLanguageTypeObjC_plus_plus))
+ const bool is_objc = m_wrap_kind == WrapKind::ObjCInstanceMethod ||
+ m_wrap_kind == WrapKind::ObjCStaticMethod;
+ if ((var_name == "self" || var_name == "_cmd") && is_objc)
continue;
- if (var_name == "this" &&
- wrapping_language == lldb::eLanguageTypeC_plus_plus)
+ if (var_name == "this" && m_wrap_kind == WrapKind::CppMemberFunction)
continue;
stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
@@ -294,9 +293,8 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
}
bool ClangExpressionSourceCode::GetText(
- std::string &text, lldb::LanguageType wrapping_language, bool static_method,
- ExecutionContext &exe_ctx, bool add_locals, bool force_add_all_locals,
- llvm::ArrayRef<std::string> modules) const {
+ std::string &text, ExecutionContext &exe_ctx, bool add_locals,
+ bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
@@ -373,21 +371,11 @@ bool ClangExpressionSourceCode::GetText(
lldb::VariableListSP var_list_sp =
frame->GetInScopeVariableList(false, true);
AddLocalVariableDecls(var_list_sp, lldb_local_var_decls,
- force_add_all_locals ? "" : m_body,
- wrapping_language);
+ force_add_all_locals ? "" : m_body);
}
}
if (m_wrap) {
- switch (wrapping_language) {
- default:
- return false;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- break;
- }
-
// Generate a list of @import statements that will import the specified
// module into our expression.
std::string module_imports;
@@ -406,22 +394,12 @@ bool ClangExpressionSourceCode::GetText(
// First construct a tagged form of the user expression so we can find it
// later:
std::string tagged_body;
- switch (wrapping_language) {
- default:
- tagged_body = m_body;
- break;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- tagged_body.append(m_start_marker);
- tagged_body.append(m_body);
- tagged_body.append(m_end_marker);
- break;
- }
- switch (wrapping_language) {
- default:
- break;
- case lldb::eLanguageTypeC:
+ tagged_body.append(m_start_marker);
+ tagged_body.append(m_body);
+ tagged_body.append(m_end_marker);
+
+ switch (m_wrap_kind) {
+ case WrapKind::Function:
wrap_stream.Printf("%s"
"void \n"
"%s(void *$__lldb_arg) \n"
@@ -432,7 +410,7 @@ bool ClangExpressionSourceCode::GetText(
module_imports.c_str(), m_name.c_str(),
lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
- case lldb::eLanguageTypeC_plus_plus:
+ case WrapKind::CppMemberFunction:
wrap_stream.Printf("%s"
"void \n"
"$__lldb_class::%s(void *$__lldb_arg) \n"
@@ -443,42 +421,42 @@ bool ClangExpressionSourceCode::GetText(
module_imports.c_str(), m_name.c_str(),
lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
- case lldb::eLanguageTypeObjC:
- if (static_method) {
- wrap_stream.Printf(
- "%s"
- "@interface $__lldb_objc_class ($__lldb_category) \n"
- "+(void)%s:(void *)$__lldb_arg; \n"
- "@end \n"
- "@implementation $__lldb_objc_class ($__lldb_category) \n"
- "+(void)%s:(void *)$__lldb_arg \n"
- "{ \n"
- " %s; \n"
- "%s"
- "} \n"
- "@end \n",
- module_imports.c_str(), m_name.c_str(), m_name.c_str(),
- lldb_local_var_decls.GetData(), tagged_body.c_str());
- } else {
- wrap_stream.Printf(
- "%s"
- "@interface $__lldb_objc_class ($__lldb_category) \n"
- "-(void)%s:(void *)$__lldb_arg; \n"
- "@end \n"
- "@implementation $__lldb_objc_class ($__lldb_category) \n"
- "-(void)%s:(void *)$__lldb_arg \n"
- "{ \n"
- " %s; \n"
- "%s"
- "} \n"
- "@end \n",
- module_imports.c_str(), m_name.c_str(), m_name.c_str(),
- lldb_local_var_decls.GetData(), tagged_body.c_str());
- }
+ case WrapKind::ObjCInstanceMethod:
+ wrap_stream.Printf(
+ "%s"
+ "@interface $__lldb_objc_class ($__lldb_category) \n"
+ "-(void)%s:(void *)$__lldb_arg; \n"
+ "@end \n"
+ "@implementation $__lldb_objc_class ($__lldb_category) \n"
+ "-(void)%s:(void *)$__lldb_arg \n"
+ "{ \n"
+ " %s; \n"
+ "%s"
+ "} \n"
+ "@end \n",
+ module_imports.c_str(), m_name.c_str(), m_name.c_str(),
+ lldb_local_var_decls.GetData(), tagged_body.c_str());
+ break;
+
+ case WrapKind::ObjCStaticMethod:
+ wrap_stream.Printf(
+ "%s"
+ "@interface $__lldb_objc_class ($__lldb_category) \n"
+ "+(void)%s:(void *)$__lldb_arg; \n"
+ "@end \n"
+ "@implementation $__lldb_objc_class ($__lldb_category) \n"
+ "+(void)%s:(void *)$__lldb_arg \n"
+ "{ \n"
+ " %s; \n"
+ "%s"
+ "} \n"
+ "@end \n",
+ module_imports.c_str(), m_name.c_str(), m_name.c_str(),
+ lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
}
- text = wrap_stream.GetString();
+ text = std::string(wrap_stream.GetString());
} else {
text.append(m_body);
}
@@ -487,17 +465,7 @@ bool ClangExpressionSourceCode::GetText(
}
bool ClangExpressionSourceCode::GetOriginalBodyBounds(
- std::string transformed_text, lldb::LanguageType wrapping_language,
- size_t &start_loc, size_t &end_loc) {
- switch (wrapping_language) {
- default:
- return false;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- break;
- }
-
+ std::string transformed_text, size_t &start_loc, size_t &end_loc) {
start_loc = transformed_text.find(m_start_marker);
if (start_loc == std::string::npos)
return false;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 1d159670b962..9a54f0e3ad8d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionSourceCode_h
-#define liblldb_ClangExpressionSourceCode_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
#include "lldb/Expression/Expression.h"
#include "lldb/Expression/ExpressionSourceCode.h"
@@ -28,20 +28,30 @@ public:
static const llvm::StringRef g_prefix_file_name;
static const char *g_expression_prefix;
+ /// The possible ways an expression can be wrapped.
+ enum class WrapKind {
+ /// Wrapped in a non-static member function of a C++ class.
+ CppMemberFunction,
+ /// Wrapped in an instance Objective-C method.
+ ObjCInstanceMethod,
+ /// Wrapped in a static Objective-C method.
+ ObjCStaticMethod,
+ /// Wrapped in a non-member function.
+ /// Note that this is also used for static member functions of a C++ class.
+ Function
+ };
+
static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename,
llvm::StringRef prefix,
- llvm::StringRef body) {
+ llvm::StringRef body,
+ WrapKind wrap_kind) {
return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body,
- Wrap);
+ Wrap, wrap_kind);
}
/// Generates the source code that will evaluate the expression.
///
/// \param text output parameter containing the source code string.
- /// \param wrapping_language If the expression is supossed to be wrapped,
- /// then this is the language that should be used for that.
- /// \param static_method True iff the expression is valuated inside a static
- /// Objective-C method.
/// \param exe_ctx The execution context in which the expression will be
/// evaluated.
/// \param add_locals True iff local variables should be injected into the
@@ -51,8 +61,7 @@ public:
/// \param modules A list of (C++) modules that the expression should import.
///
/// \return true iff the source code was successfully generated.
- bool GetText(std::string &text, lldb::LanguageType wrapping_language,
- bool static_method, ExecutionContext &exe_ctx, bool add_locals,
+ bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals,
bool force_add_all_locals,
llvm::ArrayRef<std::string> modules) const;
@@ -60,19 +69,24 @@ public:
// passed to CreateWrapped. Return true if the bounds could be found. This
// will also work on text with FixItHints applied.
bool GetOriginalBodyBounds(std::string transformed_text,
- lldb::LanguageType wrapping_language,
size_t &start_loc, size_t &end_loc);
protected:
ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name,
llvm::StringRef prefix, llvm::StringRef body,
- Wrapping wrap);
+ Wrapping wrap, WrapKind wrap_kind);
private:
+ void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
+ StreamString &stream,
+ const std::string &expr) const;
+
/// String marking the start of the user expression.
std::string m_start_marker;
/// String marking the end of the user expression.
std::string m_end_marker;
+ /// How the expression has been wrapped.
+ const WrapKind m_wrap_kind;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
index b5a2c80b5349..9af92e194da9 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionVariable.cpp -----------------------------*- C++ -*-===//
+//===-- ClangExpressionVariable.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index 0e6de28ee4df..58d589962abe 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionVariable_h_
-#define liblldb_ClangExpressionVariable_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
#include <signal.h>
#include <stdint.h>
@@ -19,7 +19,6 @@
#include "llvm/Support/Casting.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/TaggedASTType.h"
@@ -30,6 +29,10 @@ namespace llvm {
class Value;
}
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
class ValueObjectConstResult;
@@ -114,11 +117,9 @@ public:
class ParserVars {
public:
ParserVars()
- : m_parser_type(), m_named_decl(nullptr), m_llvm_value(nullptr),
+ : m_named_decl(nullptr), m_llvm_value(nullptr),
m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {}
- TypeFromParser
- m_parser_type; ///< The type of the variable according to the parser
const clang::NamedDecl
*m_named_decl; ///< The Decl corresponding to this variable
llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
@@ -196,9 +197,11 @@ public:
}
/// Members
- DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable);
+ ClangExpressionVariable(const ClangExpressionVariable &) = delete;
+ const ClangExpressionVariable &
+ operator=(const ClangExpressionVariable &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionVariable_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
new file mode 100644
index 000000000000..390afb458b5a
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
@@ -0,0 +1,88 @@
+//===-- ClangExternalASTSourceCallbacks.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace lldb_private;
+
+char ClangExternalASTSourceCallbacks::ID;
+
+void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) {
+ m_ast.CompleteTagDecl(tag_decl);
+}
+
+void ClangExternalASTSourceCallbacks::CompleteType(
+ clang::ObjCInterfaceDecl *objc_decl) {
+ m_ast.CompleteObjCInterfaceDecl(objc_decl);
+}
+
+bool ClangExternalASTSourceCallbacks::layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) {
+ return m_ast.LayoutRecordType(Record, Size, Alignment, FieldOffsets,
+ BaseOffsets, VirtualBaseOffsets);
+}
+
+void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
+ const clang::DeclContext *decl_ctx,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &decls) {
+ if (decl_ctx) {
+ clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(
+ const_cast<clang::DeclContext *>(decl_ctx));
+ if (tag_decl)
+ CompleteType(tag_decl);
+ }
+}
+
+bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(
+ const clang::DeclContext *DC, clang::DeclarationName Name) {
+ llvm::SmallVector<clang::NamedDecl *, 4> decls;
+ // Objective-C methods are not added into the LookupPtr when they originate
+ // from an external source. SetExternalVisibleDeclsForName() adds them.
+ if (auto *oid = llvm::dyn_cast<clang::ObjCInterfaceDecl>(DC)) {
+ clang::ObjCContainerDecl::method_range noload_methods(oid->noload_decls());
+ for (auto *omd : noload_methods)
+ if (omd->getDeclName() == Name)
+ decls.push_back(omd);
+ }
+ return !SetExternalVisibleDeclsForName(DC, Name, decls).empty();
+}
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
+ m_modules.push_back(module);
+ unsigned id = m_modules.size();
+ m_ids.insert({module, id});
+ return OptionalClangModuleID(id);
+}
+
+llvm::Optional<clang::ASTSourceDescriptor>
+ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) {
+ if (clang::Module *module = getModule(id))
+ return {*module};
+ return {};
+}
+
+clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) {
+ if (id && id <= m_modules.size())
+ return m_modules[id - 1];
+ return nullptr;
+}
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
+ return OptionalClangModuleID(m_ids[module]);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
new file mode 100644
index 000000000000..69088d9c82a5
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
@@ -0,0 +1,66 @@
+//===-- ClangExternalASTSourceCallbacks.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
+
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "clang/Basic/Module.h"
+
+namespace lldb_private {
+
+class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
+ /// LLVM RTTI support.
+ static char ID;
+
+public:
+ /// LLVM RTTI support.
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); }
+
+ ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {}
+
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Result) override;
+
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override;
+
+ void CompleteType(clang::TagDecl *tag_decl) override;
+
+ void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override;
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override;
+
+ TypeSystemClang &GetTypeSystem() const { return m_ast; }
+
+ /// Module-related methods.
+ /// \{
+ llvm::Optional<clang::ASTSourceDescriptor>
+ getSourceDescriptor(unsigned ID) override;
+ clang::Module *getModule(unsigned ID) override;
+ OptionalClangModuleID RegisterModule(clang::Module *module);
+ OptionalClangModuleID GetIDForModule(clang::Module *module);
+ /// \}
+private:
+ TypeSystemClang &m_ast;
+ std::vector<clang::Module *> m_modules;
+ llvm::DenseMap<clang::Module *, unsigned> m_ids;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 7f7c0a97f538..0c9ad2021035 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -1,4 +1,4 @@
-//===-- ClangFunctionCaller.cpp ---------------------------------*- C++ -*-===//
+//===-- ClangFunctionCaller.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -21,12 +21,12 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
@@ -209,8 +209,8 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
clang::ASTConsumer *
ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer(
clang::ASTConsumer *passthrough) {
- m_struct_extractor.reset(new ASTStructExtractor(
- passthrough, m_owner.GetWrapperStructName(), m_owner));
+ m_struct_extractor = std::make_unique<ASTStructExtractor>(
+ passthrough, m_owner.GetWrapperStructName(), m_owner);
return m_struct_extractor.get();
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 150a913152d0..8060b8c0aedc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangFunctionCaller_h_
-#define liblldb_ClangFunctionCaller_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
#include "ClangExpressionHelper.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -150,4 +149,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangFunctionCaller_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 42d3f22014dd..8abb7e420575 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -1,4 +1,4 @@
-//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===//
+//===-- ClangHost.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
llvm::sys::path::native(relative_path);
llvm::sys::path::append(clang_dir, relative_path);
if (!verify || VerifyClangPath(clang_dir)) {
- LLDB_LOGF(log,
- "DefaultComputeClangResourceDir: Setting ClangResourceDir "
- "to \"%s\", verify = %s",
- clang_dir.str().str().c_str(), verify ? "true" : "false");
+ LLDB_LOG(log,
+ "DefaultComputeClangResourceDir: Setting ClangResourceDir "
+ "to \"{0}\", verify = {1}",
+ clang_dir.str(), verify ? "true" : "false");
file_spec.GetDirectory().SetString(clang_dir);
FileSystem::Instance().Resolve(file_spec);
return true;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
index 9d49188178cd..d6809909a625 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
-#define LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
namespace lldb_private {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 0696c669f2e2..95acb883774d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -1,4 +1,4 @@
-//===-- ClangModulesDeclVendor.cpp ------------------------------*- C++ -*-===//
+//===-- ClangModulesDeclVendor.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#include <mutex>
-
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Parse/Parser.h"
@@ -24,10 +23,10 @@
#include "ClangModulesDeclVendor.h"
#include "ModuleDependencyCollector.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Target.h"
@@ -37,6 +36,9 @@
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
+#include <memory>
+#include <mutex>
+
using namespace lldb_private;
namespace {
@@ -54,10 +56,21 @@ public:
void DumpDiagnostics(Stream &error_stream);
+ void BeginSourceFile(const clang::LangOptions &LangOpts,
+ const clang::Preprocessor *PP = nullptr) override;
+ void EndSourceFile() override;
+
private:
typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
IDAndDiagnostic;
std::vector<IDAndDiagnostic> m_diagnostics;
+ /// The DiagnosticPrinter used for creating the full diagnostic messages
+ /// that are stored in m_diagnostics.
+ std::shared_ptr<clang::TextDiagnosticPrinter> m_diag_printer;
+ /// Output stream of m_diag_printer.
+ std::shared_ptr<llvm::raw_string_ostream> m_os;
+ /// Output string filled by m_os. Will be reused for different diagnostics.
+ std::string m_output;
Log *m_log;
};
@@ -108,25 +121,30 @@ private:
typedef std::set<ModuleID> ImportedModuleSet;
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
- // We assume that every ASTContext has an ClangASTContext, so we also store
- // a custom ClangASTContext for our internal ASTContext.
- std::unique_ptr<ClangASTContext> m_ast_context;
+ // We assume that every ASTContext has an TypeSystemClang, so we also store
+ // a custom TypeSystemClang for our internal ASTContext.
+ std::unique_ptr<TypeSystemClang> m_ast_context;
};
} // anonymous namespace
StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions();
+ m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
+ m_diag_printer =
+ std::make_shared<clang::TextDiagnosticPrinter>(*m_os, m_options);
}
void StoringDiagnosticConsumer::HandleDiagnostic(
clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
- llvm::SmallVector<char, 256> diagnostic_string;
+ // Print the diagnostic to m_output.
+ m_output.clear();
+ m_diag_printer->HandleDiagnostic(DiagLevel, info);
+ m_os->flush();
- info.FormatDiagnostic(diagnostic_string);
-
- m_diagnostics.push_back(
- IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(),
- diagnostic_string.size())));
+ // Store the diagnostic for later.
+ m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output));
}
void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
@@ -144,6 +162,15 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
}
}
+void StoringDiagnosticConsumer::BeginSourceFile(
+ const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) {
+ m_diag_printer->BeginSourceFile(LangOpts, PP);
+}
+
+void StoringDiagnosticConsumer::EndSourceFile() {
+ m_diag_printer->EndSourceFile();
+}
+
ClangModulesDeclVendor::ClangModulesDeclVendor()
: ClangDeclVendor(eClangModuleDeclVendor) {}
@@ -159,8 +186,10 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
m_compiler_instance(std::move(compiler_instance)),
m_parser(std::move(parser)) {
- // Initialize our ClangASTContext.
- m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext()));
+ // Initialize our TypeSystemClang.
+ m_ast_context =
+ std::make_unique<TypeSystemClang>("ClangModulesDeclVendor ASTContext",
+ m_compiler_instance->getASTContext());
}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
@@ -382,7 +411,7 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
if (num_matches >= max_matches)
return num_matches;
- decls.push_back(CompilerDecl(m_ast_context.get(), named_decl));
+ decls.push_back(m_ast_context->GetCompilerDecl(named_decl));
++num_matches;
}
@@ -601,10 +630,10 @@ ClangModulesDeclVendor::Create(Target &target) {
{
llvm::SmallString<128> path;
- auto props = ModuleList::GetGlobalModuleListProperties();
+ const auto &props = ModuleList::GetGlobalModuleListProperties();
props.GetClangModulesCachePath().GetPath(path);
std::string module_cache_argument("-fmodules-cache-path=");
- module_cache_argument.append(path.str());
+ module_cache_argument.append(std::string(path.str()));
compiler_invocation_arguments.push_back(module_cache_argument);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index e099b59041d8..f04d1b07f03d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -6,10 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangModulesDeclVendor_h
-#define liblldb_ClangModulesDeclVendor_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Platform.h"
@@ -113,4 +112,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_ClangModulesDeclVendor_h
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 41d62a462ab4..42afac9edb0d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -1,4 +1,4 @@
-//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===//
+//===-- ClangPersistentVariables.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,9 +7,10 @@
//===----------------------------------------------------------------------===//
#include "ClangPersistentVariables.h"
+#include "ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Value.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
@@ -82,7 +83,7 @@ ClangPersistentVariables::GetCompilerTypeFromPersistentDecl(
void ClangPersistentVariables::RegisterPersistentDecl(ConstString name,
clang::NamedDecl *decl,
- ClangASTContext *ctx) {
+ TypeSystemClang *ctx) {
PersistentDecl p = {decl, ctx};
m_persistent_decls.insert(std::make_pair(name.GetCString(), p));
@@ -99,3 +100,22 @@ clang::NamedDecl *
ClangPersistentVariables::GetPersistentDecl(ConstString name) {
return m_persistent_decls.lookup(name.GetCString()).m_decl;
}
+
+std::shared_ptr<ClangASTImporter>
+ClangPersistentVariables::GetClangASTImporter() {
+ if (!m_ast_importer_sp) {
+ m_ast_importer_sp = std::make_shared<ClangASTImporter>();
+ }
+ return m_ast_importer_sp;
+}
+
+ConstString
+ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) {
+ llvm::SmallString<64> name;
+ {
+ llvm::raw_svector_ostream os(name);
+ os << GetPersistentVariablePrefix(is_error)
+ << m_next_persistent_variable_id++;
+ }
+ return ConstString(name);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 434196b35fd5..f888b2d56e68 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangPersistentVariables_h_
-#define liblldb_ClangPersistentVariables_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
#include "llvm/ADT/DenseMap.h"
@@ -18,6 +18,9 @@
namespace lldb_private {
+class ClangASTImporter;
+class TypeSystemClang;
+
/// \class ClangPersistentVariables ClangPersistentVariables.h
/// "lldb/Expression/ClangPersistentVariables.h" Manages persistent values
/// that need to be preserved between expression invocations.
@@ -36,6 +39,8 @@ public:
return pv->getKind() == PersistentExpressionState::eKindClang;
}
+ std::shared_ptr<ClangASTImporter> GetClangASTImporter();
+
lldb::ExpressionVariableSP
CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
@@ -46,9 +51,7 @@ public:
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override {
- return "$";
- }
+ ConstString GetNextPersistentVariableName(bool is_error = false) override;
/// Returns the next file name that should be used for user expressions.
std::string GetNextExprFileName() {
@@ -63,7 +66,7 @@ public:
GetCompilerTypeFromPersistentDecl(ConstString type_name) override;
void RegisterPersistentDecl(ConstString name, clang::NamedDecl *decl,
- ClangASTContext *ctx);
+ TypeSystemClang *ctx);
clang::NamedDecl *GetPersistentDecl(ConstString name);
@@ -75,6 +78,12 @@ public:
return m_hand_loaded_clang_modules;
}
+protected:
+ llvm::StringRef
+ GetPersistentVariablePrefix(bool is_error = false) const override {
+ return "$";
+ }
+
private:
/// The counter used by GetNextExprFileName.
uint32_t m_next_user_file_id = 0;
@@ -84,8 +93,8 @@ private:
struct PersistentDecl {
/// The persistent decl.
clang::NamedDecl *m_decl = nullptr;
- /// The ClangASTContext for the ASTContext of m_decl.
- ClangASTContext *m_context = nullptr;
+ /// The TypeSystemClang for the ASTContext of m_decl.
+ TypeSystemClang *m_context = nullptr;
};
typedef llvm::DenseMap<const char *, PersistentDecl> PersistentDeclMap;
@@ -96,8 +105,9 @@ private:
m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded;
///these are the highest-
///< priority source for macros.
+ std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
};
} // namespace lldb_private
-#endif // liblldb_ClangPersistentVariables_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 6698797617a3..a28b4a7fb42c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -1,4 +1,4 @@
-//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
+//===-- ClangUserExpression.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -20,6 +20,7 @@
#include "ClangUserExpression.h"
#include "ASTResultSynthesizer.h"
+#include "ClangASTMetadata.h"
#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
@@ -27,6 +28,7 @@
#include "ClangPersistentVariables.h"
#include "CppModuleConfiguration.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
@@ -37,8 +39,6 @@
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -154,7 +154,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
}
m_needs_object_ptr = true;
} else if (clang::CXXMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
+ TypeSystemClang::DeclContextGetAsCXXMethodDecl(decl_context)) {
if (m_allow_cxx && method_decl->isInstance()) {
if (m_enforce_valid_object) {
lldb::VariableListSP variable_list_sp(
@@ -183,7 +183,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
m_needs_object_ptr = true;
}
} else if (clang::ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(
decl_context)) {
if (m_allow_objc) {
if (m_enforce_valid_object) {
@@ -216,7 +216,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
m_in_static_method = true;
}
} else if (clang::FunctionDecl *function_decl =
- ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
+ TypeSystemClang::DeclContextGetAsFunctionDecl(decl_context)) {
// We might also have a function that said in the debug information that it
// captured an object pointer. The best way to deal with getting to the
// ivars at present is by pretending that this is a method of a class in
@@ -224,7 +224,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
// that here.
ClangASTMetadata *metadata =
- ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
+ TypeSystemClang::DeclContextGetMetaData(decl_context, function_decl);
if (metadata && metadata->HasObjectPtr()) {
lldb::LanguageType language = metadata->GetObjectPtrLanguage();
if (language == lldb::eLanguageTypeC_plus_plus) {
@@ -292,9 +292,9 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
return;
}
- if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
return;
- } else if (ClangASTContext::IsObjCObjectPointerType(
+ } else if (TypeSystemClang::IsObjCObjectPointerType(
self_clang_type)) {
m_in_objectivec_method = true;
m_needs_object_ptr = true;
@@ -347,50 +347,70 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man
return true;
}
-static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
- if (ClangModulesDeclVendor *decl_vendor =
- target->GetClangModulesDeclVendor()) {
- auto *persistent_state = llvm::cast<ClangPersistentVariables>(
- target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
- if (!persistent_state)
- return;
- const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
- persistent_state->GetHandLoadedClangModules();
- ClangModulesDeclVendor::ModuleVector modules_for_macros;
+static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
+ DiagnosticManager &diagnostic_manager) {
+ ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
+ if (!decl_vendor)
+ return;
- for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
- modules_for_macros.push_back(module);
- }
+ if (!target->GetEnableAutoImportClangModules())
+ return;
- if (target->GetEnableAutoImportClangModules()) {
- if (StackFrame *frame = exe_ctx.GetFramePtr()) {
- if (Block *block = frame->GetFrameBlock()) {
- SymbolContext sc;
+ auto *persistent_state = llvm::cast<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
+ if (!persistent_state)
+ return;
- block->CalculateSymbolContext(&sc);
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (!frame)
+ return;
- if (sc.comp_unit) {
- StreamString error_stream;
+ Block *block = frame->GetFrameBlock();
+ if (!block)
+ return;
+ SymbolContext sc;
- decl_vendor->AddModulesForCompileUnit(
- *sc.comp_unit, modules_for_macros, error_stream);
- }
- }
- }
- }
+ block->CalculateSymbolContext(&sc);
+
+ if (!sc.comp_unit)
+ return;
+ StreamString error_stream;
+
+ ClangModulesDeclVendor::ModuleVector modules_for_macros =
+ persistent_state->GetHandLoadedClangModules();
+ if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros,
+ error_stream))
+ return;
+
+ // Failed to load some modules, so emit the error stream as a diagnostic.
+ if (!error_stream.Empty()) {
+ // The error stream already contains several Clang diagnostics that might
+ // be either errors or warnings, so just print them all as one remark
+ // diagnostic to prevent that the message starts with "error: error:".
+ diagnostic_manager.PutString(eDiagnosticSeverityRemark,
+ error_stream.GetString());
+ return;
}
+
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "Unknown error while loading modules needed for "
+ "current compilation unit.");
}
-void ClangUserExpression::UpdateLanguageForExpr() {
- m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- return;
+ClangExpressionSourceCode::WrapKind ClangUserExpression::GetWrapKind() const {
+ assert(m_options.GetExecutionPolicy() != eExecutionPolicyTopLevel &&
+ "Top level expressions aren't wrapped.");
+ using Kind = ClangExpressionSourceCode::WrapKind;
if (m_in_cplusplus_method)
- m_expr_lang = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- m_expr_lang = lldb::eLanguageTypeObjC;
- else
- m_expr_lang = lldb::eLanguageTypeC;
+ return Kind::CppMemberFunction;
+ else if (m_in_objectivec_method) {
+ if (m_in_static_method)
+ return Kind::ObjCStaticMethod;
+ return Kind::ObjCInstanceMethod;
+ }
+ // Not in any kind of 'special' function, so just wrap it in a normal C
+ // function.
+ return Kind::Function;
}
void ClangUserExpression::CreateSourceCode(
@@ -404,10 +424,9 @@ void ClangUserExpression::CreateSourceCode(
m_transformed_text = m_expr_text;
} else {
m_source_code.reset(ClangExpressionSourceCode::CreateWrapped(
- m_filename, prefix.c_str(), m_expr_text.c_str()));
+ m_filename, prefix, m_expr_text, GetWrapKind()));
- if (!m_source_code->GetText(m_transformed_text, m_expr_lang,
- m_in_static_method, exe_ctx, !m_ctx_obj,
+ if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj,
for_completion, modules_to_import)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
@@ -419,7 +438,7 @@ void ClangUserExpression::CreateSourceCode(
std::size_t original_start;
std::size_t original_end;
bool found_bounds = m_source_code->GetOriginalBodyBounds(
- m_transformed_text, m_expr_lang, original_start, original_end);
+ m_transformed_text, original_start, original_end);
if (found_bounds)
m_user_expression_start_pos = original_start;
}
@@ -530,7 +549,7 @@ bool ClangUserExpression::PrepareForParsing(
ApplyObjcCastHack(m_expr_text);
- SetupDeclVendor(exe_ctx, m_target);
+ SetupDeclVendor(exe_ctx, m_target, diagnostic_manager);
CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
llvm::ArrayRef<std::string> imported_modules =
@@ -544,7 +563,6 @@ bool ClangUserExpression::PrepareForParsing(
llvm::make_range(m_include_directories.begin(),
m_include_directories.end()));
- UpdateLanguageForExpr();
CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules,
for_completion);
return true;
@@ -577,7 +595,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
// Parse the expression
//
- m_materializer_up.reset(new Materializer());
+ m_materializer_up = std::make_unique<Materializer>();
ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
@@ -616,15 +634,13 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (parser.RewriteExpression(diagnostic_manager)) {
size_t fixed_start;
size_t fixed_end;
- const std::string &fixed_expression =
- diagnostic_manager.GetFixedExpression();
+ m_fixed_text = diagnostic_manager.GetFixedExpression();
// Retrieve the original expression in case we don't have a top level
// expression (which has no surrounding source code).
- if (m_source_code &&
- m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang,
- fixed_start, fixed_end))
+ if (m_source_code && m_source_code->GetOriginalBodyBounds(
+ m_fixed_text, fixed_start, fixed_end))
m_fixed_text =
- fixed_expression.substr(fixed_start, fixed_end - fixed_start);
+ m_fixed_text.substr(fixed_start, fixed_end - fixed_start);
}
}
return false;
@@ -659,7 +675,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
const char *error_cstr = static_init_error.AsCString();
if (error_cstr && error_cstr[0])
diagnostic_manager.Printf(eDiagnosticSeverityError,
- "couldn't run static initializers: %s\n",
+ "%s\n",
error_cstr);
else
diagnostic_manager.PutString(eDiagnosticSeverityError,
@@ -767,7 +783,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
// Parse the expression
//
- m_materializer_up.reset(new Materializer());
+ m_materializer_up = std::make_unique<Materializer>();
ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
@@ -896,16 +912,23 @@ void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
Materializer::PersistentVariableDelegate &delegate,
bool keep_result_in_memory,
ValueObject *ctx_obj) {
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(
- keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(),
- exe_ctx.GetTargetRef().GetClangASTImporter(), ctx_obj));
+ std::shared_ptr<ClangASTImporter> ast_importer;
+ auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC);
+ if (state) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
+ ast_importer = persistent_vars->GetClangASTImporter();
+ }
+ m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
+ keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), ast_importer,
+ ctx_obj);
}
clang::ASTConsumer *
ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
clang::ASTConsumer *passthrough) {
- m_result_synthesizer_up.reset(
- new ASTResultSynthesizer(passthrough, m_top_level, m_target));
+ m_result_synthesizer_up = std::make_unique<ASTResultSynthesizer>(
+ passthrough, m_top_level, m_target);
return m_result_synthesizer_up.get();
}
@@ -917,9 +940,7 @@ void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
}
ConstString ClangUserExpression::ResultDelegate::GetName() {
- auto prefix = m_persistent_state->GetPersistentVariablePrefix();
- return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
- prefix);
+ return m_persistent_state->GetNextPersistentVariableName(false);
}
void ClangUserExpression::ResultDelegate::DidDematerialize(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 00cbffa7fd6f..f734069655ef 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUserExpression_h_
-#define liblldb_ClangUserExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
#include <vector>
@@ -20,7 +20,6 @@
#include "IRForTarget.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Target/ExecutionContext.h"
@@ -186,7 +185,8 @@ private:
ExecutionContext &exe_ctx,
std::vector<std::string> modules_to_import,
bool for_completion);
- void UpdateLanguageForExpr();
+ /// Defines how the current expression should be wrapped.
+ ClangExpressionSourceCode::WrapKind GetWrapKind() const;
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
ExecutionContext &exe_ctx);
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
@@ -209,8 +209,6 @@ private:
lldb::TargetSP m_target_sp;
};
- /// The language type of the current expression.
- lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown;
/// The include directories that should be used when parsing the expression.
std::vector<std::string> m_include_directories;
@@ -251,4 +249,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangUserExpression_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
new file mode 100644
index 000000000000..a7f5dce8558f
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
@@ -0,0 +1,87 @@
+//===-- ClangUtil.cpp -----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+bool ClangUtil::IsClangType(const CompilerType &ct) {
+ // Invalid types are never Clang types.
+ if (!ct)
+ return false;
+
+ if (llvm::dyn_cast_or_null<TypeSystemClang>(ct.GetTypeSystem()) == nullptr)
+ return false;
+
+ if (!ct.GetOpaqueQualType())
+ return false;
+
+ return true;
+}
+
+clang::Decl *ClangUtil::GetDecl(const CompilerDecl &decl) {
+ assert(llvm::isa<TypeSystemClang>(decl.GetTypeSystem()));
+ return static_cast<clang::Decl *>(decl.GetOpaqueDecl());
+}
+
+QualType ClangUtil::GetQualType(const CompilerType &ct) {
+ // Make sure we have a clang type before making a clang::QualType
+ if (!IsClangType(ct))
+ return QualType();
+
+ return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+QualType ClangUtil::GetCanonicalQualType(const CompilerType &ct) {
+ if (!IsClangType(ct))
+ return QualType();
+
+ return GetQualType(ct).getCanonicalType();
+}
+
+CompilerType ClangUtil::RemoveFastQualifiers(const CompilerType &ct) {
+ if (!IsClangType(ct))
+ return ct;
+
+ QualType qual_type(GetQualType(ct));
+ qual_type.removeLocalFastQualifiers();
+ return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+}
+
+clang::TagDecl *ClangUtil::GetAsTagDecl(const CompilerType &type) {
+ clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
+ if (qual_type.isNull())
+ return nullptr;
+
+ return qual_type->getAsTagDecl();
+}
+
+std::string ClangUtil::DumpDecl(const clang::Decl *d) {
+ if (!d)
+ return "nullptr";
+
+ std::string result;
+ llvm::raw_string_ostream stream(result);
+ bool deserialize = false;
+ d->dump(stream, deserialize);
+
+ stream.flush();
+ return result;
+}
+
+std::string ClangUtil::ToString(const clang::Type *t) {
+ return clang::QualType(t, 0).getAsString();
+}
+
+std::string ClangUtil::ToString(const CompilerType &c) {
+ return ClangUtil::GetQualType(c).getAsString();
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h
new file mode 100644
index 000000000000..50cae42bc7c2
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h
@@ -0,0 +1,50 @@
+//===-- ClangUtil.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Type.h"
+
+#include "lldb/Symbol/CompilerType.h"
+
+namespace clang {
+class TagDecl;
+}
+
+namespace lldb_private {
+struct ClangUtil {
+ static bool IsClangType(const CompilerType &ct);
+
+ /// Returns the clang::Decl of the given CompilerDecl.
+ /// CompilerDecl has to be valid and represent a clang::Decl.
+ static clang::Decl *GetDecl(const CompilerDecl &decl);
+
+ static clang::QualType GetQualType(const CompilerType &ct);
+
+ static clang::QualType GetCanonicalQualType(const CompilerType &ct);
+
+ static CompilerType RemoveFastQualifiers(const CompilerType &ct);
+
+ static clang::TagDecl *GetAsTagDecl(const CompilerType &type);
+
+ /// Returns a textual representation of the given Decl's AST. Does not
+ /// deserialize any child nodes.
+ static std::string DumpDecl(const clang::Decl *d);
+ /// Returns a textual representation of the given type.
+ static std::string ToString(const clang::Type *t);
+ /// Returns a textual representation of the given CompilerType (assuming
+ /// its underlying type is a Clang type).
+ static std::string ToString(const CompilerType &c);
+};
+}
+
+#endif
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 199e4898e118..25ec982220a0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -1,4 +1,4 @@
-//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
+//===-- ClangUtilityFunction.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -12,6 +12,7 @@
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
#include "ClangExpressionSourceCode.h"
+#include "ClangPersistentVariables.h"
#include <stdio.h>
#if HAVE_SYS_TYPES_H
@@ -159,7 +160,14 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
ExecutionContext &exe_ctx, bool keep_result_in_memory) {
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(
- keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(),
- exe_ctx.GetTargetRef().GetClangASTImporter(), nullptr));
+ std::shared_ptr<ClangASTImporter> ast_importer;
+ auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC);
+ if (state) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
+ ast_importer = persistent_vars->GetClangASTImporter();
+ }
+ m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
+ keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), ast_importer,
+ nullptr);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 9efaa0254c3e..1f2dd5fdbecc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUtilityFunction_h_
-#define liblldb_ClangUtilityFunction_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
#include <map>
#include <string>
@@ -15,7 +15,6 @@
#include "ClangExpressionHelper.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
@@ -107,4 +106,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangUtilityFunction_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index 51ae73285b53..f1272c67d20f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -73,7 +73,7 @@ CppModuleConfiguration::CppModuleConfiguration(
llvm::SmallString<256> resource_dir;
llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(),
"include");
- m_resource_inc = resource_dir.str();
+ m_resource_inc = std::string(resource_dir.str());
// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index 8e892e37d0de..235ac2bd090c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CppModuleConfiguration_h_
-#define liblldb_CppModuleConfiguration_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H
#include <lldb/Core/FileSpecList.h>
#include <llvm/Support/Regex.h>
@@ -56,7 +56,7 @@ class CppModuleConfiguration {
bool analyzeFile(const FileSpec &f);
public:
- /// Creates a configuraiton by analyzing the given list of used source files.
+ /// Creates a configuration by analyzing the given list of used source files.
///
/// Currently only looks at the used paths and doesn't actually access the
/// files on the disk.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
new file mode 100644
index 000000000000..2f8cf1846ee7
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -0,0 +1,289 @@
+//===-- CxxModuleHandler.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include "lldb/Utility/Log.h"
+#include "clang/Sema/Lookup.h"
+#include "llvm/Support/Error.h"
+
+using namespace lldb_private;
+using namespace clang;
+
+CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
+ : m_importer(&importer),
+ m_sema(TypeSystemClang::GetASTContext(target)->getSema()) {
+
+ std::initializer_list<const char *> supported_names = {
+ // containers
+ "deque",
+ "forward_list",
+ "list",
+ "queue",
+ "stack",
+ "vector",
+ // pointers
+ "shared_ptr",
+ "unique_ptr",
+ "weak_ptr",
+ // utility
+ "allocator",
+ };
+ m_supported_templates.insert(supported_names.begin(), supported_names.end());
+}
+
+/// Builds a list of scopes that point into the given context.
+///
+/// \param sema The sema that will be using the scopes.
+/// \param ctxt The context that the scope should look into.
+/// \param result A list of scopes. The scopes need to be freed by the caller
+/// (except the TUScope which is owned by the sema).
+static void makeScopes(Sema &sema, DeclContext *ctxt,
+ std::vector<Scope *> &result) {
+ // FIXME: The result should be a list of unique_ptrs, but the TUScope makes
+ // this currently impossible as it's owned by the Sema.
+
+ if (auto parent = ctxt->getParent()) {
+ makeScopes(sema, parent, result);
+
+ Scope *scope =
+ new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics());
+ scope->setEntity(ctxt);
+ result.push_back(scope);
+ } else
+ result.push_back(sema.TUScope);
+}
+
+/// Uses the Sema to look up the given name in the given DeclContext.
+static std::unique_ptr<LookupResult>
+emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) {
+ IdentifierInfo &ident = sema.getASTContext().Idents.get(name);
+
+ std::unique_ptr<LookupResult> lookup_result;
+ lookup_result = std::make_unique<LookupResult>(sema, DeclarationName(&ident),
+ SourceLocation(),
+ Sema::LookupOrdinaryName);
+
+ // Usually during parsing we already encountered the scopes we would use. But
+ // here don't have these scopes so we have to emulate the behavior of the
+ // Sema during parsing.
+ std::vector<Scope *> scopes;
+ makeScopes(sema, ctxt, scopes);
+
+ // Now actually perform the lookup with the sema.
+ sema.LookupName(*lookup_result, scopes.back());
+
+ // Delete all the allocated scopes beside the translation unit scope (which
+ // has depth 0).
+ for (Scope *s : scopes)
+ if (s->getDepth() != 0)
+ delete s;
+
+ return lookup_result;
+}
+
+/// Error class for handling problems when finding a certain DeclContext.
+struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> {
+
+ static char ID;
+
+ MissingDeclContext(DeclContext *context, std::string error)
+ : m_context(context), m_error(error) {}
+
+ DeclContext *m_context;
+ std::string m_error;
+
+ void log(llvm::raw_ostream &OS) const override {
+ OS << llvm::formatv("error when reconstructing context of kind {0}:{1}",
+ m_context->getDeclKindName(), m_error);
+ }
+
+ std::error_code convertToErrorCode() const override {
+ return llvm::inconvertibleErrorCode();
+ }
+};
+
+char MissingDeclContext::ID = 0;
+
+/// Given a foreign decl context, this function finds the equivalent local
+/// decl context in the ASTContext of the given Sema. Potentially deserializes
+/// decls from the 'std' module if necessary.
+static llvm::Expected<DeclContext *>
+getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) {
+
+ // Inline namespaces don't matter for lookups, so let's skip them.
+ while (foreign_ctxt && foreign_ctxt->isInlineNamespace())
+ foreign_ctxt = foreign_ctxt->getParent();
+
+ // If the foreign context is the TU, we just return the local TU.
+ if (foreign_ctxt->isTranslationUnit())
+ return sema.getASTContext().getTranslationUnitDecl();
+
+ // Recursively find/build the parent DeclContext.
+ llvm::Expected<DeclContext *> parent =
+ getEqualLocalDeclContext(sema, foreign_ctxt->getParent());
+ if (!parent)
+ return parent;
+
+ // We currently only support building namespaces.
+ if (foreign_ctxt->isNamespace()) {
+ NamedDecl *ns = llvm::dyn_cast<NamedDecl>(foreign_ctxt);
+ llvm::StringRef ns_name = ns->getName();
+
+ auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent);
+ for (NamedDecl *named_decl : *lookup_result) {
+ if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl))
+ return DC->getPrimaryContext();
+ }
+ return llvm::make_error<MissingDeclContext>(
+ foreign_ctxt,
+ "Couldn't find namespace " + ns->getQualifiedNameAsString());
+ }
+
+ return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context ");
+}
+
+/// Returns true iff tryInstantiateStdTemplate supports instantiating a template
+/// with the given template arguments.
+static bool templateArgsAreSupported(ArrayRef<TemplateArgument> a) {
+ for (const TemplateArgument &arg : a) {
+ switch (arg.getKind()) {
+ case TemplateArgument::Type:
+ case TemplateArgument::Integral:
+ break;
+ default:
+ // TemplateArgument kind hasn't been handled yet.
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Constructor function for Clang declarations. Ensures that the created
+/// declaration is registered with the ASTImporter.
+template <typename T, typename... Args>
+T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) {
+ T *to_d = T::Create(std::forward<Args>(args)...);
+ importer.RegisterImportedDecl(from_d, to_d);
+ return to_d;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ // If we don't have a template to instiantiate, then there is nothing to do.
+ auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
+ if (!td)
+ return {};
+
+ // We only care about templates in the std namespace.
+ if (!td->getDeclContext()->isStdNamespace())
+ return {};
+
+ // We have a list of supported template names.
+ if (m_supported_templates.find(td->getName()) == m_supported_templates.end())
+ return {};
+
+ // Early check if we even support instantiating this template. We do this
+ // before we import anything into the target AST.
+ auto &foreign_args = td->getTemplateInstantiationArgs();
+ if (!templateArgsAreSupported(foreign_args.asArray()))
+ return {};
+
+ // Find the local DeclContext that corresponds to the DeclContext of our
+ // decl we want to import.
+ llvm::Expected<DeclContext *> to_context =
+ getEqualLocalDeclContext(*m_sema, td->getDeclContext());
+ if (!to_context) {
+ LLDB_LOG_ERROR(log, to_context.takeError(),
+ "Got error while searching equal local DeclContext for decl "
+ "'{1}':\n{0}",
+ td->getName());
+ return {};
+ }
+
+ // Look up the template in our local context.
+ std::unique_ptr<LookupResult> lookup =
+ emulateLookupInCtxt(*m_sema, td->getName(), *to_context);
+
+ ClassTemplateDecl *new_class_template = nullptr;
+ for (auto LD : *lookup) {
+ if ((new_class_template = dyn_cast<ClassTemplateDecl>(LD)))
+ break;
+ }
+ if (!new_class_template)
+ return {};
+
+ // Import the foreign template arguments.
+ llvm::SmallVector<TemplateArgument, 4> imported_args;
+
+ // If this logic is changed, also update templateArgsAreSupported.
+ for (const TemplateArgument &arg : foreign_args.asArray()) {
+ switch (arg.getKind()) {
+ case TemplateArgument::Type: {
+ llvm::Expected<QualType> type = m_importer->Import(arg.getAsType());
+ if (!type) {
+ LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
+ return {};
+ }
+ imported_args.push_back(TemplateArgument(*type));
+ break;
+ }
+ case TemplateArgument::Integral: {
+ llvm::APSInt integral = arg.getAsIntegral();
+ llvm::Expected<QualType> type =
+ m_importer->Import(arg.getIntegralType());
+ if (!type) {
+ LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
+ return {};
+ }
+ imported_args.push_back(
+ TemplateArgument(d->getASTContext(), integral, *type));
+ break;
+ }
+ default:
+ assert(false && "templateArgsAreSupported not updated?");
+ }
+ }
+
+ // Find the class template specialization declaration that
+ // corresponds to these arguments.
+ void *InsertPos = nullptr;
+ ClassTemplateSpecializationDecl *result =
+ new_class_template->findSpecialization(imported_args, InsertPos);
+
+ if (result) {
+ // We found an existing specialization in the module that fits our arguments
+ // so we can treat it as the result and register it with the ASTImporter.
+ m_importer->RegisterImportedDecl(d, result);
+ return result;
+ }
+
+ // Instantiate the template.
+ result = createDecl<ClassTemplateSpecializationDecl>(
+ *m_importer, d, m_sema->getASTContext(),
+ new_class_template->getTemplatedDecl()->getTagKind(),
+ new_class_template->getDeclContext(),
+ new_class_template->getTemplatedDecl()->getLocation(),
+ new_class_template->getLocation(), new_class_template, imported_args,
+ nullptr);
+
+ new_class_template->AddSpecialization(result, InsertPos);
+ if (new_class_template->isOutOfLine())
+ result->setLexicalDeclContext(
+ new_class_template->getLexicalDeclContext());
+ return result;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::Import(Decl *d) {
+ if (!isValid())
+ return {};
+
+ return tryInstantiateStdTemplate(d);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h
new file mode 100644
index 000000000000..6490af7f8978
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h
@@ -0,0 +1,65 @@
+//===-- CxxModuleHandler.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace lldb_private {
+
+/// Handles importing decls into an ASTContext with an attached C++ module.
+///
+/// This class searches a C++ module (which must be attached to the target
+/// ASTContext) for an equivalent decl to the one that should be imported.
+/// If the decl that is found in the module is a suitable replacement
+/// for the decl that should be imported, the module decl will be treated as
+/// the result of the import process.
+///
+/// If the Decl that should be imported is a template specialization
+/// that doesn't exist yet in the target ASTContext (e.g. `std::vector<int>`),
+/// then this class tries to create the template specialization in the target
+/// ASTContext. This is only possible if the CxxModuleHandler can determine
+/// that instantiating this template is safe to do, e.g. because the target
+/// decl is a container class from the STL.
+class CxxModuleHandler {
+ /// The ASTImporter that should be used to import any Decls which aren't
+ /// directly handled by this class itself.
+ clang::ASTImporter *m_importer = nullptr;
+
+ /// The Sema instance of the target ASTContext.
+ clang::Sema *m_sema = nullptr;
+
+ /// List of template names this class currently supports. These are the
+ /// template names inside the 'std' namespace such as 'vector' or 'list'.
+ llvm::StringSet<> m_supported_templates;
+
+ /// Tries to manually instantiate the given foreign template in the target
+ /// context (designated by m_sema).
+ llvm::Optional<clang::Decl *> tryInstantiateStdTemplate(clang::Decl *d);
+
+public:
+ CxxModuleHandler() = default;
+ CxxModuleHandler(clang::ASTImporter &importer, clang::ASTContext *target);
+
+ /// Attempts to import the given decl into the target ASTContext by
+ /// deserializing it from the 'std' module. This function returns a Decl if a
+ /// Decl has been deserialized from the 'std' module. Otherwise this function
+ /// returns nothing.
+ llvm::Optional<clang::Decl *> Import(clang::Decl *d);
+
+ /// Returns true iff this instance is capable of importing any declarations
+ /// in the target ASTContext.
+ bool isValid() const { return m_sema != nullptr; }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index d5ffb9529f36..b92f00ec2b63 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -1,4 +1,4 @@
-//===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===//
+//===-- IRDynamicChecks.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -181,8 +181,8 @@ protected:
///
/// \param[in] inst
/// The instruction to be instrumented.
- void RegisterInstruction(llvm::Instruction &i) {
- m_to_instrument.push_back(&i);
+ void RegisterInstruction(llvm::Instruction &inst) {
+ m_to_instrument.push_back(&inst);
}
/// Determine whether a single instruction is interesting to instrument,
@@ -465,7 +465,7 @@ protected:
}
static llvm::Function *GetCalledFunction(llvm::CallInst *inst) {
- return GetFunction(inst->getCalledValue());
+ return GetFunction(inst->getCalledOperand());
}
bool InspectInstruction(llvm::Instruction &i) override {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
index 5b9c8007ab76..a4de527e4512 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_IRDynamicChecks_h_
-#define liblldb_IRDynamicChecks_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
#include "lldb/Expression/DynamicCheckerFunctions.h"
#include "lldb/lldb-types.h"
@@ -124,4 +124,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_IRDynamicChecks_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 103a7ee46f35..8511e554509a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -1,4 +1,4 @@
-//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
+//===-- IRForTarget.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,7 +9,9 @@
#include "IRForTarget.h"
#include "ClangExpressionDeclMap.h"
+#include "ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
@@ -27,8 +29,6 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -283,17 +283,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
m_result_type = lldb_private::TypeFromParser(
- element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(element_qual_type));
} else if (pointer_objcobjpointertype) {
clang::QualType element_qual_type =
clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
m_result_type = lldb_private::TypeFromParser(
- element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(element_qual_type));
} else {
LLDB_LOG(log, "Expected result to have pointer type, but it did not");
@@ -305,9 +301,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
}
} else {
m_result_type = lldb_private::TypeFromParser(
- result_var->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(result_var->getType()));
}
lldb::TargetSP target_sp(m_execution_unit.GetTarget());
@@ -433,7 +427,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
missing_weak);
if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
- log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
+ LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target");
m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
"constant string requires "
@@ -823,7 +817,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
if (!omvn_initializer_array->isString())
return false;
- std::string omvn_initializer_string = omvn_initializer_array->getAsString();
+ std::string omvn_initializer_string =
+ std::string(omvn_initializer_array->getAsString());
LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
omvn_initializer_string);
@@ -981,7 +976,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
if (!ocn_initializer_array->isString())
return false;
- std::string ocn_initializer_string = ocn_initializer_array->getAsString();
+ std::string ocn_initializer_string =
+ std::string(ocn_initializer_array->getAsString());
LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
ocn_initializer_string);
@@ -1092,8 +1088,7 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
lldb_private::TypeFromParser result_decl_type(
- decl->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(decl->getType()));
StringRef decl_name(decl->getName());
lldb_private::ConstString persistent_variable_name(decl_name.data(),
@@ -1125,7 +1120,9 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
// Now, since the variable is a pointer variable, we will drop in a load of
// that pointer variable.
- LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
+ LoadInst *persistent_load =
+ new LoadInst(persistent_global->getType()->getPointerElementType(),
+ persistent_global, "", alloc);
LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
PrintValue(persistent_load));
@@ -1223,10 +1220,8 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
if (value_decl == nullptr)
return false;
- lldb_private::CompilerType compiler_type(
- lldb_private::ClangASTContext::GetASTContext(
- &value_decl->getASTContext()),
- value_decl->getType().getAsOpaquePtr());
+ lldb_private::CompilerType compiler_type =
+ m_decl_map->GetTypeSystem()->GetType(value_decl->getType());
const Type *value_type = nullptr;
@@ -1400,7 +1395,7 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
if (func && func->getName() == "__cxa_atexit")
remove = true;
- llvm::Value *val = call->getCalledValue();
+ llvm::Value *val = call->getCalledOperand();
if (val && val->getName() == "__cxa_atexit")
remove = true;
@@ -1799,7 +1794,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
get_element_ptr, value->getType()->getPointerTo(), "",
entry_instruction);
- LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
+ LoadInst *load =
+ new LoadInst(bit_cast->getType()->getPointerElementType(),
+ bit_cast, "", entry_instruction);
return load;
} else {
@@ -1845,7 +1842,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
m_module = &llvm_module;
- m_target_data.reset(new DataLayout(m_module));
+ m_target_data = std::make_unique<DataLayout>(m_module);
m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
m_target_data->getPointerSizeInBits());
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index 262e8ee0c06c..ebfc0cae626c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -7,10 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_IRForTarget_h_
-#define liblldb_IRForTarget_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -38,6 +37,10 @@ class DataLayout;
class Value;
}
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
class ClangExpressionDeclMap;
class IRExecutionUnit;
@@ -506,4 +509,4 @@ private:
bool CompleteDataAllocation();
};
-#endif // liblldb_IRForTarget_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
index 7553860f2492..b7b6640c4810 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ModuleDependencyCollector_h_
-#define liblldb_ModuleDependencyCollector_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/StringRef.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
new file mode 100644
index 000000000000..c1f88889f1dc
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
@@ -0,0 +1,179 @@
+//===-- NameSearchContext.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NameSearchContext.h"
+#include "ClangUtil.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
+ assert(type && "Type for variable must be valid!");
+
+ if (!type.IsValid())
+ return nullptr;
+
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return nullptr;
+
+ IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
+
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ clang::NamedDecl *Decl = VarDecl::Create(
+ ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+ SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
+ m_decls.push_back(Decl);
+
+ return Decl;
+}
+
+clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
+ bool extern_c) {
+ assert(type && "Type for variable must be valid!");
+
+ if (!type.IsValid())
+ return nullptr;
+
+ if (m_function_types.count(type))
+ return nullptr;
+
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return nullptr;
+
+ m_function_types.insert(type);
+
+ QualType qual_type(ClangUtil::GetQualType(type));
+
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ const bool isInlineSpecified = false;
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
+
+ clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
+
+ if (extern_c) {
+ context = LinkageSpecDecl::Create(
+ ast, context, SourceLocation(), SourceLocation(),
+ clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
+ }
+
+ // Pass the identifier info for functions the decl_name is needed for
+ // operators
+ clang::DeclarationName decl_name =
+ m_decl_name.getNameKind() == DeclarationName::Identifier
+ ? m_decl_name.getAsIdentifierInfo()
+ : m_decl_name;
+
+ clang::FunctionDecl *func_decl = FunctionDecl::Create(
+ ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
+ nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
+ isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
+
+ // We have to do more than just synthesize the FunctionDecl. We have to
+ // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
+ // this, we raid the function's FunctionProtoType for types.
+
+ const FunctionProtoType *func_proto_type =
+ qual_type.getTypePtr()->getAs<FunctionProtoType>();
+
+ if (func_proto_type) {
+ unsigned NumArgs = func_proto_type->getNumParams();
+ unsigned ArgIndex;
+
+ SmallVector<ParmVarDecl *, 5> parm_var_decls;
+
+ for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
+ QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
+
+ parm_var_decls.push_back(
+ ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
+ SourceLocation(), SourceLocation(), nullptr,
+ arg_qual_type, nullptr, SC_Static, nullptr));
+ }
+
+ func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
+ } else {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
+ }
+
+ // If this is an operator (e.g. operator new or operator==), only insert the
+ // declaration we inferred from the symbol if we can provide the correct
+ // number of arguments. We shouldn't really inject random decl(s) for
+ // functions that are analyzed semantically in a special way, otherwise we
+ // will crash in clang.
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+ if (func_proto_type &&
+ TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
+ if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
+ false, op_kind, func_proto_type->getNumParams()))
+ return nullptr;
+ }
+ m_decls.push_back(func_decl);
+
+ return func_decl;
+}
+
+clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
+ FunctionProtoType::ExtProtoInfo proto_info;
+
+ proto_info.Variadic = true;
+
+ QualType generic_function_type(
+ GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
+ ArrayRef<QualType>(), // argument types
+ proto_info));
+
+ return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
+}
+
+clang::NamedDecl *
+NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
+ if (ClangUtil::IsClangType(clang_type)) {
+ QualType qual_type = ClangUtil::GetQualType(clang_type);
+
+ if (const TypedefType *typedef_type =
+ llvm::dyn_cast<TypedefType>(qual_type)) {
+ TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
+
+ m_decls.push_back(typedef_name_decl);
+
+ return (NamedDecl *)typedef_name_decl;
+ } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ m_decls.push_back(tag_decl);
+
+ return tag_decl;
+ } else if (const ObjCObjectType *objc_object_type =
+ qual_type->getAs<ObjCObjectType>()) {
+ ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
+
+ m_decls.push_back((NamedDecl *)interface_decl);
+
+ return (NamedDecl *)interface_decl;
+ }
+ }
+ return nullptr;
+}
+
+void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
+ for (clang::NamedDecl *decl : result)
+ m_decls.push_back(decl);
+}
+
+void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
+ m_decls.push_back(decl);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
new file mode 100644
index 000000000000..dc8621dd6aba
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
@@ -0,0 +1,124 @@
+//===-- NameSearchContext.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace lldb_private {
+
+/// \class NameSearchContext ClangASTSource.h
+/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
+/// single name lookup
+///
+/// LLDB needs to create Decls for entities it finds. This class communicates
+/// what name is being searched for and provides helper functions to construct
+/// Decls given appropriate type information.
+struct NameSearchContext {
+ /// The type system of the AST from which the lookup originated.
+ TypeSystemClang &m_clang_ts;
+ /// The list of declarations already constructed.
+ llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
+ /// The mapping of all namespaces found for this request back to their
+ /// modules.
+ ClangASTImporter::NamespaceMapSP m_namespace_map;
+ /// The name being looked for.
+ const clang::DeclarationName m_decl_name;
+ /// The DeclContext to put declarations into.
+ const clang::DeclContext *m_decl_context;
+ /// All the types of functions that have been reported, so we don't
+ /// report conflicts.
+ llvm::SmallSet<CompilerType, 5> m_function_types;
+
+ bool m_found_variable = false;
+ bool m_found_function_with_type_info = false;
+ bool m_found_function = false;
+ bool m_found_local_vars_nsp = false;
+ bool m_found_type = false;
+
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// \param[in] clang_ts
+ /// The TypeSystemClang from which the request originates.
+ ///
+ /// \param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// \param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// \param[in] dc
+ /// The DeclContext to register Decls in.
+ NameSearchContext(TypeSystemClang &clang_ts,
+ llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
+ clang::DeclarationName name, const clang::DeclContext *dc)
+ : m_clang_ts(clang_ts), m_decls(decls),
+ m_namespace_map(std::make_shared<ClangASTImporter::NamespaceMap>()),
+ m_decl_name(name), m_decl_context(dc) {
+ ;
+ }
+
+ /// Create a VarDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ clang::NamedDecl *AddVarDecl(const CompilerType &type);
+
+ /// Create a FunDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ ///
+ /// \param[in] extern_c
+ /// If true, build an extern "C" linkage specification for this.
+ clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
+
+ /// Create a FunDecl with the name being searched for and generic type (i.e.
+ /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
+ clang::NamedDecl *AddGenericFunDecl();
+
+ /// Create a TypeDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] compiler_type
+ /// The opaque QualType for the TypeDecl being registered.
+ clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
+
+ /// Add Decls from the provided DeclContextLookupResult to the list of
+ /// results.
+ ///
+ /// \param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ void AddLookupResult(clang::DeclContextLookupResult result);
+
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// \param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ void AddNamedDecl(clang::NamedDecl *decl);
+
+private:
+ clang::ASTContext &GetASTContext() const {
+ return m_clang_ts.getASTContext();
+ }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index ff142e6f35ff..555912780df9 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
+//===-- EmulateInstructionARM.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -30,6 +30,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM)
+
// Convenient macro definitions.
#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
@@ -603,9 +605,6 @@ static uint32_t CountITSize(uint32_t ITMask) {
// First count the trailing zeros of the IT mask.
uint32_t TZ = llvm::countTrailingZeros(ITMask);
if (TZ > 3) {
-#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT Mask '0000'\n");
-#endif
return 0;
}
return (4 - TZ);
@@ -620,15 +619,9 @@ bool ITSession::InitIT(uint32_t bits7_0) {
// A8.6.50 IT
unsigned short FirstCond = Bits32(bits7_0, 7, 4);
if (FirstCond == 0xF) {
-#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT FirstCond '1111'\n");
-#endif
return false;
}
if (FirstCond == 0xE && ITCounter != 1) {
-#ifdef LLDB_CONFIGURATION_DEBUG
- printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
-#endif
return false;
}
@@ -7230,7 +7223,7 @@ bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode,
return true;
}
-// LDRH (literal) caculates an address from the PC value and an immediate
+// LDRH (literal) calculates an address from the PC value and an immediate
// offset, loads a halfword from memory,
// zero-extends it to form a 32-bit word, and writes it to a register.
bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode,
@@ -8516,7 +8509,7 @@ bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode,
return true;
}
-// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and
+// UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and
// writes the result to the destination
// register. You can specify a rotation by 0, 8, 16, or 24 bits before
// extracting the 8-bit value.
@@ -14368,7 +14361,7 @@ bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
if (!success)
return false;
- if (auto_advance_pc && (after_pc_value == orig_pc_value)) {
+ if (after_pc_value == orig_pc_value) {
after_pc_value += m_opcode.GetByteSize();
EmulateInstruction::Context context;
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index 13d7fc061bea..d15d80c97e38 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_EmulateInstructionARM_h_
-#define lldb_EmulateInstructionARM_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H
#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
@@ -783,4 +783,4 @@ protected:
} // namespace lldb_private
-#endif // lldb_EmulateInstructionARM_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATEINSTRUCTIONARM_H
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 11c7677c201a..aef08baa8ae9 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -1,4 +1,4 @@
-//===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===//
+//===-- EmulationStateARM.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
index e5af37a21504..955c7c642058 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_EmulationStateARM_h_
-#define lldb_EmulationStateARM_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H
#include <map>
@@ -73,7 +73,8 @@ private:
// uint32_t to a data buffer heap
// type.
- DISALLOW_COPY_AND_ASSIGN(EmulationStateARM);
+ EmulationStateARM(const EmulationStateARM &) = delete;
+ const EmulationStateARM &operator=(const EmulationStateARM &) = delete;
};
-#endif // lldb_EmulationStateARM_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM_EMULATIONSTATEARM_H
diff --git a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index 3e06fca2504c..9b0c06bcccab 100644
--- a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionARM64.cpp ------------------------------*- C++-*-===//
+//===-- EmulateInstructionARM64.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,8 +8,6 @@
#include "EmulateInstructionARM64.h"
-#include <stdlib.h>
-
#include "lldb/Core/Address.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -18,10 +16,14 @@
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Stream.h"
+#include "llvm/Support/CheckedArithmetic.h"
+
#include "Plugins/Process/Utility/ARMDefines.h"
#include "Plugins/Process/Utility/ARMUtils.h"
#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
+#include <cstdlib>
+
#define GPR_OFFSET(idx) ((idx)*8)
#define GPR_OFFSET_NAME(reg) 0
#define FPU_OFFSET(idx) ((idx)*16)
@@ -47,6 +49,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM64, InstructionARM64)
+
static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le))
return false;
@@ -83,23 +87,6 @@ static inline uint64_t LSL(uint64_t x, integer shift) {
return x << shift;
}
-// AddWithCarry()
-// ===============
-static inline uint64_t
-AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
- EmulateInstructionARM64::ProcState &proc_state) {
- uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
- int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
- uint64_t result = unsigned_sum;
- if (N < 64)
- result = Bits64(result, N - 1, 0);
- proc_state.N = Bit64(result, N - 1);
- proc_state.Z = IsZero(result);
- proc_state.C = UInt(result) == unsigned_sum;
- proc_state.V = SInt(result) == signed_sum;
- return result;
-}
-
// ConstrainUnpredictable()
// ========================
@@ -415,20 +402,12 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) {
if (opcode_data == nullptr)
return false;
- // printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
const bool auto_advance_pc =
evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
m_ignore_conditions =
evaluate_options & eEmulateInstructionOptionIgnoreConditions;
bool success = false;
- // if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
- // {
- // m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindLLDB,
- // gpr_cpsr_arm64,
- // 0,
- // &success);
- // }
// Only return false if we are unable to read the CPSR if we care about
// conditions
@@ -454,7 +433,7 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) {
if (!success)
return false;
- if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
+ if (new_pc_value == orig_pc_value) {
EmulateInstruction::Context context;
context.type = eContextAdvancePC;
context.SetNoArgs();
@@ -588,6 +567,24 @@ bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) {
return result;
}
+uint64_t EmulateInstructionARM64::
+AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
+ EmulateInstructionARM64::ProcState &proc_state) {
+ uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
+ llvm::Optional<int64_t> signed_sum = llvm::checkedAdd(SInt(x), SInt(y));
+ bool overflow = !signed_sum;
+ if (!overflow)
+ overflow |= !llvm::checkedAdd(*signed_sum, SInt(carry_in));
+ uint64_t result = unsigned_sum;
+ if (N < 64)
+ result = Bits64(result, N - 1, 0);
+ proc_state.N = Bit64(result, N - 1);
+ proc_state.Z = IsZero(result);
+ proc_state.C = UInt(result) != unsigned_sum;
+ proc_state.V = overflow;
+ return result;
+}
+
bool EmulateInstructionARM64::EmulateADDSUBImm(const uint32_t opcode) {
// integer d = UInt(Rd);
// integer n = UInt(Rn);
@@ -783,10 +780,6 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) {
RegisterValue data_Rt;
RegisterValue data_Rt2;
-
- // if (vector)
- // CheckFPEnabled(false);
-
RegisterInfo reg_info_base;
RegisterInfo reg_info_Rt;
RegisterInfo reg_info_Rt2;
diff --git a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
index 03a57a2cf92b..11ad8a99b0fc 100644
--- a/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
+++ b/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EmulateInstructionARM64_h_
-#define EmulateInstructionARM64_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
@@ -152,6 +152,9 @@ public:
} ProcState;
protected:
+ static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in,
+ EmulateInstructionARM64::ProcState &proc_state);
+
typedef struct {
uint32_t mask;
uint32_t value;
@@ -189,4 +192,4 @@ protected:
bool m_ignore_conditions;
};
-#endif // EmulateInstructionARM64_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index b55eeb0eaf46..d4cb726fc7e5 100644
--- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++-*-===//
+//===-- EmulateInstructionMIPS.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -40,6 +40,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS, InstructionMIPS)
+
#define UInt(x) ((uint64_t)x)
#define integer int64_t
@@ -157,8 +159,8 @@ EmulateInstructionMIPS::EmulateInstructionMIPS(
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
assert(m_asm_info.get() && m_subtype_info.get());
- m_context.reset(
- new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
+ m_reg_info.get(), nullptr);
assert(m_context.get());
m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
index cd447ae4975e..61291c729879 100644
--- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
+++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EmulateInstructionMIPS_h_
-#define EmulateInstructionMIPS_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
namespace llvm {
class MCDisassembler;
@@ -203,7 +203,7 @@ protected:
bool nonvolatile_reg_p(uint32_t regnum);
- const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool alternate_name);
private:
std::unique_ptr<llvm::MCDisassembler> m_disasm;
@@ -218,4 +218,4 @@ private:
bool m_use_alt_disaasm;
};
-#endif // EmulateInstructionMIPS_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
diff --git a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 3baf942bc17f..4ccaf0de0758 100644
--- a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionMIPS64.cpp -----------------------------*- C++-*-===//
+//===-- EmulateInstructionMIPS64.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -40,6 +40,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionMIPS64, InstructionMIPS64)
+
#define UInt(x) ((uint64_t)x)
#define integer int64_t
@@ -161,8 +163,8 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64(
target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
assert(m_asm_info.get() && m_subtype_info.get());
- m_context.reset(
- new llvm::MCContext(m_asm_info.get(), m_reg_info.get(), nullptr));
+ m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
+ m_reg_info.get(), nullptr);
assert(m_context.get());
m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
diff --git a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
index 953a0935bd06..c4ae2296c5dd 100644
--- a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
+++ b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EmulateInstructionMIPS64_h_
-#define EmulateInstructionMIPS64_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
@@ -168,7 +168,7 @@ protected:
bool nonvolatile_reg_p(uint64_t regnum);
- const char *GetRegisterName(unsigned reg_num, bool altnernate_name);
+ const char *GetRegisterName(unsigned reg_num, bool alternate_name);
private:
std::unique_ptr<llvm::MCDisassembler> m_disasm;
@@ -179,4 +179,4 @@ private:
std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
};
-#endif // EmulateInstructionMIPS64_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS64_EMULATEINSTRUCTIONMIPS64_H
diff --git a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index 4b8d8dd2228c..5d97513c0be7 100644
--- a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstructionPPC64.cpp ------------------------------*- C++-*-===//
+//===-- EmulateInstructionPPC64.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,6 +25,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionPPC64, InstructionPPC64)
+
EmulateInstructionPPC64::EmulateInstructionPPC64(const ArchSpec &arch)
: EmulateInstruction(arch) {}
@@ -196,7 +198,7 @@ bool EmulateInstructionPPC64::EvaluateInstruction(uint32_t evaluate_options) {
if (!success)
return false;
- if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
+ if (new_pc_value == orig_pc_value) {
EmulateInstruction::Context context;
context.type = eContextAdvancePC;
context.SetNoArgs();
diff --git a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
index bf239770b933..02d2bce8f05e 100644
--- a/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
+++ b/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EmulateInstructionPPC64_h_
-#define EmulateInstructionPPC64_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
@@ -89,4 +89,4 @@ private:
} // namespace lldb_private
-#endif // EmulateInstructionPPC64_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_PPC64_EMULATEINSTRUCTIONPPC64_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
index 2e5dd5989e77..e78ea3a68483 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
@@ -1,4 +1,4 @@
-//===-- ASanRuntime.cpp -----------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeASan.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "ASanRuntime.h"
+#include "InstrumentationRuntimeASan.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
@@ -30,40 +30,42 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASan)
+
lldb::InstrumentationRuntimeSP
-AddressSanitizerRuntime::CreateInstance(const lldb::ProcessSP &process_sp) {
- return InstrumentationRuntimeSP(new AddressSanitizerRuntime(process_sp));
+InstrumentationRuntimeASan::CreateInstance(const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(new InstrumentationRuntimeASan(process_sp));
}
-void AddressSanitizerRuntime::Initialize() {
+void InstrumentationRuntimeASan::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), "AddressSanitizer instrumentation runtime plugin.",
CreateInstance, GetTypeStatic);
}
-void AddressSanitizerRuntime::Terminate() {
+void InstrumentationRuntimeASan::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString AddressSanitizerRuntime::GetPluginNameStatic() {
+lldb_private::ConstString InstrumentationRuntimeASan::GetPluginNameStatic() {
return ConstString("AddressSanitizer");
}
-lldb::InstrumentationRuntimeType AddressSanitizerRuntime::GetTypeStatic() {
+lldb::InstrumentationRuntimeType InstrumentationRuntimeASan::GetTypeStatic() {
return eInstrumentationRuntimeTypeAddressSanitizer;
}
-AddressSanitizerRuntime::~AddressSanitizerRuntime() { Deactivate(); }
+InstrumentationRuntimeASan::~InstrumentationRuntimeASan() { Deactivate(); }
const RegularExpression &
-AddressSanitizerRuntime::GetPatternForRuntimeLibrary() {
+InstrumentationRuntimeASan::GetPatternForRuntimeLibrary() {
// FIXME: This shouldn't include the "dylib" suffix.
static RegularExpression regex(
llvm::StringRef("libclang_rt.asan_(.*)_dynamic\\.dylib"));
return regex;
}
-bool AddressSanitizerRuntime::CheckIfRuntimeIsValid(
+bool InstrumentationRuntimeASan::CheckIfRuntimeIsValid(
const lldb::ModuleSP module_sp) {
const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny);
@@ -108,7 +110,7 @@ t.description = __asan_get_report_description();
t
)";
-StructuredData::ObjectSP AddressSanitizerRuntime::RetrieveReportData() {
+StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() {
ProcessSP process_sp = GetProcessSP();
if (!process_sp)
return StructuredData::ObjectSP();
@@ -189,11 +191,11 @@ StructuredData::ObjectSP AddressSanitizerRuntime::RetrieveReportData() {
}
std::string
-AddressSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) {
- std::string description = report->GetAsDictionary()
- ->GetValueForKey("description")
- ->GetAsString()
- ->GetValue();
+InstrumentationRuntimeASan::FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = std::string(report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue());
return llvm::StringSwitch<std::string>(description)
.Case("heap-use-after-free", "Use of deallocated memory")
.Case("heap-buffer-overflow", "Heap buffer overflow")
@@ -235,15 +237,15 @@ AddressSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) {
.Default("AddressSanitizer detected: " + description);
}
-bool AddressSanitizerRuntime::NotifyBreakpointHit(
+bool InstrumentationRuntimeASan::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
assert(baton && "null baton");
if (!baton)
return false;
- AddressSanitizerRuntime *const instance =
- static_cast<AddressSanitizerRuntime *>(baton);
+ InstrumentationRuntimeASan *const instance =
+ static_cast<InstrumentationRuntimeASan *>(baton);
ProcessSP process_sp = instance->GetProcessSP();
@@ -275,7 +277,7 @@ bool AddressSanitizerRuntime::NotifyBreakpointHit(
return false; // Let target run
}
-void AddressSanitizerRuntime::Activate() {
+void InstrumentationRuntimeASan::Activate() {
if (IsActive())
return;
@@ -305,7 +307,7 @@ void AddressSanitizerRuntime::Activate() {
process_sp->GetTarget()
.CreateBreakpoint(symbol_address, internal, hardware)
.get();
- breakpoint->SetCallback(AddressSanitizerRuntime::NotifyBreakpointHit, this,
+ breakpoint->SetCallback(InstrumentationRuntimeASan::NotifyBreakpointHit, this,
true);
breakpoint->SetBreakpointKind("address-sanitizer-report");
SetBreakpointID(breakpoint->GetID());
@@ -313,7 +315,7 @@ void AddressSanitizerRuntime::Activate() {
SetActive(true);
}
-void AddressSanitizerRuntime::Deactivate() {
+void InstrumentationRuntimeASan::Deactivate() {
if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
ProcessSP process_sp = GetProcessSP();
if (process_sp) {
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
index 0771e624ff6b..cde0a9613350 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h
+++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
@@ -1,4 +1,4 @@
-//===-- ASanRuntime.h -------------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeASan.h ----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AddressSanitizerRuntime_h_
-#define liblldb_AddressSanitizerRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/Process.h"
@@ -16,9 +16,9 @@
namespace lldb_private {
-class AddressSanitizerRuntime : public lldb_private::InstrumentationRuntime {
+class InstrumentationRuntimeASan : public lldb_private::InstrumentationRuntime {
public:
- ~AddressSanitizerRuntime() override;
+ ~InstrumentationRuntimeASan() override;
static lldb::InstrumentationRuntimeSP
CreateInstance(const lldb::ProcessSP &process_sp);
@@ -40,7 +40,7 @@ public:
uint32_t GetPluginVersion() override { return 1; }
private:
- AddressSanitizerRuntime(const lldb::ProcessSP &process_sp)
+ InstrumentationRuntimeASan(const lldb::ProcessSP &process_sp)
: lldb_private::InstrumentationRuntime(process_sp) {}
const RegularExpression &GetPatternForRuntimeLibrary() override;
@@ -63,4 +63,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AddressSanitizerRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
index b73b6c095368..72d28c347457 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -1,4 +1,4 @@
-//===-- MainThreadCheckerRuntime.cpp ----------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeMainThreadChecker.cpp -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#include "MainThreadCheckerRuntime.h"
+#include "InstrumentationRuntimeMainThreadChecker.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -22,47 +23,54 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegularExpression.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
#include <memory>
using namespace lldb;
using namespace lldb_private;
-MainThreadCheckerRuntime::~MainThreadCheckerRuntime() {
+LLDB_PLUGIN_DEFINE(InstrumentationRuntimeMainThreadChecker)
+
+InstrumentationRuntimeMainThreadChecker::
+ ~InstrumentationRuntimeMainThreadChecker() {
Deactivate();
}
lldb::InstrumentationRuntimeSP
-MainThreadCheckerRuntime::CreateInstance(const lldb::ProcessSP &process_sp) {
- return InstrumentationRuntimeSP(new MainThreadCheckerRuntime(process_sp));
+InstrumentationRuntimeMainThreadChecker::CreateInstance(
+ const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(
+ new InstrumentationRuntimeMainThreadChecker(process_sp));
}
-void MainThreadCheckerRuntime::Initialize() {
+void InstrumentationRuntimeMainThreadChecker::Initialize() {
PluginManager::RegisterPlugin(
- GetPluginNameStatic(), "MainThreadChecker instrumentation runtime plugin.",
- CreateInstance, GetTypeStatic);
+ GetPluginNameStatic(),
+ "MainThreadChecker instrumentation runtime plugin.", CreateInstance,
+ GetTypeStatic);
}
-void MainThreadCheckerRuntime::Terminate() {
+void InstrumentationRuntimeMainThreadChecker::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString MainThreadCheckerRuntime::GetPluginNameStatic() {
+lldb_private::ConstString
+InstrumentationRuntimeMainThreadChecker::GetPluginNameStatic() {
return ConstString("MainThreadChecker");
}
-lldb::InstrumentationRuntimeType MainThreadCheckerRuntime::GetTypeStatic() {
+lldb::InstrumentationRuntimeType
+InstrumentationRuntimeMainThreadChecker::GetTypeStatic() {
return eInstrumentationRuntimeTypeMainThreadChecker;
}
const RegularExpression &
-MainThreadCheckerRuntime::GetPatternForRuntimeLibrary() {
+InstrumentationRuntimeMainThreadChecker::GetPatternForRuntimeLibrary() {
static RegularExpression regex(llvm::StringRef("libMainThreadChecker.dylib"));
return regex;
}
-bool MainThreadCheckerRuntime::CheckIfRuntimeIsValid(
+bool InstrumentationRuntimeMainThreadChecker::CheckIfRuntimeIsValid(
const lldb::ModuleSP module_sp) {
static ConstString test_sym("__main_thread_checker_on_report");
const Symbol *symbol =
@@ -71,7 +79,8 @@ bool MainThreadCheckerRuntime::CheckIfRuntimeIsValid(
}
StructuredData::ObjectSP
-MainThreadCheckerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
+InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
+ ExecutionContextRef exe_ctx_ref) {
ProcessSP process_sp = GetProcessSP();
if (!process_sp)
return StructuredData::ObjectSP();
@@ -148,15 +157,15 @@ MainThreadCheckerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
return dict_sp;
}
-bool MainThreadCheckerRuntime::NotifyBreakpointHit(
+bool InstrumentationRuntimeMainThreadChecker::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
assert(baton && "null baton");
if (!baton)
return false; ///< false => resume execution.
- MainThreadCheckerRuntime *const instance =
- static_cast<MainThreadCheckerRuntime *>(baton);
+ InstrumentationRuntimeMainThreadChecker *const instance =
+ static_cast<InstrumentationRuntimeMainThreadChecker *>(baton);
ProcessSP process_sp = instance->GetProcessSP();
ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
@@ -171,10 +180,10 @@ bool MainThreadCheckerRuntime::NotifyBreakpointHit(
instance->RetrieveReportData(context->exe_ctx_ref);
if (report) {
- std::string description = report->GetAsDictionary()
- ->GetValueForKey("description")
- ->GetAsString()
- ->GetValue();
+ std::string description = std::string(report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue());
thread_sp->SetStopInfo(
InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
*thread_sp, description, report));
@@ -184,7 +193,7 @@ bool MainThreadCheckerRuntime::NotifyBreakpointHit(
return false;
}
-void MainThreadCheckerRuntime::Activate() {
+void InstrumentationRuntimeMainThreadChecker::Activate() {
if (IsActive())
return;
@@ -215,15 +224,15 @@ void MainThreadCheckerRuntime::Activate() {
.CreateBreakpoint(symbol_address, /*internal=*/true,
/*hardware=*/false)
.get();
- breakpoint->SetCallback(MainThreadCheckerRuntime::NotifyBreakpointHit, this,
- true);
+ breakpoint->SetCallback(
+ InstrumentationRuntimeMainThreadChecker::NotifyBreakpointHit, this, true);
breakpoint->SetBreakpointKind("main-thread-checker-report");
SetBreakpointID(breakpoint->GetID());
SetActive(true);
}
-void MainThreadCheckerRuntime::Deactivate() {
+void InstrumentationRuntimeMainThreadChecker::Deactivate() {
SetActive(false);
auto BID = GetBreakpointID();
@@ -237,7 +246,7 @@ void MainThreadCheckerRuntime::Deactivate() {
}
lldb::ThreadCollectionSP
-MainThreadCheckerRuntime::GetBacktracesFromExtendedStopInfo(
+InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
StructuredData::ObjectSP info) {
ThreadCollectionSP threads;
threads = std::make_shared<ThreadCollection>();
@@ -245,7 +254,7 @@ MainThreadCheckerRuntime::GetBacktracesFromExtendedStopInfo(
ProcessSP process_sp = GetProcessSP();
if (info->GetObjectForDotSeparatedPath("instrumentation_class")
- ->GetStringValue() != "MainThreadChecker")
+ ->GetStringValue() != "MainThreadChecker")
return threads;
std::vector<lldb::addr_t> PCs;
diff --git a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h
new file mode 100644
index 000000000000..1435ae8d367f
--- /dev/null
+++ b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h
@@ -0,0 +1,68 @@
+//===-- InstrumentationRuntimeMainThreadChecker.h----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H
+
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class InstrumentationRuntimeMainThreadChecker
+ : public lldb_private::InstrumentationRuntime {
+public:
+ ~InstrumentationRuntimeMainThreadChecker() override;
+
+ static lldb::InstrumentationRuntimeSP
+ CreateInstance(const lldb::ProcessSP &process_sp);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static lldb::InstrumentationRuntimeType GetTypeStatic();
+
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
+
+private:
+ InstrumentationRuntimeMainThreadChecker(const lldb::ProcessSP &process_sp)
+ : lldb_private::InstrumentationRuntime(process_sp) {}
+
+ const RegularExpression &GetPatternForRuntimeLibrary() override;
+
+ bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
+
+ void Activate() override;
+
+ void Deactivate();
+
+ static bool NotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_MAINTHREADCHECKER_INSTRUMENTATIONRUNTIMEMAINTHREADCHECKER_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h b/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h
deleted file mode 100644
index 1dcbc0f6bc89..000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- MainThreadCheckerRuntime.h ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_MainThreadCheckerRuntime_h_
-#define liblldb_MainThreadCheckerRuntime_h_
-
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/InstrumentationRuntime.h"
-#include "lldb/Utility/StructuredData.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
- class MainThreadCheckerRuntime : public lldb_private::InstrumentationRuntime {
- public:
- ~MainThreadCheckerRuntime() override;
-
- static lldb::InstrumentationRuntimeSP
- CreateInstance(const lldb::ProcessSP &process_sp);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static lldb::InstrumentationRuntimeType GetTypeStatic();
-
- lldb_private::ConstString GetPluginName() override {
- return GetPluginNameStatic();
- }
-
- virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
-
- uint32_t GetPluginVersion() override { return 1; }
-
- lldb::ThreadCollectionSP
- GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
-
- private:
- MainThreadCheckerRuntime(const lldb::ProcessSP &process_sp)
- : lldb_private::InstrumentationRuntime(process_sp) {}
-
- const RegularExpression &GetPatternForRuntimeLibrary() override;
-
- bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
-
- void Activate() override;
-
- void Deactivate();
-
- static bool NotifyBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- StructuredData::ObjectSP RetrieveReportData(ExecutionContextRef exe_ctx_ref);
- };
-
-} // namespace lldb_private
-
-#endif // liblldb_MainThreadCheckerRuntime_h_
diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
index 45a3aeeb204e..50f0faefa0f4 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
@@ -1,4 +1,4 @@
-//===-- TSanRuntime.cpp -----------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeTSan.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "TSanRuntime.h"
+#include "InstrumentationRuntimeTSan.h"
#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -35,30 +35,32 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(InstrumentationRuntimeTSan)
+
lldb::InstrumentationRuntimeSP
-ThreadSanitizerRuntime::CreateInstance(const lldb::ProcessSP &process_sp) {
- return InstrumentationRuntimeSP(new ThreadSanitizerRuntime(process_sp));
+InstrumentationRuntimeTSan::CreateInstance(const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(new InstrumentationRuntimeTSan(process_sp));
}
-void ThreadSanitizerRuntime::Initialize() {
+void InstrumentationRuntimeTSan::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), "ThreadSanitizer instrumentation runtime plugin.",
CreateInstance, GetTypeStatic);
}
-void ThreadSanitizerRuntime::Terminate() {
+void InstrumentationRuntimeTSan::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString ThreadSanitizerRuntime::GetPluginNameStatic() {
+lldb_private::ConstString InstrumentationRuntimeTSan::GetPluginNameStatic() {
return ConstString("ThreadSanitizer");
}
-lldb::InstrumentationRuntimeType ThreadSanitizerRuntime::GetTypeStatic() {
+lldb::InstrumentationRuntimeType InstrumentationRuntimeTSan::GetTypeStatic() {
return eInstrumentationRuntimeTypeThreadSanitizer;
}
-ThreadSanitizerRuntime::~ThreadSanitizerRuntime() { Deactivate(); }
+InstrumentationRuntimeTSan::~InstrumentationRuntimeTSan() { Deactivate(); }
const char *thread_sanitizer_retrieve_report_data_prefix = R"(
extern "C"
@@ -84,7 +86,7 @@ extern "C"
int *running, const char **name, int *parent_tid,
void **trace, unsigned long trace_size);
int __tsan_get_report_unique_tid(void *report, unsigned long idx, int *tid);
-
+
// TODO: dlsym won't work on Windows.
void *dlsym(void* handle, const char* symbol);
int (*ptr__tsan_get_report_loc_object_type)(void *report, unsigned long idx, const char **object_type);
@@ -97,15 +99,15 @@ struct data {
void *report;
const char *description;
int report_count;
-
+
void *sleep_trace[REPORT_TRACE_SIZE];
-
+
int stack_count;
struct {
int idx;
void *trace[REPORT_TRACE_SIZE];
} stacks[REPORT_ARRAY_SIZE];
-
+
int mop_count;
struct {
int idx;
@@ -116,7 +118,7 @@ struct data {
void *addr;
void *trace[REPORT_TRACE_SIZE];
} mops[REPORT_ARRAY_SIZE];
-
+
int loc_count;
struct {
int idx;
@@ -130,7 +132,7 @@ struct data {
void *trace[REPORT_TRACE_SIZE];
const char *object_type;
} locs[REPORT_ARRAY_SIZE];
-
+
int mutex_count;
struct {
int idx;
@@ -139,7 +141,7 @@ struct data {
int destroyed;
void *trace[REPORT_TRACE_SIZE];
} mutexes[REPORT_ARRAY_SIZE];
-
+
int thread_count;
struct {
int idx;
@@ -150,7 +152,7 @@ struct data {
int parent_tid;
void *trace[REPORT_TRACE_SIZE];
} threads[REPORT_ARRAY_SIZE];
-
+
int unique_tid_count;
struct {
int idx;
@@ -299,8 +301,8 @@ static user_id_t Renumber(uint64_t id,
return IT->second;
}
-StructuredData::ObjectSP
-ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
+StructuredData::ObjectSP InstrumentationRuntimeTSan::RetrieveReportData(
+ ExecutionContextRef exe_ctx_ref) {
ProcessSP process_sp = GetProcessSP();
if (!process_sp)
return StructuredData::ObjectSP();
@@ -486,11 +488,11 @@ ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
}
std::string
-ThreadSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report) {
- std::string description = report->GetAsDictionary()
- ->GetValueForKey("issue_type")
- ->GetAsString()
- ->GetValue();
+InstrumentationRuntimeTSan::FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = std::string(report->GetAsDictionary()
+ ->GetValueForKey("issue_type")
+ ->GetAsString()
+ ->GetValue());
if (description == "data-race") {
return "Data race";
@@ -536,7 +538,7 @@ static std::string Sprintf(const char *format, ...) {
va_start(args, format);
s.PrintfVarArg(format, args);
va_end(args);
- return s.GetString();
+ return std::string(s.GetString());
}
static std::string GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr) {
@@ -564,15 +566,14 @@ static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr,
if (!symbol)
return;
- ConstString sym_name = symbol->GetMangled().GetName(
- lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+ ConstString sym_name = symbol->GetMangled().GetName(Mangled::ePreferMangled);
ModuleSP module = symbol->CalculateSymbolContextModule();
if (!module)
return;
VariableList var_list;
- module->FindGlobalVariables(sym_name, nullptr, 1U, var_list);
+ module->FindGlobalVariables(sym_name, CompilerDeclContext(), 1U, var_list);
if (var_list.GetSize() < 1)
return;
@@ -580,7 +581,7 @@ static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr,
decl = var->GetDeclaration();
}
-addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc(
+addr_t InstrumentationRuntimeTSan::GetFirstNonInternalFramePc(
StructuredData::ObjectSP trace, bool skip_one_frame) {
ProcessSP process_sp = GetProcessSP();
ModuleSP runtime_module_sp = GetRuntimeModuleSP();
@@ -609,13 +610,13 @@ addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc(
}
std::string
-ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report) {
+InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
ProcessSP process_sp = GetProcessSP();
- std::string summary = report->GetAsDictionary()
- ->GetValueForKey("description")
- ->GetAsString()
- ->GetValue();
+ std::string summary = std::string(report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue());
bool skip_one_frame =
report->GetObjectForDotSeparatedPath("issue_type")->GetStringValue() ==
"external-race";
@@ -657,10 +658,10 @@ ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report) {
->GetValueForKey("locs")
->GetAsArray()
->GetItemAtIndex(0);
- std::string object_type = loc->GetAsDictionary()
- ->GetValueForKey("object_type")
- ->GetAsString()
- ->GetValue();
+ std::string object_type = std::string(loc->GetAsDictionary()
+ ->GetValueForKey("object_type")
+ ->GetAsString()
+ ->GetValue());
if (!object_type.empty()) {
summary = "Race on " + object_type + " object";
}
@@ -695,8 +696,8 @@ ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report) {
return summary;
}
-addr_t
-ThreadSanitizerRuntime::GetMainRacyAddress(StructuredData::ObjectSP report) {
+addr_t InstrumentationRuntimeTSan::GetMainRacyAddress(
+ StructuredData::ObjectSP report) {
addr_t result = (addr_t)-1;
report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
@@ -711,7 +712,7 @@ ThreadSanitizerRuntime::GetMainRacyAddress(StructuredData::ObjectSP report) {
return (result == (addr_t)-1) ? 0 : result;
}
-std::string ThreadSanitizerRuntime::GetLocationDescription(
+std::string InstrumentationRuntimeTSan::GetLocationDescription(
StructuredData::ObjectSP report, addr_t &global_addr,
std::string &global_name, std::string &filename, uint32_t &line) {
std::string result = "";
@@ -726,8 +727,8 @@ std::string ThreadSanitizerRuntime::GetLocationDescription(
->GetValueForKey("locs")
->GetAsArray()
->GetItemAtIndex(0);
- std::string type =
- loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ std::string type = std::string(
+ loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
if (type == "global") {
global_addr = loc->GetAsDictionary()
->GetValueForKey("address")
@@ -756,10 +757,10 @@ std::string ThreadSanitizerRuntime::GetLocationDescription(
->GetValueForKey("size")
->GetAsInteger()
->GetValue();
- std::string object_type = loc->GetAsDictionary()
- ->GetValueForKey("object_type")
- ->GetAsString()
- ->GetValue();
+ std::string object_type = std::string(loc->GetAsDictionary()
+ ->GetValueForKey("object_type")
+ ->GetAsString()
+ ->GetValue());
if (!object_type.empty()) {
result = Sprintf("Location is a %ld-byte %s object at 0x%llx", size,
object_type.c_str(), addr);
@@ -791,15 +792,15 @@ std::string ThreadSanitizerRuntime::GetLocationDescription(
return result;
}
-bool ThreadSanitizerRuntime::NotifyBreakpointHit(
+bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
assert(baton && "null baton");
if (!baton)
return false;
- ThreadSanitizerRuntime *const instance =
- static_cast<ThreadSanitizerRuntime *>(baton);
+ InstrumentationRuntimeTSan *const instance =
+ static_cast<InstrumentationRuntimeTSan *>(baton);
ProcessSP process_sp = instance->GetProcessSP();
@@ -873,12 +874,13 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit(
return false; // Let target run
}
-const RegularExpression &ThreadSanitizerRuntime::GetPatternForRuntimeLibrary() {
+const RegularExpression &
+InstrumentationRuntimeTSan::GetPatternForRuntimeLibrary() {
static RegularExpression regex(llvm::StringRef("libclang_rt.tsan_"));
return regex;
}
-bool ThreadSanitizerRuntime::CheckIfRuntimeIsValid(
+bool InstrumentationRuntimeTSan::CheckIfRuntimeIsValid(
const lldb::ModuleSP module_sp) {
static ConstString g_tsan_get_current_report("__tsan_get_current_report");
const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
@@ -886,7 +888,7 @@ bool ThreadSanitizerRuntime::CheckIfRuntimeIsValid(
return symbol != nullptr;
}
-void ThreadSanitizerRuntime::Activate() {
+void InstrumentationRuntimeTSan::Activate() {
if (IsActive())
return;
@@ -916,7 +918,7 @@ void ThreadSanitizerRuntime::Activate() {
process_sp->GetTarget()
.CreateBreakpoint(symbol_address, internal, hardware)
.get();
- breakpoint->SetCallback(ThreadSanitizerRuntime::NotifyBreakpointHit, this,
+ breakpoint->SetCallback(InstrumentationRuntimeTSan::NotifyBreakpointHit, this,
true);
breakpoint->SetBreakpointKind("thread-sanitizer-report");
SetBreakpointID(breakpoint->GetID());
@@ -924,7 +926,7 @@ void ThreadSanitizerRuntime::Activate() {
SetActive(true);
}
-void ThreadSanitizerRuntime::Deactivate() {
+void InstrumentationRuntimeTSan::Deactivate() {
if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
ProcessSP process_sp = GetProcessSP();
if (process_sp) {
@@ -977,8 +979,8 @@ static std::string GenerateThreadName(const std::string &path,
}
if (path == "locs") {
- std::string type =
- o->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ std::string type = std::string(
+ o->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
int thread_id =
o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
int fd =
@@ -1043,7 +1045,7 @@ static void AddThreadsForPath(const std::string &path,
}
lldb::ThreadCollectionSP
-ThreadSanitizerRuntime::GetBacktracesFromExtendedStopInfo(
+InstrumentationRuntimeTSan::GetBacktracesFromExtendedStopInfo(
StructuredData::ObjectSP info) {
ThreadCollectionSP threads;
threads = std::make_shared<ThreadCollection>();
diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h
index db8bb1db7996..35a878d90aff 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h
+++ b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h
@@ -1,4 +1,4 @@
-//===-- TSanRuntime.h -------------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeTSan.h ----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ThreadSanitizerRuntime_h_
-#define liblldb_ThreadSanitizerRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H
#include "lldb/Target/ABI.h"
#include "lldb/Target/InstrumentationRuntime.h"
@@ -16,9 +16,9 @@
namespace lldb_private {
-class ThreadSanitizerRuntime : public lldb_private::InstrumentationRuntime {
+class InstrumentationRuntimeTSan : public lldb_private::InstrumentationRuntime {
public:
- ~ThreadSanitizerRuntime() override;
+ ~InstrumentationRuntimeTSan() override;
static lldb::InstrumentationRuntimeSP
CreateInstance(const lldb::ProcessSP &process_sp);
@@ -43,7 +43,7 @@ public:
GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
private:
- ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp)
+ InstrumentationRuntimeTSan(const lldb::ProcessSP &process_sp)
: lldb_private::InstrumentationRuntime(process_sp) {}
const RegularExpression &GetPatternForRuntimeLibrary() override;
@@ -78,4 +78,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ThreadSanitizerRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_TSAN_INSTRUMENTATIONRUNTIMETSAN_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
index 137ecab224bc..b60eb53f3d4a 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -1,4 +1,4 @@
-//===-- UBSanRuntime.cpp ----------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeUBSan.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "UBSanRuntime.h"
+#include "InstrumentationRuntimeUBSan.h"
#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -36,35 +36,31 @@
using namespace lldb;
using namespace lldb_private;
-UndefinedBehaviorSanitizerRuntime::~UndefinedBehaviorSanitizerRuntime() {
- Deactivate();
-}
+LLDB_PLUGIN_DEFINE(InstrumentationRuntimeUBSan)
+
+InstrumentationRuntimeUBSan::~InstrumentationRuntimeUBSan() { Deactivate(); }
lldb::InstrumentationRuntimeSP
-UndefinedBehaviorSanitizerRuntime::CreateInstance(
- const lldb::ProcessSP &process_sp) {
- return InstrumentationRuntimeSP(
- new UndefinedBehaviorSanitizerRuntime(process_sp));
+InstrumentationRuntimeUBSan::CreateInstance(const lldb::ProcessSP &process_sp) {
+ return InstrumentationRuntimeSP(new InstrumentationRuntimeUBSan(process_sp));
}
-void UndefinedBehaviorSanitizerRuntime::Initialize() {
+void InstrumentationRuntimeUBSan::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(),
"UndefinedBehaviorSanitizer instrumentation runtime plugin.",
CreateInstance, GetTypeStatic);
}
-void UndefinedBehaviorSanitizerRuntime::Terminate() {
+void InstrumentationRuntimeUBSan::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
-lldb_private::ConstString
-UndefinedBehaviorSanitizerRuntime::GetPluginNameStatic() {
+lldb_private::ConstString InstrumentationRuntimeUBSan::GetPluginNameStatic() {
return ConstString("UndefinedBehaviorSanitizer");
}
-lldb::InstrumentationRuntimeType
-UndefinedBehaviorSanitizerRuntime::GetTypeStatic() {
+lldb::InstrumentationRuntimeType InstrumentationRuntimeUBSan::GetTypeStatic() {
return eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer;
}
@@ -110,7 +106,7 @@ static std::string RetrieveString(ValueObjectSP return_value_sp,
return str;
}
-StructuredData::ObjectSP UndefinedBehaviorSanitizerRuntime::RetrieveReportData(
+StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData(
ExecutionContextRef exe_ctx_ref) {
ProcessSP process_sp = GetProcessSP();
if (!process_sp)
@@ -187,9 +183,10 @@ StructuredData::ObjectSP UndefinedBehaviorSanitizerRuntime::RetrieveReportData(
static std::string GetStopReasonDescription(StructuredData::ObjectSP report) {
llvm::StringRef stop_reason_description_ref;
- report->GetAsDictionary()->GetValueForKeyAsString("description",
- stop_reason_description_ref);
- std::string stop_reason_description = stop_reason_description_ref;
+ report->GetAsDictionary()->GetValueForKeyAsString(
+ "description", stop_reason_description_ref);
+ std::string stop_reason_description =
+ std::string(stop_reason_description_ref);
if (!stop_reason_description.size()) {
stop_reason_description = "Undefined behavior detected";
@@ -202,15 +199,15 @@ static std::string GetStopReasonDescription(StructuredData::ObjectSP report) {
return stop_reason_description;
}
-bool UndefinedBehaviorSanitizerRuntime::NotifyBreakpointHit(
+bool InstrumentationRuntimeUBSan::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
assert(baton && "null baton");
if (!baton)
return false; ///< false => resume execution.
- UndefinedBehaviorSanitizerRuntime *const instance =
- static_cast<UndefinedBehaviorSanitizerRuntime *>(baton);
+ InstrumentationRuntimeUBSan *const instance =
+ static_cast<InstrumentationRuntimeUBSan *>(baton);
ProcessSP process_sp = instance->GetProcessSP();
ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
@@ -235,12 +232,12 @@ bool UndefinedBehaviorSanitizerRuntime::NotifyBreakpointHit(
}
const RegularExpression &
-UndefinedBehaviorSanitizerRuntime::GetPatternForRuntimeLibrary() {
+InstrumentationRuntimeUBSan::GetPatternForRuntimeLibrary() {
static RegularExpression regex(llvm::StringRef("libclang_rt\\.(a|t|ub)san_"));
return regex;
}
-bool UndefinedBehaviorSanitizerRuntime::CheckIfRuntimeIsValid(
+bool InstrumentationRuntimeUBSan::CheckIfRuntimeIsValid(
const lldb::ModuleSP module_sp) {
static ConstString ubsan_test_sym("__ubsan_on_report");
const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
@@ -249,7 +246,7 @@ bool UndefinedBehaviorSanitizerRuntime::CheckIfRuntimeIsValid(
}
// FIXME: Factor out all the logic we have in common with the {a,t}san plugins.
-void UndefinedBehaviorSanitizerRuntime::Activate() {
+void InstrumentationRuntimeUBSan::Activate() {
if (IsActive())
return;
@@ -280,15 +277,15 @@ void UndefinedBehaviorSanitizerRuntime::Activate() {
.CreateBreakpoint(symbol_address, /*internal=*/true,
/*hardware=*/false)
.get();
- breakpoint->SetCallback(
- UndefinedBehaviorSanitizerRuntime::NotifyBreakpointHit, this, true);
+ breakpoint->SetCallback(InstrumentationRuntimeUBSan::NotifyBreakpointHit,
+ this, true);
breakpoint->SetBreakpointKind("undefined-behavior-sanitizer-report");
SetBreakpointID(breakpoint->GetID());
SetActive(true);
}
-void UndefinedBehaviorSanitizerRuntime::Deactivate() {
+void InstrumentationRuntimeUBSan::Deactivate() {
SetActive(false);
auto BID = GetBreakpointID();
@@ -302,7 +299,7 @@ void UndefinedBehaviorSanitizerRuntime::Deactivate() {
}
lldb::ThreadCollectionSP
-UndefinedBehaviorSanitizerRuntime::GetBacktracesFromExtendedStopInfo(
+InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
StructuredData::ObjectSP info) {
ThreadCollectionSP threads;
threads = std::make_shared<ThreadCollection>();
diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h
index 1d854b7bf06f..813c30069600 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h
+++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h
@@ -1,4 +1,4 @@
-//===-- UBSanRuntime.h ------------------------------------------*- C++ -*-===//
+//===-- InstrumentationRuntimeUBSan.h ---------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_UndefinedBehaviorSanitizerRuntime_h_
-#define liblldb_UndefinedBehaviorSanitizerRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H
+#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H
#include "lldb/Target/ABI.h"
#include "lldb/Target/InstrumentationRuntime.h"
@@ -16,10 +16,10 @@
namespace lldb_private {
-class UndefinedBehaviorSanitizerRuntime
+class InstrumentationRuntimeUBSan
: public lldb_private::InstrumentationRuntime {
public:
- ~UndefinedBehaviorSanitizerRuntime() override;
+ ~InstrumentationRuntimeUBSan() override;
static lldb::InstrumentationRuntimeSP
CreateInstance(const lldb::ProcessSP &process_sp);
@@ -44,7 +44,7 @@ public:
GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
private:
- UndefinedBehaviorSanitizerRuntime(const lldb::ProcessSP &process_sp)
+ InstrumentationRuntimeUBSan(const lldb::ProcessSP &process_sp)
: lldb_private::InstrumentationRuntime(process_sp) {}
const RegularExpression &GetPatternForRuntimeLibrary() override;
@@ -65,4 +65,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_UndefinedBehaviorSanitizerRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UBSAN_INSTRUMENTATIONRUNTIMEUBSAN_H
diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index fff44123539f..cbeef600ba9b 100644
--- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -1,4 +1,4 @@
-//===-- JITLoaderGDB.cpp ----------------------------------------*- C++ -*-===//
+//===-- JITLoaderGDB.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,6 +32,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(JITLoaderGDB)
+
// Debug Interface Structures
enum jit_actions_t { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
@@ -132,9 +134,9 @@ bool ReadJITEntry(const addr_t from_addr, Process *process,
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
process->GetByteOrder(), sizeof(ptr_t));
lldb::offset_t offset = 0;
- entry->next_entry = extractor.GetPointer(&offset);
- entry->prev_entry = extractor.GetPointer(&offset);
- entry->symfile_addr = extractor.GetPointer(&offset);
+ entry->next_entry = extractor.GetAddress(&offset);
+ entry->prev_entry = extractor.GetAddress(&offset);
+ entry->symfile_addr = extractor.GetAddress(&offset);
offset = llvm::alignTo(offset, uint64_align_bytes);
entry->symfile_size = extractor.GetU64(&offset);
diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
index 2a2537c3edd4..42377f435293 100644
--- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
+++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_JITLoaderGDB_h_
-#define liblldb_JITLoaderGDB_h_
+#ifndef LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H
+#define LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H
#include <map>
@@ -77,4 +77,4 @@ private:
lldb::addr_t m_jit_descriptor_addr;
};
-#endif // liblldb_JITLoaderGDB_h_
+#endif // LLDB_SOURCE_PLUGINS_JITLOADER_GDB_JITLOADERGDB_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 5cfd978774fd..42f6bd9ffb7b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -1,4 +1,4 @@
-//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===//
+//===-- BlockPointer.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,14 +8,14 @@
#include "BlockPointer.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
-
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
@@ -45,18 +45,24 @@ public:
if (auto err = type_system_or_err.takeError()) {
LLDB_LOG_ERROR(
lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
- std::move(err), "Failed to get scratch ClangASTContext");
+ std::move(err), "Failed to get scratch TypeSystemClang");
return;
}
- ClangASTContext *clang_ast_context =
- llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_context =
+ llvm::dyn_cast<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_context) {
return;
}
- ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
+ std::shared_ptr<ClangASTImporter> clang_ast_importer;
+ auto *state = target_sp->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC_plus_plus);
+ if (state) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
+ clang_ast_importer = persistent_vars->GetClangASTImporter();
+ }
if (!clang_ast_importer) {
return;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h
index 624c17a6a6af..23f3f7b34b4f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_BlockPointer_h_
-#define liblldb_BlockPointer_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H
#include "lldb/lldb-forward.h"
@@ -22,4 +22,4 @@ BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_BlockPointer_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 4385a60f5862..08e43ae6b3e8 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1,4 +1,4 @@
-//===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===//
+//===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -43,6 +43,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
+
void CPlusPlusLanguage::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
CreateInstance);
@@ -68,7 +70,9 @@ uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }
// Static Functions
Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
- if (Language::LanguageIsCPlusPlus(language))
+ // Use plugin for C++ but not for Objective-C++ (which has its own plugin).
+ if (Language::LanguageIsCPlusPlus(language) &&
+ language != eLanguageTypeObjC_plus_plus)
return new CPlusPlusLanguage();
return nullptr;
}
@@ -125,7 +129,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) {
return false; // Empty string or "~"
if (!std::isalpha(basename[idx]) && basename[idx] != '_')
- return false; // First charater (after removing the possible '~'') isn't in
+ return false; // First character (after removing the possible '~'') isn't in
// [A-Za-z_]
// Read all characters matching [A-Za-z_0-9]
@@ -230,7 +234,7 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
if (!m_parsed)
Parse();
if (m_context.empty())
- return m_basename;
+ return std::string(m_basename);
std::string res;
res += m_context;
@@ -609,6 +613,15 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"shared_ptr synthetic children",
ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
stl_synth_flags, true);
+
+ ConstString libcxx_std_unique_ptr_regex(
+ "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$");
+ AddCXXSynthetic(
+ cpp_category_sp,
+ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
+ "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
+ stl_synth_flags, true);
+
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
@@ -713,6 +726,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::weak_ptr summary provider",
ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
+ "libc++ std::unique_ptr summary provider",
+ libcxx_std_unique_ptr_regex, stl_summary_flags, true);
AddCXXSynthetic(
cpp_category_sp,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 4ed45bc904ce..89dea08a2c53 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CPlusPlusLanguage_h_
-#define liblldb_CPlusPlusLanguage_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H
#include <set>
#include <vector>
@@ -133,4 +133,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_CPlusPlusLanguage_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
index 932db17b964a..eca36fff18f8 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
@@ -1,4 +1,4 @@
-//===-- CPlusPlusNameParser.cpp ---------------------------------*- C++ -*-===//
+//===-- CPlusPlusNameParser.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -329,6 +329,37 @@ bool CPlusPlusNameParser::ConsumeOperator() {
}
const auto &token = Peek();
+
+ // When clang generates debug info it adds template parameters to names.
+ // Since clang doesn't add a space between the name and the template parameter
+ // in some cases we are not generating valid C++ names e.g.:
+ //
+ // operator<<A::B>
+ //
+ // In some of these cases we will not parse them correctly. This fixes the
+ // issue by detecting this case and inserting tok::less in place of
+ // tok::lessless and returning successfully that we consumed the operator.
+ if (token.getKind() == tok::lessless) {
+ // Make sure we have more tokens before attempting to look ahead one more.
+ if (m_next_token_index + 1 < m_tokens.size()) {
+ // Look ahead two tokens.
+ clang::Token n_token = m_tokens[m_next_token_index + 1];
+ // If we find ( or < then this is indeed operator<< no need for fix.
+ if (n_token.getKind() != tok::l_paren && n_token.getKind() != tok::less) {
+ clang::Token tmp_tok;
+ tmp_tok.startToken();
+ tmp_tok.setLength(1);
+ tmp_tok.setLocation(token.getLocation().getLocWithOffset(1));
+ tmp_tok.setKind(tok::less);
+
+ m_tokens[m_next_token_index] = tmp_tok;
+
+ start_position.Remove();
+ return true;
+ }
+ }
+ }
+
switch (token.getKind()) {
case tok::kw_new:
case tok::kw_delete:
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
index 414c3a009157..6fe6b12725b0 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CPlusPlusNameParser_h_
-#define liblldb_CPlusPlusNameParser_h_
-
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/Optional.h"
@@ -174,4 +173,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_CPlusPlusNameParser_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 3ea7589d8e4a..41bbd2b01a1e 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -1,4 +1,4 @@
-//===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===//
+//===-- CxxStringTypes.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,13 +10,13 @@
#include "llvm/Support/ConvertUTF.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/Time.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
index 35498b3b568f..2713ded45929 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CxxStringTypes_h_
-#define liblldb_CxxStringTypes_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -46,4 +46,4 @@ bool WCharSummaryProvider(ValueObject &valobj, Stream &stream,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_CxxStringTypes_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index ecadaef7a87e..84dd09a47d8a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxx.cpp ----------------------------------------------*- C++ -*-===//
+//===-- LibCxx.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,7 +8,6 @@
#include "LibCxx.h"
-#include "llvm/ADT/ScopeExit.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/ValueObject.h"
@@ -17,7 +16,6 @@
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/VectorIterator.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
@@ -27,6 +25,7 @@
#include "lldb/Utility/Stream.h"
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
using namespace lldb;
using namespace lldb_private;
@@ -145,6 +144,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
return true;
}
+bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
+ if (!ptr_sp)
+ return false;
+
+ ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+ if (!ptr_sp)
+ return false;
+
+ if (ptr_sp->GetValueAsUnsigned(0) == 0) {
+ stream.Printf("nullptr");
+ return true;
+ } else {
+ bool print_pointee = false;
+ Status error;
+ ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
+ if (pointee_sp && error.Success()) {
+ if (pointee_sp->DumpPrintableRepresentation(
+ stream, ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::PrintableRepresentationSpecialCases::eDisable,
+ false))
+ print_pointee = true;
+ }
+ if (!print_pointee)
+ stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
+ }
+
+ return true;
+}
+
/*
(lldb) fr var ibeg --raw --ptr-depth 1
(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
@@ -241,8 +277,8 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
m_pair_ptr = nullptr;
if (addr && addr != LLDB_INVALID_ADDRESS) {
- ClangASTContext *ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());
+ TypeSystemClang *ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem());
if (!ast_ctx)
return false;
CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
@@ -450,6 +486,67 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator(
: nullptr);
}
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+ if (valobj_sp)
+ Update();
+}
+
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ ~LibcxxUniquePtrSyntheticFrontEnd() = default;
+
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp)
+ : nullptr);
+}
+
+size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ CalculateNumChildren() {
+ return (m_compressed_pair_sp ? 1 : 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ if (!m_compressed_pair_sp)
+ return lldb::ValueObjectSP();
+
+ if (idx != 0)
+ return lldb::ValueObjectSP();
+
+ return m_compressed_pair_sp;
+}
+
+bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP ptr_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
+ if (!ptr_sp)
+ return false;
+
+ m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+
+ return false;
+}
+
+bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
+}
+
+size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ if (name == "__value_")
+ return 0;
+ return UINT32_MAX;
+}
+
bool lldb_private::formatters::LibcxxContainerSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
if (valobj.IsPointerType()) {
@@ -469,22 +566,20 @@ enum LibcxxStringLayoutMode {
eLibcxxStringLayoutModeInvalid = 0xffff
};
-// this function abstracts away the layout and mode details of a libc++ string
-// and returns the address of the data and the size ready for callers to
-// consume
-static bool ExtractLibcxxStringInfo(ValueObject &valobj,
- ValueObjectSP &location_sp,
- uint64_t &size) {
+/// Determine the size in bytes of \p valobj (a libc++ std::string object) and
+/// extract its data payload. Return the size + payload pair.
+static llvm::Optional<std::pair<uint64_t, ValueObjectSP>>
+ExtractLibcxxStringInfo(ValueObject &valobj) {
ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
if (!D)
- return false;
+ return {};
ValueObjectSP layout_decider(
D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
// this child should exist
if (!layout_decider)
- return false;
+ return {};
ConstString g_data_name("__data_");
ConstString g_size_name("__size_");
@@ -498,13 +593,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
if (layout == eLibcxxStringLayoutModeDSC) {
ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0}));
if (!size_mode)
- return false;
+ return {};
if (size_mode->GetName() != g_size_name) {
// we are hitting the padding structure, move along
size_mode = D->GetChildAtIndexPath({1, 1, 1});
if (!size_mode)
- return false;
+ return {};
}
size_mode_value = (size_mode->GetValueAsUnsigned(0));
@@ -512,7 +607,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
} else {
ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0}));
if (!size_mode)
- return false;
+ return {};
size_mode_value = (size_mode->GetValueAsUnsigned(0));
short_mode = ((size_mode_value & 1) == 0);
@@ -521,36 +616,58 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
if (short_mode) {
ValueObjectSP s(D->GetChildAtIndex(1, true));
if (!s)
- return false;
- location_sp = s->GetChildAtIndex(
+ return {};
+ ValueObjectSP location_sp = s->GetChildAtIndex(
(layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
- size = (layout == eLibcxxStringLayoutModeDSC)
- ? size_mode_value
- : ((size_mode_value >> 1) % 256);
- return (location_sp.get() != nullptr);
- } else {
- ValueObjectSP l(D->GetChildAtIndex(0, true));
- if (!l)
- return false;
- // we can use the layout_decider object as the data pointer
- location_sp = (layout == eLibcxxStringLayoutModeDSC)
- ? layout_decider
- : l->GetChildAtIndex(2, true);
- ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
- if (!size_vo || !location_sp)
- return false;
- size = size_vo->GetValueAsUnsigned(0);
- return true;
+ const uint64_t size = (layout == eLibcxxStringLayoutModeDSC)
+ ? size_mode_value
+ : ((size_mode_value >> 1) % 256);
+
+ // When the small-string optimization takes place, the data must fit in the
+ // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
+ // likely that the string isn't initialized and we're reading garbage.
+ ExecutionContext exe_ctx(location_sp->GetExecutionContextRef());
+ const llvm::Optional<uint64_t> max_bytes =
+ location_sp->GetCompilerType().GetByteSize(
+ exe_ctx.GetBestExecutionContextScope());
+ if (!max_bytes || size > *max_bytes || !location_sp)
+ return {};
+
+ return std::make_pair(size, location_sp);
}
+
+ ValueObjectSP l(D->GetChildAtIndex(0, true));
+ if (!l)
+ return {};
+ // we can use the layout_decider object as the data pointer
+ ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC)
+ ? layout_decider
+ : l->GetChildAtIndex(2, true);
+ ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
+ const unsigned capacity_index =
+ (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0;
+ ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
+ if (!size_vo || !location_sp || !capacity_vo)
+ return {};
+ const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
+ const uint64_t capacity =
+ capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
+ if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
+ capacity < size)
+ return {};
+ return std::make_pair(size, location_sp);
}
bool lldb_private::formatters::LibcxxWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options) {
- uint64_t size = 0;
- ValueObjectSP location_sp;
- if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ auto string_info = ExtractLibcxxStringInfo(valobj);
+ if (!string_info)
return false;
+ uint64_t size;
+ ValueObjectSP location_sp;
+ std::tie(size, location_sp) = *string_info;
+
if (size == 0) {
stream.Printf("L\"\"");
return true;
@@ -558,10 +675,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
if (!location_sp)
return false;
- DataExtractor extractor;
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
-
if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
if (size > max_size) {
@@ -569,11 +684,15 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
options.SetIsTruncated(true);
}
}
- location_sp->GetPointeeData(extractor, 0, size);
+
+ DataExtractor extractor;
+ const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
+ if (bytes_read < size)
+ return false;
// std::wstring::size() is measured in 'characters', not bytes
- ClangASTContext *ast_context =
- ClangASTContext::GetScratch(*valobj.GetTargetSP());
+ TypeSystemClang *ast_context =
+ TypeSystemClang::GetScratch(*valobj.GetTargetSP());
if (!ast_context)
return false;
@@ -591,40 +710,35 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
switch (*wchar_t_size) {
case 1:
- StringPrinter::ReadBufferAndDumpToStream<
+ return StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::UTF8>(
options);
break;
case 2:
- lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<
+ return StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::UTF16>(
options);
break;
case 4:
- lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<
+ return StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::UTF32>(
options);
- break;
-
- default:
- stream.Printf("size for wchar_t is not valid");
- return true;
}
-
- return true;
+ return false;
}
template <StringPrinter::StringElementType element_type>
bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options,
- std::string prefix_token = "") {
- uint64_t size = 0;
- ValueObjectSP location_sp;
-
- if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ std::string prefix_token) {
+ auto string_info = ExtractLibcxxStringInfo(valobj);
+ if (!string_info)
return false;
+ uint64_t size;
+ ValueObjectSP location_sp;
+ std::tie(size, location_sp) = *string_info;
if (size == 0) {
stream.Printf("\"\"");
@@ -636,7 +750,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
- DataExtractor extractor;
if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
if (size > max_size) {
@@ -644,41 +757,55 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
options.SetIsTruncated(true);
}
}
- location_sp->GetPointeeData(extractor, 0, size);
+
+ DataExtractor extractor;
+ const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
+ if (bytes_read < size)
+ return false;
options.SetData(extractor);
options.SetStream(&stream);
-
if (prefix_token.empty())
options.SetPrefixToken(nullptr);
else
options.SetPrefixToken(prefix_token);
-
options.SetQuote('"');
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
- StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
+ return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
+}
+template <StringPrinter::StringElementType element_type>
+static bool formatStringImpl(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token) {
+ StreamString scratch_stream;
+ const bool success = LibcxxStringSummaryProvider<element_type>(
+ valobj, scratch_stream, summary_options, prefix_token);
+ if (success)
+ stream << scratch_stream.GetData();
+ else
+ stream << "Summary Unavailable";
return true;
}
bool lldb_private::formatters::LibcxxStringSummaryProviderASCII(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options) {
- return LibcxxStringSummaryProvider<StringPrinter::StringElementType::ASCII>(
- valobj, stream, summary_options);
+ return formatStringImpl<StringPrinter::StringElementType::ASCII>(
+ valobj, stream, summary_options, "");
}
bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options) {
- return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF16>(
+ return formatStringImpl<StringPrinter::StringElementType::UTF16>(
valobj, stream, summary_options, "u");
}
bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &summary_options) {
- return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF32>(
+ return formatStringImpl<StringPrinter::StringElementType::UTF32>(
valobj, stream, summary_options, "U");
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 214f5512e4a5..ea5a7c178178 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LibCxx_h_
-#define liblldb_LibCxx_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -43,6 +43,10 @@ bool LibcxxSmartPointerSummaryProvider(
const TypeSummaryOptions
&options); // libc++ std::shared_ptr<> and std::weak_ptr<>
+// libc++ std::unique_ptr<>
+bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
bool LibcxxFunctionSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::function<>
@@ -107,6 +111,26 @@ private:
lldb::ByteOrder m_byte_order;
};
+class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+ ~LibcxxUniquePtrSyntheticFrontEnd() override;
+
+private:
+ lldb::ValueObjectSP m_compressed_pair_sp;
+};
+
SyntheticChildrenFrontEnd *
LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -116,6 +140,10 @@ LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -156,4 +184,4 @@ LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_LibCxx_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
index b4e7a1703e46..45d4322e93d7 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
@@ -1,5 +1,4 @@
-//===-- LibCxxAtomic.cpp ------------------------------------------*- C++
-//-*-===//
+//===-- LibCxxAtomic.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "LibCxxAtomic.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
using namespace lldb;
using namespace lldb_private;
@@ -101,8 +101,6 @@ public:
size_t GetIndexOfChildWithName(ConstString name) override;
- lldb::ValueObjectSP GetSyntheticValue() override;
-
private:
ValueObject *m_real_child;
};
@@ -128,26 +126,20 @@ bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
CalculateNumChildren() {
- return m_real_child ? m_real_child->GetNumChildren() : 0;
+ return m_real_child ? 1 : 0;
}
lldb::ValueObjectSP
lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(
size_t idx) {
- return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr;
+ if (idx == 0)
+ return m_real_child->GetSP()->Clone(ConstString("Value"));
+ return nullptr;
}
size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
GetIndexOfChildWithName(ConstString name) {
- return m_real_child ? m_real_child->GetIndexOfChildWithName(name)
- : UINT32_MAX;
-}
-
-lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
- GetSyntheticValue() {
- if (m_real_child && m_real_child->CanProvideValue())
- return m_real_child->GetSP();
- return nullptr;
+ return formatters::ExtractIndexFromString(name.GetCString());
}
SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
index 8be833dd82f6..6fcceb645c7b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LibCxxAtomic_h_
-#define liblldb_LibCxxAtomic_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -30,4 +30,4 @@ LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_LibCxxAtomic_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 78c453cd1b3c..6de4637a6a4a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===//
+//===-- LibCxxBitset.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "LibCxx.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
using namespace lldb;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 79c7434f617f..65e88d114fcc 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxInitializerList.cpp -------------------------------*- C++ -*-===//
+//===-- LibCxxInitializerList.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index f5281f2ce532..0d5ae16a0b29 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===//
+//===-- LibCxxList.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "LibCxx.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
@@ -290,15 +290,6 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) {
m_element_type);
}
-static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) {
- ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true);
- if (! value) {
- // pre-r300140 member name
- value = pair.GetChildMemberWithName(ConstString("__first_"), true);
- }
- return value;
-}
-
bool ForwardListFrontEnd::Update() {
AbstractListFrontEnd::Update();
@@ -311,7 +302,7 @@ bool ForwardListFrontEnd::Update() {
m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true));
if (!impl_sp)
return false;
- impl_sp = GetValueOfCompressedPair(*impl_sp);
+ impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp);
if (!impl_sp)
return false;
m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
@@ -332,7 +323,7 @@ size_t ListFrontEnd::CalculateNumChildren() {
ValueObjectSP size_alloc(
m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
if (size_alloc) {
- ValueObjectSP value = GetValueOfCompressedPair(*size_alloc);
+ ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc);
if (value) {
m_count = value->GetValueAsUnsigned(UINT32_MAX);
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index f6d8d4d9a7eb..64a199e24e4a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===//
+//===-- LibCxxMap.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "LibCxx.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
@@ -298,8 +298,8 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
UINT32_MAX) {
m_skip_size = bit_offset / 8u;
} else {
- ClangASTContext *ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(node_type.GetTypeSystem());
+ TypeSystemClang *ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(node_type.GetTypeSystem());
if (!ast_ctx)
return;
CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index b1ad171d0b0c..c0c819632851 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===//
+//===-- LibCxxOptional.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -26,11 +26,12 @@ public:
bool MightHaveChildren() override { return true; }
bool Update() override;
- size_t CalculateNumChildren() override { return m_size; }
+ size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
- size_t m_size = 0;
+ /// True iff the option contains a value.
+ bool m_has_value = false;
};
} // namespace
@@ -44,13 +45,13 @@ bool OptionalFrontEnd::Update() {
// __engaged_ is a bool flag and is true if the optional contains a value.
// Converting it to unsigned gives us a size of 1 if it contains a value
// and 0 if not.
- m_size = engaged_sp->GetValueAsUnsigned(0);
+ m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1;
return false;
}
ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx >= m_size)
+ if (!m_has_value)
return ValueObjectSP();
// __val_ contains the underlying value of an optional if it has one.
@@ -71,7 +72,7 @@ ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) {
if (!holder_type)
return ValueObjectSP();
- return val_sp->Clone(ConstString(llvm::formatv("Value").str()));
+ return val_sp->Clone(ConstString("Value"));
}
SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
index 2f06d684f953..616ffdca107d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===//
+//===-- LibCxxQueue.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
index 45294e25f0f5..a113fe98c6b6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===//
+//===-- LibCxxTuple.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index b2c38c915c81..3a441973fc73 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxUnorderedMap.cpp ----------------------------------*- C++ -*-===//
+//===-- LibCxxUnorderedMap.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "LibCxx.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
index 62945bd3ce80..951bf2896fb0 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===//
+//===-- LibCxxVariant.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -60,10 +60,10 @@ using namespace lldb_private;
namespace {
// libc++ std::variant index could have one of three states
-// 1) VALID, we can obtain it and its not variant_npos
-// 2) INVALID, we can't obtain it or it is not a type we expect
-// 3) NPOS, its value is variant_npos which means the variant has no value
-enum class LibcxxVariantIndexValidity { VALID, INVALID, NPOS };
+// 1) Valid, we can obtain it and its not variant_npos
+// 2) Invalid, we can't obtain it or it is not a type we expect
+// 3) NPos, its value is variant_npos which means the variant has no value
+enum class LibcxxVariantIndexValidity { Valid, Invalid, NPos };
LibcxxVariantIndexValidity
LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) {
@@ -71,14 +71,14 @@ LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) {
impl_sp->GetChildMemberWithName(ConstString("__index"), true));
if (!index_sp)
- return LibcxxVariantIndexValidity::INVALID;
+ return LibcxxVariantIndexValidity::Invalid;
int64_t index_value = index_sp->GetValueAsSigned(0);
if (index_value == -1)
- return LibcxxVariantIndexValidity::NPOS;
+ return LibcxxVariantIndexValidity::NPos;
- return LibcxxVariantIndexValidity::VALID;
+ return LibcxxVariantIndexValidity::Valid;
}
llvm::Optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) {
@@ -129,10 +129,10 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream,
LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
- if (validity == LibcxxVariantIndexValidity::INVALID)
+ if (validity == LibcxxVariantIndexValidity::Invalid)
return false;
- if (validity == LibcxxVariantIndexValidity::NPOS) {
+ if (validity == LibcxxVariantIndexValidity::NPos) {
stream.Printf(" No Value");
return true;
}
@@ -159,7 +159,7 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream,
if (!template_type)
return false;
- stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString());
+ stream << " Active Type = " << template_type.GetDisplayTypeName() << " ";
return true;
}
@@ -196,10 +196,10 @@ bool VariantFrontEnd::Update() {
LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
- if (validity == LibcxxVariantIndexValidity::INVALID)
+ if (validity == LibcxxVariantIndexValidity::Invalid)
return false;
- if (validity == LibcxxVariantIndexValidity::NPOS)
+ if (validity == LibcxxVariantIndexValidity::NPos)
return true;
m_size = 1;
@@ -242,7 +242,7 @@ ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) {
if (!head_value)
return ValueObjectSP();
- return head_value->Clone(ConstString(ConstString("Value").AsCString()));
+ return head_value->Clone(ConstString("Value"));
}
SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
index 65db5aeaa99d..b4c27ccb9d77 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LibCxxVariant_h_
-#define liblldb_LibCxxVariant_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -27,4 +27,4 @@ SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_LibCxxVariant_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index bcd7442bc669..43f76b0df810 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -1,4 +1,4 @@
-//===-- LibCxxVector.cpp ----------------------------------------*- C++ -*-===//
+//===-- LibCxxVector.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index 0e0f6663c924..b4af67ecee0d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -1,4 +1,4 @@
-//===-- LibStdcpp.cpp -------------------------------------------*- C++ -*-===//
+//===-- LibStdcpp.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,11 +8,11 @@
#include "LibStdcpp.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/VectorIterator.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
@@ -259,6 +259,7 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider(
if (error.Fail())
return false;
options.SetSourceSize(size_of_data);
+ options.SetHasSourceSize(true);
if (!StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF8>(options)) {
@@ -319,6 +320,7 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider(
if (error.Fail())
return false;
options.SetSourceSize(size_of_data);
+ options.SetHasSourceSize(true);
options.SetPrefixToken("L");
switch (wchar_size) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index e7f88d667c14..9e41aa0ffc01 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LibStdCpp_h_
-#define liblldb_LibStdCpp_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -56,4 +56,4 @@ LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_LibStdCpp_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
index 0ac7b8f8e02b..7ba59ff9d1ad 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -1,4 +1,4 @@
-//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===//
+//===-- LibStdcppTuple.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index cceb511cdc46..0b34b4e2fc89 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -1,4 +1,4 @@
-//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===//
+//===-- LibStdcppUniquePointer.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
index 248c51acea42..b24bcc1344e2 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
@@ -1,4 +1,4 @@
-//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===//
+//===-- MSVCUndecoratedNameParser.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
index 6e20877cae1b..e5b60a0a1d5b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_MSVCUndecoratedNameParser_h_
-#define liblldb_MSVCUndecoratedNameParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H
#include <vector>
diff --git a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
index 3e77b1646739..aaf578c6f728 100644
--- a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
+++ b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
@@ -1,4 +1,4 @@
-//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===//
+//===-- ClangHighlighter.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,6 +13,7 @@
#include "lldb/Utility/AnsiTerminal.h"
#include "lldb/Utility/StreamString.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringSet.h"
diff --git a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h
index f459f9424697..5257c728ca5c 100644
--- a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h
+++ b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangHighlighter_h_
-#define liblldb_ClangHighlighter_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringSet.h"
@@ -34,4 +34,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_ClangHighlighter_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H
diff --git a/lldb/source/Plugins/Language/ObjC/CF.cpp b/lldb/source/Plugins/Language/ObjC/CF.cpp
index 5bca260616ea..2610468b17fd 100644
--- a/lldb/source/Plugins/Language/ObjC/CF.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CF.cpp
@@ -1,5 +1,4 @@
-//===-- CF.cpp ----------------------------------------------------*- C++
-//-*-===//
+//===-- CF.cpp ------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,10 +8,10 @@
#include "CF.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -30,7 +29,7 @@ using namespace lldb_private::formatters;
bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
+ epoch = epoch + (time_t)valobj.GetValueAsSigned(0);
tm *tm_date = localtime(&epoch);
if (!tm_date)
return false;
diff --git a/lldb/source/Plugins/Language/ObjC/CF.h b/lldb/source/Plugins/Language/ObjC/CF.h
index 2abb56d407eb..6165e1c235bc 100644
--- a/lldb/source/Plugins/Language/ObjC/CF.h
+++ b/lldb/source/Plugins/Language/ObjC/CF.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CF_h_
-#define liblldb_CF_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -29,4 +29,4 @@ bool CFAbsoluteTimeSummaryProvider(ValueObject &valobj, Stream &stream,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_CF_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H
diff --git a/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp b/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp
new file mode 100644
index 000000000000..42cda0146f2e
--- /dev/null
+++ b/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp
@@ -0,0 +1,114 @@
+#include "CFBasicHash.h"
+
+#include "lldb/Utility/Endian.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool CFBasicHash::IsValid() const {
+ if (m_address != LLDB_INVALID_ADDRESS) {
+ if (m_ptr_size == 4 && m_ht_32)
+ return true;
+ else if (m_ptr_size == 8 && m_ht_64)
+ return true;
+ else
+ return false;
+ }
+ return false;
+}
+
+bool CFBasicHash::Update(addr_t addr, ExecutionContextRef exe_ctx_rf) {
+ if (addr == LLDB_INVALID_ADDRESS || !addr)
+ return false;
+
+ m_address = addr;
+ m_exe_ctx_ref = exe_ctx_rf;
+ m_ptr_size =
+ m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetAddressByteSize();
+ m_byte_order = m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetByteOrder();
+
+ if (m_ptr_size == 4)
+ return UpdateFor(m_ht_32);
+ else if (m_ptr_size == 8)
+ return UpdateFor(m_ht_64);
+ return false;
+
+ llvm_unreachable(
+ "Unsupported architecture. Only 32bits and 64bits supported.");
+}
+
+template <typename T>
+bool CFBasicHash::UpdateFor(std::unique_ptr<__CFBasicHash<T>> &m_ht) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ return false;
+
+ Status error;
+ Target *target = m_exe_ctx_ref.GetTargetSP().get();
+ addr_t addr = m_address.GetLoadAddress(target);
+ size_t size = sizeof(typename __CFBasicHash<T>::RuntimeBase) +
+ sizeof(typename __CFBasicHash<T>::Bits);
+
+ m_ht = std::make_unique<__CFBasicHash<T>>();
+ m_exe_ctx_ref.GetProcessSP()->ReadMemory(addr, m_ht.get(),
+ size, error);
+ if (error.Fail())
+ return false;
+
+ m_mutable = !(m_ht->base.cfinfoa & (1 << 6));
+ m_multi = m_ht->bits.counts_offset;
+ m_type = static_cast<HashType>(m_ht->bits.keys_offset);
+ addr_t ptr_offset = addr + size;
+ size_t ptr_count = GetPointerCount();
+ size = ptr_count * sizeof(T);
+
+ m_exe_ctx_ref.GetProcessSP()->ReadMemory(ptr_offset, m_ht->pointers, size,
+ error);
+
+ if (error.Fail()) {
+ m_ht = nullptr;
+ return false;
+ }
+
+ return true;
+}
+
+size_t CFBasicHash::GetCount() const {
+ if (!IsValid())
+ return 0;
+
+ if (!m_multi)
+ return (m_ptr_size == 4) ? m_ht_32->bits.used_buckets
+ : m_ht_64->bits.used_buckets;
+
+ // FIXME: Add support for multi
+ return 0;
+}
+
+size_t CFBasicHash::GetPointerCount() const {
+ if (!IsValid())
+ return 0;
+
+ if (m_multi)
+ return 3; // Bits::counts_offset;
+ return (m_type == HashType::dict) + 1;
+}
+
+addr_t CFBasicHash::GetKeyPointer() const {
+ if (!IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ if (m_ptr_size == 4)
+ return m_ht_32->pointers[m_ht_32->bits.keys_offset];
+
+ return m_ht_64->pointers[m_ht_64->bits.keys_offset];
+}
+
+addr_t CFBasicHash::GetValuePointer() const {
+ if (!IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ if (m_ptr_size == 4)
+ return m_ht_32->pointers[0];
+
+ return m_ht_64->pointers[0];
+}
diff --git a/lldb/source/Plugins/Language/ObjC/CFBasicHash.h b/lldb/source/Plugins/Language/ObjC/CFBasicHash.h
new file mode 100644
index 000000000000..fd30f5f7845f
--- /dev/null
+++ b/lldb/source/Plugins/Language/ObjC/CFBasicHash.h
@@ -0,0 +1,76 @@
+//===-- CFBasicHash.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+namespace lldb_private {
+
+class CFBasicHash {
+public:
+ enum class HashType { set = 0, dict };
+
+ CFBasicHash() = default;
+ ~CFBasicHash() = default;
+
+ bool Update(lldb::addr_t addr, ExecutionContextRef exe_ctx_rf);
+
+ bool IsValid() const;
+
+ bool IsMutable() const { return m_mutable; };
+ bool IsMultiVariant() const { return m_multi; }
+ HashType GetType() const { return m_type; }
+
+ size_t GetCount() const;
+ lldb::addr_t GetKeyPointer() const;
+ lldb::addr_t GetValuePointer() const;
+
+private:
+ template <typename T> struct __CFBasicHash {
+ struct RuntimeBase {
+ T cfisa;
+ T cfinfoa;
+ } base;
+
+ struct Bits {
+ uint16_t __reserved0;
+ uint16_t __reserved1 : 2;
+ uint16_t keys_offset : 1;
+ uint16_t counts_offset : 2;
+ uint16_t counts_width : 2;
+ uint16_t __reserved2 : 9;
+ uint32_t used_buckets; // number of used buckets
+ uint64_t deleted : 16; // number of elements deleted
+ uint64_t num_buckets_idx : 8; // index to number of buckets
+ uint64_t __reserved3 : 40;
+ uint64_t __reserved4;
+ } bits;
+
+ T pointers[3];
+ };
+ template <typename T> bool UpdateFor(std::unique_ptr<__CFBasicHash<T>> &m_ht);
+
+ size_t GetPointerCount() const;
+
+ uint32_t m_ptr_size = UINT32_MAX;
+ lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid;
+ Address m_address = LLDB_INVALID_ADDRESS;
+ std::unique_ptr<__CFBasicHash<uint32_t>> m_ht_32 = nullptr;
+ std::unique_ptr<__CFBasicHash<uint64_t>> m_ht_64 = nullptr;
+ ExecutionContextRef m_exe_ctx_ref;
+ bool m_mutable = true;
+ bool m_multi = false;
+ HashType m_type;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H
diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index 8a81abbaedbe..648fc4adf24f 100644
--- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -1,4 +1,4 @@
-//===-- Cocoa.cpp -----------------------------------------------*- C++ -*-===//
+//===-- Cocoa.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,6 +8,7 @@
#include "Cocoa.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -15,7 +16,6 @@
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Host/Time.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessStructReader.h"
@@ -818,13 +818,14 @@ bool lldb_private::formatters::NSDateSummaryProvider(
static const ConstString g___NSDate("__NSDate");
static const ConstString g___NSTaggedDate("__NSTaggedDate");
static const ConstString g_NSCalendarDate("NSCalendarDate");
+ static const ConstString g_NSConstantDate("NSConstantDate");
if (class_name.IsEmpty())
return false;
uint64_t info_bits = 0, value_bits = 0;
if ((class_name == g_NSDate) || (class_name == g___NSDate) ||
- (class_name == g___NSTaggedDate)) {
+ (class_name == g___NSTaggedDate) || (class_name == g_NSConstantDate)) {
if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) {
date_value_bits = ((value_bits << 8) | (info_bits << 4));
memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
@@ -850,8 +851,14 @@ bool lldb_private::formatters::NSDateSummaryProvider(
} else
return false;
- if (date_value == -63114076800) {
- stream.Printf("0001-12-30 00:00:00 +0000");
+ // FIXME: It seems old dates are not formatted according to NSDate's calendar
+ // so we hardcode distantPast's value so that it looks like LLDB is doing
+ // the right thing.
+
+ // The relative time in seconds from Cocoa Epoch to [NSDate distantPast].
+ const double RelSecondsFromCocoaEpochToNSDateDistantPast = -63114076800;
+ if (date_value == RelSecondsFromCocoaEpochToNSDateDistantPast) {
+ stream.Printf("0001-01-01 00:00:00 UTC");
return true;
}
@@ -867,7 +874,7 @@ bool lldb_private::formatters::NSDateSummaryProvider(
// is generally true and POSIXly happy, but might break if a library vendor
// decides to get creative
time_t epoch = GetOSXEpoch();
- epoch = epoch + (time_t)date_value;
+ epoch = epoch + static_cast<time_t>(std::floor(date_value));
tm *tm_date = gmtime(&epoch);
if (!tm_date)
return false;
@@ -902,8 +909,7 @@ bool lldb_private::formatters::ObjCClassSummaryProvider(
if (class_name.IsEmpty())
return false;
- if (ConstString cs =
- Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
+ if (ConstString cs = Mangled(class_name).GetDemangledName())
class_name = cs;
stream.Printf("%s", class_name.AsCString("<unknown class>"));
diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.h b/lldb/source/Plugins/Language/ObjC/Cocoa.h
index 388e6f03aa0f..a195d622ce58 100644
--- a/lldb/source/Plugins/Language/ObjC/Cocoa.h
+++ b/lldb/source/Plugins/Language/ObjC/Cocoa.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Cocoa_h_
-#define liblldb_Cocoa_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -113,4 +113,4 @@ public:
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_Cocoa_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H
diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index 247429da1b06..ac2f45b8354f 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -1,5 +1,4 @@
-//===-- CoreMedia.cpp --------------------------------------------*- C++
-//-*-===//
+//===-- CoreMedia.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.h b/lldb/source/Plugins/Language/ObjC/CoreMedia.h
index 79abb67b9d7e..7fd8560d20e1 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.h
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CoreMedia_h_
-#define liblldb_CoreMedia_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -22,4 +22,4 @@ bool CMTimeSummaryProvider(ValueObject &valobj, Stream &stream,
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_CF_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H
diff --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index 73335aff2fd7..8d648d8a0861 100644
--- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -1,4 +1,4 @@
-//===-- NSArray.cpp ---------------------------------------------*- C++ -*-===//
+//===-- NSArray.cpp -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,16 +7,17 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "clang/Basic/TargetInfo.h"
#include "Cocoa.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -97,42 +98,46 @@ private:
};
namespace Foundation1010 {
- struct DataDescriptor_32 {
- uint32_t _used;
- uint32_t _offset;
- uint32_t _size : 28;
- uint64_t _priv1 : 4;
- uint32_t _priv2;
- uint32_t _data;
- };
-
- struct DataDescriptor_64 {
- uint64_t _used;
- uint64_t _offset;
- uint64_t _size : 60;
- uint64_t _priv1 : 4;
- uint32_t _priv2;
- uint64_t _data;
- };
+ namespace {
+ struct DataDescriptor_32 {
+ uint32_t _used;
+ uint32_t _offset;
+ uint32_t _size : 28;
+ uint64_t _priv1 : 4;
+ uint32_t _priv2;
+ uint32_t _data;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used;
+ uint64_t _offset;
+ uint64_t _size : 60;
+ uint64_t _priv1 : 4;
+ uint32_t _priv2;
+ uint64_t _data;
+ };
+ }
using NSArrayMSyntheticFrontEnd =
GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
namespace Foundation1428 {
- struct DataDescriptor_32 {
- uint32_t _used;
- uint32_t _offset;
- uint32_t _size;
- uint32_t _data;
- };
-
- struct DataDescriptor_64 {
- uint64_t _used;
- uint64_t _offset;
- uint64_t _size;
- uint64_t _data;
- };
+ namespace {
+ struct DataDescriptor_32 {
+ uint32_t _used;
+ uint32_t _offset;
+ uint32_t _size;
+ uint32_t _data;
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used;
+ uint64_t _offset;
+ uint64_t _size;
+ uint64_t _data;
+ };
+ }
using NSArrayMSyntheticFrontEnd =
GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
@@ -436,7 +441,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
if (valobj_sp) {
- auto *clang_ast_context = ClangASTContext::GetScratch(
+ auto *clang_ast_context = TypeSystemClang::GetScratch(
*valobj_sp->GetExecutionContextRef().GetTargetSP());
if (clang_ast_context)
m_id_type = CompilerType(
@@ -528,7 +533,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName
template <typename D32, typename D64>
lldb_private::formatters::
GenericNSArrayMSyntheticFrontEnd<D32, D64>::
- ~GenericNSArrayMSyntheticFrontEnd() {
+ ~GenericNSArrayMSyntheticFrontEnd<D32, D64>() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
@@ -584,7 +589,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
if (valobj_sp) {
CompilerType type = valobj_sp->GetCompilerType();
if (type) {
- auto *clang_ast_context = ClangASTContext::GetScratch(
+ auto *clang_ast_context = TypeSystemClang::GetScratch(
*valobj_sp->GetExecutionContextRef().GetTargetSP());
if (clang_ast_context)
m_id_type = clang_ast_context->GetType(
@@ -595,7 +600,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
template <typename D32, typename D64, bool Inline>
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
- ~GenericNSArrayISyntheticFrontEnd() {
+ ~GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
@@ -753,7 +758,7 @@ lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex(
if (idx == 0) {
auto *clang_ast_context =
- ClangASTContext::GetScratch(*m_backend.GetTargetSP());
+ TypeSystemClang::GetScratch(*m_backend.GetTargetSP());
if (clang_ast_context) {
CompilerType id_type(
clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID));
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index ae00674c49f3..3dc07678f92f 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -1,4 +1,4 @@
-//===-- NSDictionary.cpp ----------------------------------------*- C++ -*-===//
+//===-- NSDictionary.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,14 +10,15 @@
#include "clang/AST/DeclCXX.h"
+#include "CFBasicHash.h"
#include "NSDictionary.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -65,7 +66,7 @@ NSDictionary_Additionals::GetAdditionalSynthetics() {
static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
CompilerType compiler_type;
- ClangASTContext *target_ast_context = ClangASTContext::GetScratch(*target_sp);
+ TypeSystemClang *target_ast_context = TypeSystemClang::GetScratch(*target_sp);
if (target_ast_context) {
ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
@@ -76,18 +77,19 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
if (!compiler_type) {
compiler_type = target_ast_context->CreateRecordType(
- nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
- clang::TTK_Struct, lldb::eLanguageTypeC);
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
+ g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct,
+ lldb::eLanguageTypeC);
if (compiler_type) {
- ClangASTContext::StartTagDeclarationDefinition(compiler_type);
+ TypeSystemClang::StartTagDeclarationDefinition(compiler_type);
CompilerType id_compiler_type =
target_ast_context->GetBasicType(eBasicTypeObjCID);
- ClangASTContext::AddFieldToRecordType(
+ TypeSystemClang::AddFieldToRecordType(
compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0);
- ClangASTContext::AddFieldToRecordType(
+ TypeSystemClang::AddFieldToRecordType(
compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0);
- ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
}
}
}
@@ -139,6 +141,37 @@ private:
std::vector<DictionaryItemDescriptor> m_children;
};
+class NSCFDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+private:
+ struct DictionaryItemDescriptor {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+
+ CFBasicHash m_hashtable;
+
+ CompilerType m_pair_type;
+ std::vector<DictionaryItemDescriptor> m_children;
+};
+
class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -245,64 +278,67 @@ namespace Foundation1100 {
}
namespace Foundation1428 {
- struct DataDescriptor_32 {
- uint32_t _used : 26;
- uint32_t _kvo : 1;
- uint32_t _size;
- uint32_t _buffer;
- uint64_t GetSize() { return _size; }
- };
-
- struct DataDescriptor_64 {
- uint64_t _used : 58;
- uint32_t _kvo : 1;
- uint64_t _size;
- uint64_t _buffer;
- uint64_t GetSize() { return _size; }
- };
-
-
-
+ namespace {
+ struct DataDescriptor_32 {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _buffer;
+ uint64_t GetSize() { return _size; }
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _buffer;
+ uint64_t GetSize() { return _size; }
+ };
+ }
+
using NSDictionaryMSyntheticFrontEnd =
GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
namespace Foundation1437 {
- static const uint64_t NSDictionaryCapacities[] = {
- 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
- 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
- 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
- 6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
- 111638519, 180634607, 292272623, 472907251
- };
-
- static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t);
-
- struct DataDescriptor_32 {
- uint32_t _buffer;
- uint32_t _muts;
- uint32_t _used : 25;
- uint32_t _kvo : 1;
- uint32_t _szidx : 6;
+ namespace {
+ static const uint64_t NSDictionaryCapacities[] = {
+ 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
+ 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
+ 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
+ 6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
+ 111638519, 180634607, 292272623, 472907251
+ };
+
+ static const size_t NSDictionaryNumSizeBuckets =
+ sizeof(NSDictionaryCapacities) / sizeof(uint64_t);
+
+ struct DataDescriptor_32 {
+ uint32_t _buffer;
+ uint32_t _muts;
+ uint32_t _used : 25;
+ uint32_t _kvo : 1;
+ uint32_t _szidx : 6;
- uint64_t GetSize() {
- return (_szidx) >= NSDictionaryNumSizeBuckets ?
- 0 : NSDictionaryCapacities[_szidx];
- }
- };
-
- struct DataDescriptor_64 {
- uint64_t _buffer;
- uint32_t _muts;
- uint32_t _used : 25;
- uint32_t _kvo : 1;
- uint32_t _szidx : 6;
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
+ };
+
+ struct DataDescriptor_64 {
+ uint64_t _buffer;
+ uint32_t _muts;
+ uint32_t _used : 25;
+ uint32_t _kvo : 1;
+ uint32_t _szidx : 6;
- uint64_t GetSize() {
- return (_szidx) >= NSDictionaryNumSizeBuckets ?
- 0 : NSDictionaryCapacities[_szidx];
- }
- };
+ uint64_t GetSize() {
+ return (_szidx) >= NSDictionaryNumSizeBuckets ?
+ 0 : NSDictionaryCapacities[_szidx];
+ }
+ };
+ }
using NSDictionaryMSyntheticFrontEnd =
GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
@@ -375,7 +411,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable");
static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
static const ConstString g_Dictionary0("__NSDictionary0");
- static const ConstString g_DictionaryCF("__NSCFDictionary");
+ static const ConstString g_DictionaryCF("__CFDictionary");
+ static const ConstString g_DictionaryNSCF("__NSCFDictionary");
+ static const ConstString g_DictionaryCFRef("CFDictionaryRef");
if (class_name.IsEmpty())
return false;
@@ -386,9 +424,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
ptr_size, 0, error);
if (error.Fail())
return false;
+
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy ||
- class_name == g_DictionaryCF) {
+ } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
@@ -406,8 +444,15 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
value = 1;
} else if (class_name == g_Dictionary0) {
value = 0;
- }
- else {
+ } else if (class_name == g_DictionaryCF ||
+ class_name == g_DictionaryNSCF ||
+ class_name == g_DictionaryCFRef) {
+ ExecutionContext exe_ctx(process_sp);
+ CFBasicHash cfbh;
+ if (!cfbh.Update(valobj_addr, exe_ctx))
+ return false;
+ value = cfbh.GetCount();
+ } else {
auto &map(NSDictionary_Additionals::GetAdditionalSummaries());
for (auto &candidate : map) {
if (candidate.first && candidate.first->Match(class_name))
@@ -465,6 +510,9 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable");
static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
static const ConstString g_Dictionary0("__NSDictionary0");
+ static const ConstString g_DictionaryCF("__CFDictionary");
+ static const ConstString g_DictionaryNSCF("__NSCFDictionary");
+ static const ConstString g_DictionaryCFRef("CFDictionaryRef");
if (class_name.IsEmpty())
return nullptr;
@@ -483,6 +531,10 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_Dictionary1) {
return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_DictionaryCF ||
+ class_name == g_DictionaryNSCF ||
+ class_name == g_DictionaryCFRef) {
+ return (new NSCFDictionarySyntheticFrontEnd(valobj_sp));
} else {
auto &map(NSDictionary_Additionals::GetAdditionalSynthetics());
for (auto &candidate : map) {
@@ -640,6 +692,140 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex(
return dict_item.valobj_sp;
}
+lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::
+ NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {}
+
+size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ const char *item_name = name.GetCString();
+ const uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::
+ CalculateNumChildren() {
+ if (!m_hashtable.IsValid())
+ return 0;
+ return m_hashtable.GetCount();
+}
+
+bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ m_order = process_sp->GetByteOrder();
+ return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref);
+}
+
+bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ lldb::addr_t m_keys_ptr = m_hashtable.GetKeyPointer();
+ lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer();
+
+ const uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+
+ Status error;
+ lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ // Iterate over inferior memory, reading key/value pointers by shifting each
+ // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read
+ // fails, otherwise, continue until the number of tries matches the number
+ // of childen.
+ while (tries < num_children) {
+ key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+ val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
+
+ key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!key_at_idx || !val_at_idx)
+ continue;
+ tries++;
+
+ DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+ lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ DictionaryItemDescriptor &dict_item = m_children[idx];
+ if (!dict_item.valobj_sp) {
+ if (!m_pair_type.IsValid()) {
+ TargetSP target_sp(m_backend.GetTargetSP());
+ if (!target_sp)
+ return ValueObjectSP();
+ m_pair_type = GetLLDBNSPairType(target_sp);
+ }
+ if (!m_pair_type.IsValid())
+ return ValueObjectSP();
+
+ DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+ switch (m_ptr_size) {
+ case 0: // architecture has no clue - fail
+ return lldb::ValueObjectSP();
+ case 4: {
+ uint32_t *data_ptr = reinterpret_cast<uint32_t *>(buffer_sp->GetBytes());
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
+ } break;
+ case 8: {
+ uint64_t *data_ptr = reinterpret_cast<uint64_t *>(buffer_sp->GetBytes());
+ *data_ptr = dict_item.key_ptr;
+ *(data_ptr + 1) = dict_item.val_ptr;
+ } break;
+ default:
+ lldbassert(false && "pointer size is not 4 nor 8");
+ }
+
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+ DataExtractor data(buffer_sp, m_order, m_ptr_size);
+ dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data,
+ m_exe_ctx_ref, m_pair_type);
+ }
+ return dict_item.valobj_sp;
+}
+
lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {}
@@ -724,7 +910,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
template <typename D32, typename D64>
lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
- ~GenericNSDictionaryMSyntheticFrontEnd() {
+ ~GenericNSDictionaryMSyntheticFrontEnd<D32,D64>() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
@@ -732,8 +918,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
}
template <typename D32, typename D64>
-size_t
-lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: GetIndexOfChildWithName(ConstString name) {
+size_t lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<
+ D32, D64>::GetIndexOfChildWithName(ConstString name) {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -782,7 +968,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
}
if (error.Fail())
return false;
- return false;
+ return true;
}
template <typename D32, typename D64>
@@ -794,9 +980,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
template <typename D32, typename D64>
lldb::ValueObjectSP
-lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
- GetChildAtIndex(
- size_t idx) {
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<
+ D32, D64>::GetChildAtIndex(size_t idx) {
lldb::addr_t m_keys_ptr;
lldb::addr_t m_values_ptr;
if (m_data_32) {
@@ -884,7 +1069,6 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
return dict_item.valobj_sp;
}
-
lldb_private::formatters::Foundation1100::
NSDictionaryMSyntheticFrontEnd::
NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.h b/lldb/source/Plugins/Language/ObjC/NSDictionary.h
index 44d56f9c2c68..57dacd6759d2 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.h
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.h
@@ -1,5 +1,4 @@
-//===-- NSDictionary.h ---------------------------------------------------*- C++
-//-*-===//
+//===-- NSDictionary.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_NSDictionary_h_
-#define liblldb_NSDictionary_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -91,4 +90,4 @@ public:
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_NSDictionary_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H
diff --git a/lldb/source/Plugins/Language/ObjC/NSError.cpp b/lldb/source/Plugins/Language/ObjC/NSError.cpp
index 94a97c8ad039..aa1103cb342c 100644
--- a/lldb/source/Plugins/Language/ObjC/NSError.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSError.cpp
@@ -1,4 +1,4 @@
-//===-- NSError.cpp ---------------------------------------------*- C++ -*-===//
+//===-- NSError.cpp -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,10 +10,10 @@
#include "Cocoa.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -87,7 +87,7 @@ bool lldb_private::formatters::NSError_SummaryProvider(
ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData(
"domain_str", isw.GetAsData(process_sp->GetByteOrder()),
valobj.GetExecutionContextRef(),
- ClangASTContext::GetScratch(process_sp->GetTarget())
+ TypeSystemClang::GetScratch(process_sp->GetTarget())
->GetBasicType(lldb::eBasicTypeVoid)
.GetPointerType());
@@ -156,7 +156,7 @@ public:
m_child_sp = CreateValueObjectFromData(
"_userInfo", isw.GetAsData(process_sp->GetByteOrder()),
m_backend.GetExecutionContextRef(),
- ClangASTContext::GetScratch(process_sp->GetTarget())
+ TypeSystemClang::GetScratch(process_sp->GetTarget())
->GetBasicType(lldb::eBasicTypeObjCID));
return false;
}
diff --git a/lldb/source/Plugins/Language/ObjC/NSException.cpp b/lldb/source/Plugins/Language/ObjC/NSException.cpp
index 9150787361c5..c6bae5e1c008 100644
--- a/lldb/source/Plugins/Language/ObjC/NSException.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSException.cpp
@@ -1,4 +1,4 @@
-//===-- NSException.cpp -----------------------------------------*- C++ -*-===//
+//===-- NSException.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,7 +13,6 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -23,6 +22,7 @@
#include "Plugins/Language/ObjC/NSString.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
using namespace lldb;
using namespace lldb_private;
@@ -69,7 +69,7 @@ static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp,
InferiorSizedWord userinfo_isw(userinfo, *process_sp);
InferiorSizedWord reserved_isw(reserved, *process_sp);
- auto *clang_ast_context = ClangASTContext::GetScratch(process_sp->GetTarget());
+ auto *clang_ast_context = TypeSystemClang::GetScratch(process_sp->GetTarget());
if (!clang_ast_context)
return false;
diff --git a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 587dd13870a0..d962f39611b6 100644
--- a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -1,4 +1,4 @@
-//===-- NSIndexPath.cpp -----------------------------------------*- C++ -*-===//
+//===-- NSIndexPath.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,11 +8,11 @@
#include "Cocoa.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -53,7 +53,7 @@ public:
if (!type_system)
return false;
- ClangASTContext *ast = ClangASTContext::GetScratch(
+ TypeSystemClang *ast = TypeSystemClang::GetScratch(
*m_backend.GetExecutionContextRef().GetTargetSP());
if (!ast)
return false;
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
index ebaa990fb74b..4dbbe6fbddff 100644
--- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -1,4 +1,4 @@
-//===-- NSSet.cpp -----------------------------------------------*- C++ -*-===//
+//===-- NSSet.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,12 +7,13 @@
//===----------------------------------------------------------------------===//
#include "NSSet.h"
+#include "CFBasicHash.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -79,6 +80,36 @@ private:
std::vector<SetItemDescriptor> m_children;
};
+class NSCFSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ NSCFSetSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ size_t CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+ bool Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+private:
+ struct SetItemDescriptor {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ lldb::ByteOrder m_order;
+
+ CFBasicHash m_hashtable;
+
+ CompilerType m_pair_type;
+ std::vector<SetItemDescriptor> m_children;
+};
+
template <typename D32, typename D64>
class GenericNSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
@@ -245,21 +276,25 @@ bool lldb_private::formatters::NSSetSummaryProvider(
uint64_t value = 0;
- ConstString class_name_cs = descriptor->GetClassName();
- const char *class_name = class_name_cs.GetCString();
+ ConstString class_name(descriptor->GetClassName());
- if (!class_name || !*class_name)
+ static const ConstString g_SetI("__NSSetI");
+ static const ConstString g_OrderedSetI("__NSOrderedSetI");
+ static const ConstString g_SetM("__NSSetM");
+ static const ConstString g_SetCF("__NSCFSet");
+ static const ConstString g_SetCFRef("CFSetRef");
+
+ if (class_name.IsEmpty())
return false;
- if (!strcmp(class_name, "__NSSetI") ||
- !strcmp(class_name, "__NSOrderedSetI")) {
+ if (class_name == g_SetI || class_name == g_OrderedSetI) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
ptr_size, 0, error);
if (error.Fail())
return false;
value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- } else if (!strcmp(class_name, "__NSSetM")) {
+ } else if (class_name == g_SetM) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Status error;
@@ -272,9 +307,15 @@ bool lldb_private::formatters::NSSetSummaryProvider(
}
if (error.Fail())
return false;
+ } else if (class_name == g_SetCF || class_name == g_SetCFRef) {
+ ExecutionContext exe_ctx(process_sp);
+ CFBasicHash cfbh;
+ if (!cfbh.Update(valobj_addr, exe_ctx))
+ return false;
+ value = cfbh.GetCount();
} else {
auto &map(NSSet_Additionals::GetAdditionalSummaries());
- auto iter = map.find(class_name_cs), end = map.end();
+ auto iter = map.find(class_name), end = map.end();
if (iter != end)
return iter->second(valobj, stream, options);
else
@@ -321,16 +362,20 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator(
if (!descriptor || !descriptor->IsValid())
return nullptr;
- ConstString class_name_cs = descriptor->GetClassName();
- const char *class_name = class_name_cs.GetCString();
+ ConstString class_name = descriptor->GetClassName();
- if (!class_name || !*class_name)
+ static const ConstString g_SetI("__NSSetI");
+ static const ConstString g_OrderedSetI("__NSOrderedSetI");
+ static const ConstString g_SetM("__NSSetM");
+ static const ConstString g_SetCF("__NSCFSet");
+ static const ConstString g_SetCFRef("CFSetRef");
+
+ if (class_name.IsEmpty())
return nullptr;
- if (!strcmp(class_name, "__NSSetI") ||
- !strcmp(class_name, "__NSOrderedSetI")) {
+ if (class_name == g_SetI || class_name == g_OrderedSetI) {
return (new NSSetISyntheticFrontEnd(valobj_sp));
- } else if (!strcmp(class_name, "__NSSetM")) {
+ } else if (class_name == g_SetM) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
if (apple_runtime) {
@@ -343,9 +388,11 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator(
} else {
return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
}
+ } else if (class_name == g_SetCF || class_name == g_SetCFRef) {
+ return (new NSCFSetSyntheticFrontEnd(valobj_sp));
} else {
auto &map(NSSet_Additionals::GetAdditionalSynthetics());
- auto iter = map.find(class_name_cs), end = map.end();
+ auto iter = map.find(class_name), end = map.end();
if (iter != end)
return iter->second(synth, valobj_sp);
return nullptr;
@@ -475,16 +522,18 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) {
auto ptr_size = process_sp->GetAddressByteSize();
DataBufferHeap buffer(ptr_size, 0);
switch (ptr_size) {
- case 0: // architecture has no clue?? - fail
+ case 0: // architecture has no clue - fail
return lldb::ValueObjectSP();
case 4:
- *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+ *reinterpret_cast<uint32_t *>(buffer.GetBytes()) =
+ static_cast<uint32_t>(set_item.item_ptr);
break;
case 8:
- *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+ *reinterpret_cast<uint64_t *>(buffer.GetBytes()) =
+ static_cast<uint64_t>(set_item.item_ptr);
break;
default:
- assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
+ lldbassert(false && "pointer size is not 4 nor 8");
}
StreamString idx_name;
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
@@ -501,6 +550,128 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) {
return set_item.valobj_sp;
}
+lldb_private::formatters::NSCFSetSyntheticFrontEnd::NSCFSetSyntheticFrontEnd(
+ lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+ m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {}
+
+size_t
+lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetIndexOfChildWithName(
+ ConstString name) {
+ const char *item_name = name.GetCString();
+ const uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSCFSetSyntheticFrontEnd::CalculateNumChildren() {
+ if (!m_hashtable.IsValid())
+ return 0;
+ return m_hashtable.GetCount();
+}
+
+bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::Update() {
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ m_order = process_sp->GetByteOrder();
+ return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref);
+}
+
+bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::MightHaveChildren() {
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex(
+ size_t idx) {
+ lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer();
+
+ const uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty()) {
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+
+ Status error;
+ lldb::addr_t val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ // Iterate over inferior memory, reading value pointers by shifting the
+ // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read
+ // fails, otherwise, continue until the number of tries matches the number
+ // of childen.
+ while (tries < num_children) {
+ val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
+
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!val_at_idx)
+ continue;
+ tries++;
+
+ SetItemDescriptor descriptor = {val_at_idx, lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ SetItemDescriptor &set_item = m_children[idx];
+ if (!set_item.valobj_sp) {
+
+ DataBufferSP buffer_sp(new DataBufferHeap(m_ptr_size, 0));
+
+ switch (m_ptr_size) {
+ case 0: // architecture has no clue - fail
+ return lldb::ValueObjectSP();
+ case 4:
+ *reinterpret_cast<uint32_t *>(buffer_sp->GetBytes()) =
+ static_cast<uint32_t>(set_item.item_ptr);
+ break;
+ case 8:
+ *reinterpret_cast<uint64_t *>(buffer_sp->GetBytes()) =
+ static_cast<uint64_t>(set_item.item_ptr);
+ break;
+ default:
+ lldbassert(false && "pointer size is not 4 nor 8");
+ }
+ StreamString idx_name;
+ idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+ DataExtractor data(buffer_sp, m_order, m_ptr_size);
+
+ set_item.valobj_sp = CreateValueObjectFromData(
+ idx_name.GetString(), data, m_exe_ctx_ref,
+ m_backend.GetCompilerType().GetBasicTypeFromAST(
+ lldb::eBasicTypeObjCID));
+ }
+
+ return set_item.valobj_sp;
+}
+
template <typename D32, typename D64>
lldb_private::formatters::
GenericNSSetMSyntheticFrontEnd<D32, D64>::GenericNSSetMSyntheticFrontEnd(
@@ -513,7 +684,7 @@ lldb_private::formatters::
template <typename D32, typename D64>
lldb_private::formatters::
- GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd() {
+ GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd<D32, D64>() {
delete m_data_32;
m_data_32 = nullptr;
delete m_data_64;
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.h b/lldb/source/Plugins/Language/ObjC/NSSet.h
index f11b6d406dec..3ad1f694befe 100644
--- a/lldb/source/Plugins/Language/ObjC/NSSet.h
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_NSSet_h_
-#define liblldb_NSSet_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -36,4 +36,4 @@ public:
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_NSSet_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp b/lldb/source/Plugins/Language/ObjC/NSString.cpp
index ce54d657374b..b9d0d73cbc2e 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -1,5 +1,4 @@
-//===-- NSString.cpp ----------------------------------------------*- C++
-//-*-===//
+//===-- NSString.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,11 +8,11 @@
#include "NSString.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/ProcessStructReader.h"
#include "lldb/Target/Target.h"
@@ -35,7 +34,7 @@ NSString_Additionals::GetAdditionalSummaries() {
static CompilerType GetNSPathStore2Type(Target &target) {
static ConstString g_type_name("__lldb_autogen_nspathstore2");
- ClangASTContext *ast_ctx = ClangASTContext::GetScratch(target);
+ TypeSystemClang *ast_ctx = TypeSystemClang::GetScratch(target);
if (!ast_ctx)
return CompilerType();
@@ -171,11 +170,11 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetNeedsZeroTermination(false);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else {
@@ -183,11 +182,11 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetProcessSP(process_sp);
options.SetStream(&stream);
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetNeedsZeroTermination(false);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::ASCII>(options);
}
@@ -200,9 +199,9 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::ASCII>(options);
} else if (is_unicode) {
@@ -222,11 +221,11 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
options.SetBinaryZeroIsTerminator(!has_explicit_length);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else if (is_path_store) {
@@ -242,11 +241,11 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
options.SetBinaryZeroIsTerminator(!has_explicit_length);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
} else if (is_inline) {
@@ -264,11 +263,11 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetProcessSP(process_sp);
options.SetStream(&stream);
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
options.SetBinaryZeroIsTerminator(!has_explicit_length);
- options.SetLanguage(summary_options.GetLanguage());
if (has_explicit_length)
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF8>(options);
@@ -287,9 +286,9 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetProcessSP(process_sp);
options.SetStream(&stream);
options.SetSourceSize(explicit_length);
+ options.SetHasSourceSize(has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::ASCII>(options);
}
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.h b/lldb/source/Plugins/Language/ObjC/NSString.h
index 699d8eb36f88..a68cc6c056b0 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.h
+++ b/lldb/source/Plugins/Language/ObjC/NSString.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_NSString_h_
-#define liblldb_NSString_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
@@ -39,4 +39,4 @@ public:
} // namespace formatters
} // namespace lldb_private
-#endif // liblldb_CF_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 3be548ad4144..29391daaab93 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -1,4 +1,4 @@
-//===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===//
+//===-- ObjCLanguage.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,12 +10,12 @@
#include "ObjCLanguage.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
@@ -37,6 +37,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+LLDB_PLUGIN_DEFINE(ObjCLanguage)
+
void ObjCLanguage::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
CreateInstance);
@@ -446,6 +448,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
appkit_flags);
AddCXXSummary(objc_category_sp,
lldb_private::formatters::NSDictionarySummaryProvider<true>,
+ "NSDictionary summary provider", ConstString("__CFDictionary"),
+ appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSDictionarySummaryProvider<true>,
"NSDictionary summary provider",
ConstString("CFMutableDictionaryRef"), appkit_flags);
@@ -466,6 +472,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
"__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
AddCXXSummary(objc_category_sp,
lldb_private::formatters::NSSetSummaryProvider<false>,
+ "__CFSet summary", ConstString("__CFSet"), appkit_flags);
+ AddCXXSummary(objc_category_sp,
+ lldb_private::formatters::NSSetSummaryProvider<false>,
"__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
AddCXXSummary(objc_category_sp,
lldb_private::formatters::NSSetSummaryProvider<false>,
@@ -582,6 +591,11 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
"NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(
+ objc_category_sp,
+ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+ "NSDictionary synthetic children", ConstString("__CFDictionary"),
+ ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp,
lldb_private::formatters::NSErrorSyntheticFrontEndCreator,
@@ -604,6 +618,15 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
lldb_private::formatters::NSSetSyntheticFrontEndCreator,
"__NSSetM synthetic children", ConstString("__NSSetM"),
ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__NSCFSet synthetic children", ConstString("__NSCFSet"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "CFSetRef synthetic children", ConstString("CFSetRef"),
+ ScriptedSyntheticChildren::Flags());
+
AddCXXSynthetic(
objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
"NSMutableSet synthetic children", ConstString("NSMutableSet"),
@@ -620,6 +643,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
"__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+ "__CFSet synthetic children", ConstString("__CFSet"),
+ ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp,
lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 3e2cc0972993..bed62a5c447a 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjCLanguage_h_
-#define liblldb_ObjCLanguage_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
#include <cstring>
#include <vector>
@@ -160,4 +160,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_ObjCLanguage_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
index 81b3c5807c41..0a4017eda434 100644
--- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
@@ -1,5 +1,4 @@
-//===-- ObjCPlusPlusLanguage.cpp --------------------------------------*- C++
-//-*-===//
+//===-- ObjCPlusPlusLanguage.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -15,6 +14,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage)
+
bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
const auto suffixes = {".h", ".mm"};
for (auto suffix : suffixes) {
diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 6224a3f47b3b..4b3d23653347 100644
--- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjCPlusPlusLanguage_h_
-#define liblldb_ObjCPlusPlusLanguage_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H
#include "Plugins/Language/ClangCommon/ClangHighlighter.h"
#include "lldb/Target/Language.h"
@@ -48,4 +48,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_CPlusPlusLanguage_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index d556aae1c458..8aa803a8553e 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -1,4 +1,4 @@
-//===-- CPPLanguageRuntime.cpp
+//===-- CPPLanguageRuntime.cpp---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -20,7 +20,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
@@ -44,7 +43,7 @@ CPPLanguageRuntime::~CPPLanguageRuntime() {}
CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
: LanguageRuntime(process) {}
-bool CPPLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) {
+bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
return name == g_this;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index abdd79fcd7b9..5b00590e6301 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CPPLanguageRuntime_h_
-#define liblldb_CPPLanguageRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H
#include <vector>
@@ -69,7 +69,7 @@ public:
/// Obtain a ThreadPlan to get us into C++ constructs such as std::function.
///
/// \param[in] thread
- /// Curent thrad of execution.
+ /// Current thrad of execution.
///
/// \param[in] stop_others
/// True if other threads should pause during execution.
@@ -79,7 +79,7 @@ public:
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
bool stop_others) override;
- bool IsWhitelistedRuntimeValue(ConstString name) override;
+ bool IsAllowedRuntimeValue(ConstString name) override;
protected:
// Classes that inherit from CPPLanguageRuntime can see and modify these
CPPLanguageRuntime(Process *process);
@@ -90,9 +90,10 @@ private:
OperatorStringToCallableInfoMap CallableLookupCache;
- DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime);
+ CPPLanguageRuntime(const CPPLanguageRuntime &) = delete;
+ const CPPLanguageRuntime &operator=(const CPPLanguageRuntime &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_CPPLanguageRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_CPPLANGUAGERUNTIME_H
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 9efb021caa83..3ab32641d9c1 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -1,5 +1,4 @@
-//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*-
-//C++ -*-===//
+//===-- ItaniumABILanguageRuntime.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,6 +8,7 @@
#include "ItaniumABILanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
@@ -21,7 +21,6 @@
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
@@ -41,6 +40,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(ItaniumABILanguageRuntime, CXXItaniumABI)
+
static const char *vtable_demangled_prefix = "vtable for ";
char ItaniumABILanguageRuntime::ID = 0;
@@ -73,9 +74,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
Symbol *symbol = sc.symbol;
if (symbol != nullptr) {
const char *name =
- symbol->GetMangled()
- .GetDemangledName(lldb::eLanguageTypeC_plus_plus)
- .AsCString();
+ symbol->GetMangled().GetDemangledName().AsCString();
if (name && strstr(name, vtable_demangled_prefix) == name) {
Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
@@ -118,7 +117,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
if (class_types.GetSize() == 1) {
type_sp = class_types.GetTypeAtIndex(0);
if (type_sp) {
- if (ClangASTContext::IsCXXClassType(
+ if (TypeSystemClang::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
LLDB_LOGF(
log,
@@ -150,7 +149,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
for (i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
- if (ClangASTContext::IsCXXClassType(
+ if (TypeSystemClang::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
LLDB_LOGF(
log,
@@ -238,7 +237,7 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
if (!type)
return true;
- if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), type)) {
+ if (TypeSystemClang::AreTypesSame(in_value.GetCompilerType(), type)) {
// The dynamic type we found was the same type, so we don't have a
// dynamic type here...
return false;
@@ -358,8 +357,7 @@ protected:
Mangled mangled(name);
if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
- ConstString demangled(
- mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
+ ConstString demangled(mangled.GetDisplayDemangledName());
demangled_any = true;
result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(),
demangled.GetCString());
@@ -420,12 +418,13 @@ lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() {
uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; }
BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
- Breakpoint *bkpt, bool catch_bp, bool throw_bp) {
+ const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) {
return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false);
}
BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver(
- Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) {
+ const BreakpointSP &bkpt, bool catch_bp, bool throw_bp,
+ bool for_expressions) {
// One complication here is that most users DON'T want to stop at
// __cxa_allocate_expression, but until we can do anything better with
// predicting unwinding the expression parser does. So we have two forms of
@@ -536,8 +535,8 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
if (!thread_sp->SafeToCallFunctions())
return {};
- ClangASTContext *clang_ast_context =
- ClangASTContext::GetScratch(m_process->GetTarget());
+ TypeSystemClang *clang_ast_context =
+ TypeSystemClang::GetScratch(m_process->GetTarget());
if (!clang_ast_context)
return {};
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 97cc81b8681f..d591527d9257 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ItaniumABILanguageRuntime_h_
-#define liblldb_ItaniumABILanguageRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H
#include <map>
#include <mutex>
@@ -66,9 +66,9 @@ public:
bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
@@ -81,10 +81,9 @@ public:
uint32_t GetPluginVersion() override;
protected:
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp,
- bool for_expressions);
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp, bool for_expressions);
lldb::BreakpointSP CreateExceptionBreakpoint(bool catch_bp, bool throw_bp,
bool for_expressions,
@@ -114,4 +113,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ItaniumABILanguageRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABI_ITANIUMABILANGUAGERUNTIME_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 859b693477a9..bdd5c29db848 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -1,5 +1,4 @@
-//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*- C++
-//-*-===//
+//===-- AppleObjCClassDescriptorV2.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,7 +16,7 @@ using namespace lldb_private;
bool ClassDescriptorV2::Read_objc_class(
Process *process, std::unique_ptr<objc_class_t> &objc_class) const {
- objc_class.reset(new objc_class_t);
+ objc_class = std::make_unique<objc_class_t>();
bool ret = objc_class->Read(process, m_objc_class_ptr);
@@ -198,14 +197,14 @@ bool ClassDescriptorV2::Read_class_row(
return false;
if (class_row_t_flags & RW_REALIZED) {
- class_rw.reset(new class_rw_t);
+ class_rw = std::make_unique<class_rw_t>();
if (!class_rw->Read(process, objc_class.m_data_ptr)) {
class_rw.reset();
return false;
}
- class_ro.reset(new class_ro_t);
+ class_ro = std::make_unique<class_ro_t>();
if (!class_ro->Read(process, class_rw->m_ro_ptr)) {
class_rw.reset();
@@ -213,7 +212,7 @@ bool ClassDescriptorV2::Read_class_row(
return false;
}
} else {
- class_ro.reset(new class_ro_t);
+ class_ro = std::make_unique<class_ro_t>();
if (!class_ro->Read(process, objc_class.m_data_ptr)) {
class_ro.reset();
@@ -242,15 +241,20 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
lldb::offset_t cursor = 0;
- m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
+ uint32_t entsize = extractor.GetU32_unchecked(&cursor);
+ m_is_small = (entsize & 0x80000000) != 0;
+ m_has_direct_selector = (entsize & 0x40000000) != 0;
+ m_entsize = entsize & 0xfffc;
m_count = extractor.GetU32_unchecked(&cursor);
m_first_ptr = addr + cursor;
return true;
}
-bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
- size_t size = GetSize(process);
+bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
+ bool is_small, bool has_direct_sel) {
+ size_t ptr_size = process->GetAddressByteSize();
+ size_t size = GetSize(process, is_small);
DataBufferHeap buffer(size, '\0');
Status error;
@@ -261,13 +265,30 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
}
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
- process->GetAddressByteSize());
-
+ ptr_size);
lldb::offset_t cursor = 0;
- m_name_ptr = extractor.GetAddress_unchecked(&cursor);
- m_types_ptr = extractor.GetAddress_unchecked(&cursor);
- m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
+ if (is_small) {
+ uint32_t nameref_offset = extractor.GetU32_unchecked(&cursor);
+ uint32_t types_offset = extractor.GetU32_unchecked(&cursor);
+ uint32_t imp_offset = extractor.GetU32_unchecked(&cursor);
+
+ m_name_ptr = addr + nameref_offset;
+
+ if (!has_direct_sel) {
+ // The SEL offset points to a SELRef. We need to dereference twice.
+ m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size,
+ 0, error);
+ if (!error.Success())
+ return false;
+ }
+ m_types_ptr = addr + 4 + types_offset;
+ m_imp_ptr = addr + 8 + imp_offset;
+ } else {
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_types_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
+ }
process->ReadCStringFromMemory(m_name_ptr, m_name, error);
if (error.Fail()) {
@@ -358,19 +379,24 @@ bool ClassDescriptorV2::Describe(
if (instance_method_func) {
std::unique_ptr<method_list_t> base_method_list;
- base_method_list.reset(new method_list_t);
+ base_method_list = std::make_unique<method_list_t>();
if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
return false;
- if (base_method_list->m_entsize != method_t::GetSize(process))
+ bool is_small = base_method_list->m_is_small;
+ bool has_direct_selector = base_method_list->m_has_direct_selector;
+
+ if (base_method_list->m_entsize != method_t::GetSize(process, is_small))
return false;
std::unique_ptr<method_t> method;
- method.reset(new method_t);
+ method = std::make_unique<method_t>();
for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
- method->Read(process, base_method_list->m_first_ptr +
- (i * base_method_list->m_entsize));
+ method->Read(process,
+ base_method_list->m_first_ptr +
+ (i * base_method_list->m_entsize),
+ is_small, has_direct_selector);
if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
break;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index b8ba9dbb65f4..9ef21c6e7208 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCClassDescriptorV2_h_
-#define liblldb_AppleObjCClassDescriptorV2_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H
#include <mutex>
@@ -133,7 +133,9 @@ private:
};
struct method_list_t {
- uint32_t m_entsize;
+ uint16_t m_entsize;
+ bool m_is_small;
+ bool m_has_direct_selector;
uint32_t m_count;
lldb::addr_t m_first_ptr;
@@ -148,15 +150,19 @@ private:
std::string m_name;
std::string m_types;
- static size_t GetSize(Process *process) {
- size_t ptr_size = process->GetAddressByteSize();
+ static size_t GetSize(Process *process, bool is_small) {
+ size_t field_size;
+ if (is_small)
+ field_size = 4; // uint32_t relative indirect fields
+ else
+ field_size = process->GetAddressByteSize();
- return ptr_size // SEL name;
- + ptr_size // const char *types;
- + ptr_size; // IMP imp;
+ return field_size // SEL name;
+ + field_size // const char *types;
+ + field_size; // IMP imp;
}
- bool Read(Process *process, lldb::addr_t addr);
+ bool Read(Process *process, lldb::addr_t addr, bool, bool);
};
struct ivar_list_t {
@@ -328,4 +334,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AppleObjCClassDescriptorV2_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCCLASSDESCRIPTORV2_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 73843063606c..7b331307c0f7 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -1,4 +1,4 @@
-//===-- AppleObjCDeclVendor.cpp ---------------------------------*- C++ -*-===//
+//===-- AppleObjCDeclVendor.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "AppleObjCDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
#include "lldb/Core/Module.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
@@ -30,17 +30,14 @@ public:
bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx,
clang::DeclarationName name) override {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
LLDB_LOGF(log,
- "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
- "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
- current_id,
+ "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName"
+ " on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
static_cast<void *>(&decl_ctx->getParentASTContext()),
name.getAsString().c_str(), decl_ctx->getDeclKindName(),
static_cast<const void *>(decl_ctx));
@@ -70,44 +67,37 @@ public:
}
void CompleteType(clang::TagDecl *tag_decl) override {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
LLDB_LOGF(log,
- "AppleObjCExternalASTSource::CompleteType[%u] on "
+ "AppleObjCExternalASTSource::CompleteType on "
"(ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id, static_cast<void *>(&tag_decl->getASTContext()),
+ static_cast<void *>(&tag_decl->getASTContext()),
static_cast<void *>(tag_decl), tag_decl->getName().str().c_str());
- LLDB_LOG(log, " AOEAS::CT[{0}] Before:\n{1}", current_id,
- ClangUtil::DumpDecl(tag_decl));
+ LLDB_LOG(log, " AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl));
- LLDB_LOG(log, " AOEAS::CT[{1}] After:{1}", current_id,
- ClangUtil::DumpDecl(tag_decl));
+ LLDB_LOG(log, " AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl));
return;
}
void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
LLDB_LOGF(log,
- "AppleObjCExternalASTSource::CompleteType[%u] on "
+ "AppleObjCExternalASTSource::CompleteType on "
"(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
- current_id,
static_cast<void *>(&interface_decl->getASTContext()),
static_cast<void *>(interface_decl),
interface_decl->getName().str().c_str());
- LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id);
+ LLDB_LOGF(log, " AOEAS::CT Before:");
LLDB_LOG(log, " [CT] {0}", ClangUtil::DumpDecl(interface_decl));
}
@@ -143,10 +133,9 @@ private:
AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
: ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime),
- m_ast_ctx(runtime.GetProcess()
- ->GetTarget()
- .GetArchitecture()
- .GetTriple()),
+ m_ast_ctx(
+ "AppleObjCDeclVendor AST",
+ runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()),
m_type_realizer_sp(m_runtime.GetEncodingToType()) {
m_external_source = new AppleObjCExternalASTSource(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
@@ -309,7 +298,7 @@ public:
}
clang::ObjCMethodDecl *
- BuildMethod(ClangASTContext &clang_ast_ctxt,
+ BuildMethod(TypeSystemClang &clang_ast_ctxt,
clang::ObjCInterfaceDecl *interface_decl, const char *name,
bool instance,
ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp) {
@@ -538,15 +527,13 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
uint32_t max_matches,
std::vector<CompilerDecl> &decls) {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
- current_id, (const char *)name.AsCString(),
- append ? "true" : "false", max_matches);
+ LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )",
+ (const char *)name.AsCString(), append ? "true" : "false",
+ max_matches);
if (!append)
decls.clear();
@@ -579,24 +566,21 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
isa_value = metadata->GetISAPtr();
LLDB_LOG(log,
- "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
- ") in the ASTContext",
- current_id, result_iface_type.getAsString(), isa_value);
+ "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext",
+ result_iface_type.getAsString(), isa_value);
}
- decls.push_back(CompilerDecl(&m_ast_ctx, result_iface_decl));
+ decls.push_back(m_ast_ctx.GetCompilerDecl(result_iface_decl));
ret++;
break;
} else {
- LLDB_LOGF(log,
- "AOCTV::FT [%u] There's something in the ASTContext, but "
- "it's not something we know about",
- current_id);
+ LLDB_LOGF(log, "AOCTV::FT There's something in the ASTContext, but "
+ "it's not something we know about");
break;
}
} else if (log) {
- LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext",
- current_id, name.AsCString());
+ LLDB_LOGF(log, "AOCTV::FT Couldn't find %s in the ASTContext",
+ name.AsCString());
}
// It's not. If it exists, we have to put it into our ASTContext.
@@ -604,7 +588,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
if (!isa) {
- LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id);
+ LLDB_LOGF(log, "AOCTV::FT Couldn't find the isa");
break;
}
@@ -613,9 +597,9 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
if (!iface_decl) {
LLDB_LOGF(log,
- "AOCTV::FT [%u] Couldn't get the Objective-C interface for "
+ "AOCTV::FT Couldn't get the Objective-C interface for "
"isa 0x%" PRIx64,
- current_id, (uint64_t)isa);
+ (uint64_t)isa);
break;
}
@@ -623,11 +607,11 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
if (log) {
clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl);
- LLDB_LOG(log, "AOCTV::FT [{0}] Created {1} (isa 0x{2:x})", current_id,
+ LLDB_LOG(log, "AOCTV::FT Created {1} (isa 0x{2:x})",
new_iface_type.getAsString(), (uint64_t)isa);
}
- decls.push_back(CompilerDecl(&m_ast_ctx, iface_decl));
+ decls.push_back(m_ast_ctx.GetCompilerDecl(iface_decl));
ret++;
break;
} while (false);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index f49ca3540c2c..c1201b985814 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCDeclVendor_h_
-#define liblldb_AppleObjCDeclVendor_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/lldb-private.h"
#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
namespace lldb_private {
@@ -37,7 +37,7 @@ private:
bool FinishDecl(clang::ObjCInterfaceDecl *decl);
ObjCLanguageRuntime &m_runtime;
- ClangASTContext m_ast_ctx;
+ TypeSystemClang m_ast_ctx;
ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp;
AppleObjCExternalASTSource *m_external_source;
@@ -50,4 +50,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AppleObjCDeclVendor_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCDECLVENDOR_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 7076959bee97..22ea83a57beb 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -1,5 +1,4 @@
-//===-- AppleObjCRuntime.cpp -------------------------------------*- C++
-//-*-===//
+//===-- AppleObjCRuntime.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "AppleObjCRuntime.h"
+#include "AppleObjCRuntimeV1.h"
+#include "AppleObjCRuntimeV2.h"
#include "AppleObjCTrampolineHandler.h"
-
-#include "clang/AST/Type.h"
-
+#include "Plugins/Language/ObjC/NSString.h"
+#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -22,7 +23,6 @@
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -35,16 +35,17 @@
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
+#include "clang/AST/Type.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
-#include "Plugins/Language/ObjC/NSString.h"
-#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include <vector>
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(AppleObjCRuntime)
+
char AppleObjCRuntime::ID = 0;
AppleObjCRuntime::~AppleObjCRuntime() {}
@@ -55,6 +56,16 @@ AppleObjCRuntime::AppleObjCRuntime(Process *process)
ReadObjCLibraryIfNeeded(process->GetTarget().GetImages());
}
+void AppleObjCRuntime::Initialize() {
+ AppleObjCRuntimeV2::Initialize();
+ AppleObjCRuntimeV1::Initialize();
+}
+
+void AppleObjCRuntime::Terminate() {
+ AppleObjCRuntimeV2::Terminate();
+ AppleObjCRuntimeV1::Terminate();
+}
+
bool AppleObjCRuntime::GetObjectDescription(Stream &str, ValueObject &valobj) {
CompilerType compiler_type(valobj.GetCompilerType());
bool is_signed;
@@ -105,13 +116,13 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
Target *target = exe_ctx.GetTargetPtr();
CompilerType compiler_type = value.GetCompilerType();
if (compiler_type) {
- if (!ClangASTContext::IsObjCObjectPointerType(compiler_type)) {
+ if (!TypeSystemClang::IsObjCObjectPointerType(compiler_type)) {
strm.Printf("Value doesn't point to an ObjC object.\n");
return false;
}
} else {
// If it is not a pointer, see if we can make it into a pointer.
- ClangASTContext *ast_context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target);
if (!ast_context)
return false;
@@ -126,7 +137,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
arg_value_list.PushValue(value);
// This is the return value:
- ClangASTContext *ast_context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target);
if (!ast_context)
return false;
@@ -239,7 +250,8 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() {
contexts.GetContextAtIndex(0, context);
- m_PrintForDebugger_addr.reset(new Address(context.symbol->GetAddress()));
+ m_PrintForDebugger_addr =
+ std::make_unique<Address>(context.symbol->GetAddress());
}
return m_PrintForDebugger_addr.get();
@@ -335,8 +347,8 @@ bool AppleObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) {
// Maybe check here and if we have a handler already, and the UUID of this
// module is the same as the one in the current module, then we don't have to
// reread it?
- m_objc_trampoline_handler_up.reset(
- new AppleObjCTrampolineHandler(m_process->shared_from_this(), module_sp));
+ m_objc_trampoline_handler_up = std::make_unique<AppleObjCTrampolineHandler>(
+ m_process->shared_from_this(), module_sp);
if (m_objc_trampoline_handler_up != nullptr) {
m_read_objc_library = true;
return true;
@@ -479,7 +491,7 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread(
auto descriptor = GetClassDescriptor(*cpp_exception);
if (!descriptor || !descriptor->IsValid()) return ValueObjectSP();
-
+
while (descriptor) {
ConstString class_name(descriptor->GetClassName());
if (class_name == "NSException")
@@ -490,19 +502,32 @@ ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread(
return ValueObjectSP();
}
+/// Utility method for error handling in GetBacktraceThreadFromException.
+/// \param msg The message to add to the log.
+/// \return An invalid ThreadSP to be returned from
+/// GetBacktraceThreadFromException.
+LLVM_NODISCARD
+static ThreadSP FailExceptionParsing(llvm::StringRef msg) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ LLDB_LOG(log, "Failed getting backtrace from exception: {0}", msg);
+ return ThreadSP();
+}
+
ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
lldb::ValueObjectSP exception_sp) {
ValueObjectSP reserved_dict =
exception_sp->GetChildMemberWithName(ConstString("reserved"), true);
- if (!reserved_dict) return ThreadSP();
+ if (!reserved_dict)
+ return FailExceptionParsing("Failed to get 'reserved' member.");
reserved_dict = reserved_dict->GetSyntheticValue();
- if (!reserved_dict) return ThreadSP();
+ if (!reserved_dict)
+ return FailExceptionParsing("Failed to get synthetic value.");
- ClangASTContext *clang_ast_context =
- ClangASTContext::GetScratch(*exception_sp->GetTargetSP());
+ TypeSystemClang *clang_ast_context =
+ TypeSystemClang::GetScratch(*exception_sp->GetTargetSP());
if (!clang_ast_context)
- return ThreadSP();
+ return FailExceptionParsing("Failed to get scratch AST.");
CompilerType objc_id =
clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID);
ValueObjectSP return_addresses;
@@ -527,8 +552,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
if (error.Fail()) return ThreadSP();
lldb::offset_t data_offset = 0;
- auto dict_entry_key = data.GetPointer(&data_offset);
- auto dict_entry_value = data.GetPointer(&data_offset);
+ auto dict_entry_key = data.GetAddress(&data_offset);
+ auto dict_entry_value = data.GetAddress(&data_offset);
auto key_nsstring = objc_object_from_address(dict_entry_key, "key");
StreamString key_summary;
@@ -543,15 +568,22 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
}
}
- if (!return_addresses) return ThreadSP();
+ if (!return_addresses)
+ return FailExceptionParsing("Failed to get return addresses.");
auto frames_value =
return_addresses->GetChildMemberWithName(ConstString("_frames"), true);
+ if (!frames_value)
+ return FailExceptionParsing("Failed to get frames_value.");
addr_t frames_addr = frames_value->GetValueAsUnsigned(0);
auto count_value =
return_addresses->GetChildMemberWithName(ConstString("_cnt"), true);
+ if (!count_value)
+ return FailExceptionParsing("Failed to get count_value.");
size_t count = count_value->GetValueAsUnsigned(0);
auto ignore_value =
return_addresses->GetChildMemberWithName(ConstString("_ignore"), true);
+ if (!ignore_value)
+ return FailExceptionParsing("Failed to get ignore_value.");
size_t ignore = ignore_value->GetValueAsUnsigned(0);
size_t ptr_size = m_process->GetAddressByteSize();
@@ -563,7 +595,8 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
pcs.push_back(pc);
}
- if (pcs.empty()) return ThreadSP();
+ if (pcs.empty())
+ return FailExceptionParsing("Failed to get PC list.");
ThreadSP new_thread_sp(new HistoryThread(*m_process, 0, pcs));
m_process->GetExtendedThreadList().AddThread(new_thread_sp);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index 79ac53e1e440..e9790871e8c4 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCRuntime_h_
-#define liblldb_AppleObjCRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
#include "llvm/ADT/Optional.h"
@@ -31,6 +31,10 @@ public:
static char ID;
+ static void Initialize();
+
+ static void Terminate();
+
bool isA(const void *ClassID) const override {
return ClassID == &ID || ObjCLanguageRuntime::isA(ClassID);
}
@@ -84,7 +88,7 @@ public:
bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
-
+
static std::tuple<FileSpec, ConstString> GetExceptionThrowLocation();
lldb::ValueObjectSP GetExceptionObjectForThread(
@@ -97,7 +101,7 @@ public:
virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
lldb::addr_t &cf_false);
-
+
virtual bool IsTaggedPointer (lldb::addr_t addr) { return false; }
protected:
@@ -128,4 +132,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_AppleObjCRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIME_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 88bfe2ce0203..8202686597ae 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -1,5 +1,4 @@
-//===-- AppleObjCRuntimeV1.cpp --------------------------------------*- C++
-//-*-===//
+//===-- AppleObjCRuntimeV1.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,12 +12,12 @@
#include "clang/AST/Type.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -106,8 +105,8 @@ ConstString AppleObjCRuntimeV1::GetPluginName() {
uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; }
BreakpointResolverSP
-AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
- bool throw_bp) {
+AppleObjCRuntimeV1::CreateExceptionResolver(const BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp) {
BreakpointResolverSP resolver_sp;
if (throw_bp)
@@ -363,7 +362,7 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
lldb::offset_t offset = addr_size; // Skip prototype
const uint32_t count = data.GetU32(&offset);
const uint32_t num_buckets = data.GetU32(&offset);
- const addr_t buckets_ptr = data.GetPointer(&offset);
+ const addr_t buckets_ptr = data.GetAddress(&offset);
if (m_hash_signature.NeedsUpdate(count, num_buckets, buckets_ptr)) {
m_hash_signature.UpdateSignature(count, num_buckets, buckets_ptr);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 6fdae63d4126..d8725d0f57ce 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCRuntimeV1_h_
-#define liblldb_AppleObjCRuntimeV1_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H
#include "AppleObjCRuntime.h"
#include "lldb/lldb-private.h"
@@ -113,9 +113,9 @@ public:
DeclVendor *GetDeclVendor() override;
protected:
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp) override;
class HashTableSignature {
public:
@@ -153,4 +153,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AppleObjCRuntimeV1_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV1_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 4015f10c4966..ac9a09394021 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -1,4 +1,4 @@
-//===-- AppleObjCRuntimeV2.cpp ----------------------------------*- C++ -*-===//
+//===-- AppleObjCRuntimeV2.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -15,12 +15,11 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/lldb-enumerations.h"
-#include "lldb/Core/ClangForward.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -35,7 +34,6 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/TypeList.h"
@@ -64,6 +62,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/TargetInfo.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
@@ -582,8 +581,8 @@ protected:
case 0:
break;
case 1: {
- regex_up.reset(new RegularExpression(
- llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))));
+ regex_up = std::make_unique<RegularExpression>(
+ llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)));
if (!regex_up->IsValid()) {
result.AppendError(
"invalid argument - please provide a valid regular expression");
@@ -826,8 +825,8 @@ lldb_private::ConstString AppleObjCRuntimeV2::GetPluginName() {
uint32_t AppleObjCRuntimeV2::GetPluginVersion() { return 1; }
BreakpointResolverSP
-AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
- bool throw_bp) {
+AppleObjCRuntimeV2::CreateExceptionResolver(const BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp) {
BreakpointResolverSP resolver_sp;
if (throw_bp)
@@ -897,12 +896,12 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
const char *ivar_name) {
uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET;
- const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
- if (class_name && class_name[0] && ivar_name && ivar_name[0]) {
+ ConstString class_name = parent_ast_type.GetTypeName();
+ if (!class_name.IsEmpty() && ivar_name && ivar_name[0]) {
// Make the objective C V2 mangled name for the ivar offset from the class
// name and ivar name
std::string buffer("OBJC_IVAR_$_");
- buffer.append(class_name);
+ buffer.append(class_name.AsCString());
buffer.push_back('.');
buffer.append(ivar_name);
ConstString ivar_const_str(buffer.c_str());
@@ -1176,6 +1175,28 @@ AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) {
return class_descriptor_sp;
}
+static std::pair<bool, ConstString> ObjCGetClassNameRaw(
+ AppleObjCRuntime::ObjCISA isa,
+ Process *process) {
+ StreamString expr_string;
+ std::string input = std::to_string(isa);
+ expr_string.Printf("(const char *)objc_debug_class_getNameRaw(%s)",
+ input.c_str());
+
+ ValueObjectSP result_sp;
+ EvaluateExpressionOptions eval_options;
+ eval_options.SetLanguage(lldb::eLanguageTypeObjC);
+ eval_options.SetResultIsInternal(true);
+ eval_options.SetGenerateDebugInfo(true);
+ eval_options.SetTimeout(process->GetUtilityExpressionTimeout());
+ auto eval_result = process->GetTarget().EvaluateExpression(
+ expr_string.GetData(),
+ process->GetThreadList().GetSelectedThread()->GetSelectedFrame().get(),
+ result_sp, eval_options);
+ ConstString type_name(result_sp->GetSummaryAsCString());
+ return std::make_pair(eval_result == eExpressionCompleted, type_name);
+}
+
ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
ClassDescriptorSP objc_class_sp;
@@ -1192,32 +1213,43 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
// if we get an invalid VO (which might still happen when playing around with
// pointers returned by the expression parser, don't consider this a valid
// ObjC object)
- if (valobj.GetCompilerType().IsValid()) {
- addr_t isa_pointer = valobj.GetPointerValue();
+ if (!valobj.GetCompilerType().IsValid())
+ return objc_class_sp;
+ addr_t isa_pointer = valobj.GetPointerValue();
- // tagged pointer
- if (IsTaggedPointer(isa_pointer)) {
- return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer);
- } else {
- ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+ // tagged pointer
+ if (IsTaggedPointer(isa_pointer))
+ return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer);
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process) {
- Status error;
- ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
- if (isa != LLDB_INVALID_ADDRESS) {
- objc_class_sp = GetClassDescriptorFromISA(isa);
- if (isa && !objc_class_sp) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- LLDB_LOGF(log,
- "0x%" PRIx64
- ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
- "not in class descriptor cache 0x%" PRIx64,
- isa_pointer, isa);
- }
- }
- }
- }
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return objc_class_sp;
+
+ Status error;
+ ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
+ if (isa == LLDB_INVALID_ADDRESS)
+ return objc_class_sp;
+
+ objc_class_sp = GetClassDescriptorFromISA(isa);
+
+ if (objc_class_sp)
+ return objc_class_sp;
+ else {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS |
+ LIBLLDB_LOG_TYPES));
+ LLDB_LOGF(log,
+ "0x%" PRIx64
+ ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+ "not in class descriptor cache 0x%" PRIx64,
+ isa_pointer, isa);
+ }
+
+ ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, nullptr));
+ auto resolved = ObjCGetClassNameRaw(isa, process);
+ if (resolved.first == true) {
+ AddClass(isa, descriptor_sp, resolved.second.AsCString());
+ objc_class_sp = descriptor_sp;
}
return objc_class_sp;
}
@@ -1301,7 +1333,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
return DescriptorMapUpdateResult::Fail();
thread_sp->CalculateExecutionContext(exe_ctx);
- ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget());
+ TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
if (!ast)
return DescriptorMapUpdateResult::Fail();
@@ -1434,8 +1466,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
Value return_value;
return_value.SetValueType(Value::eValueTypeScalar);
- // return_value.SetContext (Value::eContextTypeClangType,
- // clang_uint32_t_type);
return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
@@ -1499,7 +1529,7 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
// Iterate through all ClassInfo structures
lldb::offset_t offset = 0;
for (uint32_t i = 0; i < num_class_infos; ++i) {
- ObjCISA isa = data.GetPointer(&offset);
+ ObjCISA isa = data.GetAddress(&offset);
if (isa == 0) {
if (should_log)
@@ -1563,7 +1593,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
return DescriptorMapUpdateResult::Fail();
thread_sp->CalculateExecutionContext(exe_ctx);
- ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget());
+ TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
if (!ast)
return DescriptorMapUpdateResult::Fail();
@@ -1660,13 +1690,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
// Next make the function caller for our implementation utility function.
Value value;
value.SetValueType(Value::eValueTypeScalar);
- // value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
value.SetCompilerType(clang_void_pointer_type);
arguments.PushValue(value);
arguments.PushValue(value);
value.SetValueType(Value::eValueTypeScalar);
- // value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
value.SetCompilerType(clang_uint32_t_type);
arguments.PushValue(value);
arguments.PushValue(value);
@@ -1732,8 +1760,6 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
Value return_value;
return_value.SetValueType(Value::eValueTypeScalar);
- // return_value.SetContext (Value::eContextTypeClangType,
- // clang_uint32_t_type);
return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
@@ -1980,7 +2006,7 @@ void AppleObjCRuntimeV2::WarnIfNoClassesCached(
DeclVendor *AppleObjCRuntimeV2::GetDeclVendor() {
if (!m_decl_vendor_up)
- m_decl_vendor_up.reset(new AppleObjCDeclVendor(*this));
+ m_decl_vendor_up = std::make_unique<AppleObjCDeclVendor>(*this);
return m_decl_vendor_up.get();
}
@@ -2477,7 +2503,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
ObjCISA isa, ObjCISA &ret_isa) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
- LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
+ LLDB_LOGF(log, "AOCRT::NPI Evaluate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
if ((isa & ~m_objc_debug_isa_class_mask) == 0)
return false;
@@ -2550,7 +2576,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
lldb::offset_t offset = 0;
for (unsigned i = 0; i != num_new_classes; ++i)
- m_indexed_isa_cache.push_back(data.GetPointer(&offset));
+ m_indexed_isa_cache.push_back(data.GetAddress(&offset));
}
}
@@ -2558,7 +2584,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (index > m_indexed_isa_cache.size())
return false;
- LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
+ LLDB_LOGF(log, "AOCRT::NPI Evaluate(ret_isa = 0x%" PRIx64 ")",
(uint64_t)m_indexed_isa_cache[index]);
ret_isa = m_indexed_isa_cache[index];
@@ -2642,8 +2668,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
const lldb::ABISP &abi = process_sp->GetABI();
if (!abi) return;
- ClangASTContext *clang_ast_context =
- ClangASTContext::GetScratch(process_sp->GetTarget());
+ TypeSystemClang *clang_ast_context =
+ TypeSystemClang::GetScratch(process_sp->GetTarget());
if (!clang_ast_context)
return;
CompilerType voidstar =
@@ -2668,6 +2694,8 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
m_arguments = ValueObjectListSP(new ValueObjectList());
m_arguments->Append(exception);
+
+ m_stop_desc = "hit Objective-C exception";
}
ValueObjectSP exception;
@@ -2689,8 +2717,10 @@ static void RegisterObjCExceptionRecognizer() {
FileSpec module;
ConstString function;
std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
+ std::vector<ConstString> symbols = {function};
StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
- module.GetFilename(), function, /*first_instruction_only*/ true);
+ module.GetFilename(), symbols,
+ /*first_instruction_only*/ true);
});
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 785bb3938d2c..99264d556da5 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCRuntimeV2_h_
-#define liblldb_AppleObjCRuntimeV2_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
#include <map>
#include <memory>
@@ -103,9 +103,9 @@ public:
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
protected:
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
+ bool catch_bp, bool throw_bp) override;
private:
class HashTableSignature {
@@ -162,7 +162,8 @@ private:
friend class AppleObjCRuntimeV2;
- DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
+ NonPointerISACache(const NonPointerISACache &) = delete;
+ const NonPointerISACache &operator=(const NonPointerISACache &) = delete;
};
class TaggedPointerVendorV2
@@ -181,7 +182,9 @@ private:
: TaggedPointerVendor(), m_runtime(runtime) {}
private:
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
+ TaggedPointerVendorV2(const TaggedPointerVendorV2 &) = delete;
+ const TaggedPointerVendorV2 &
+ operator=(const TaggedPointerVendorV2 &) = delete;
};
class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
@@ -212,7 +215,10 @@ private:
friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
+ TaggedPointerVendorRuntimeAssisted(
+ const TaggedPointerVendorRuntimeAssisted &) = delete;
+ const TaggedPointerVendorRuntimeAssisted &
+ operator=(const TaggedPointerVendorRuntimeAssisted &) = delete;
};
class TaggedPointerVendorExtended
@@ -250,7 +256,9 @@ private:
friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
+ TaggedPointerVendorExtended(const TaggedPointerVendorExtended &) = delete;
+ const TaggedPointerVendorExtended &
+ operator=(const TaggedPointerVendorExtended &) = delete;
};
class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
@@ -266,7 +274,9 @@ private:
friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
+ TaggedPointerVendorLegacy(const TaggedPointerVendorLegacy &) = delete;
+ const TaggedPointerVendorLegacy &
+ operator=(const TaggedPointerVendorLegacy &) = delete;
};
struct DescriptorMapUpdateResult {
@@ -337,4 +347,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AppleObjCRuntimeV2_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index 36f95c063b81..c96768c9f585 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -1,5 +1,4 @@
-//===-- AppleObjCTrampolineHandler.cpp ----------------------------*- C++
-//-*-===//
+//===-- AppleObjCTrampolineHandler.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,6 +9,7 @@
#include "AppleObjCTrampolineHandler.h"
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -19,7 +19,6 @@
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/UtilityFunction.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
@@ -319,7 +318,7 @@ void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
const uint16_t descriptor_size = data.GetU16(&offset);
const size_t num_descriptors = data.GetU32(&offset);
- m_next_region = data.GetPointer(&offset);
+ m_next_region = data.GetAddress(&offset);
// If the header size is 0, that means we've come in too early before this
// data is set up.
@@ -521,8 +520,8 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
Process *process = exe_ctx.GetProcessPtr();
const ABI *abi = process->GetABI().get();
- ClangASTContext *clang_ast_context =
- ClangASTContext::GetScratch(process->GetTarget());
+ TypeSystemClang *clang_ast_context =
+ TypeSystemClang::GetScratch(process->GetTarget());
if (!clang_ast_context)
return false;
@@ -548,7 +547,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data,
nullptr);
lldb::offset_t offset = 0;
- lldb::addr_t region_addr = data.GetPointer(&offset);
+ lldb::addr_t region_addr = data.GetAddress(&offset);
if (region_addr != 0)
vtable_handler->ReadRegions(region_addr);
@@ -657,6 +656,27 @@ const AppleObjCTrampolineHandler::DispatchFunction
DispatchFunction::eFixUpFixed},
};
+// This is the table of ObjC "accelerated dispatch" functions. They are a set
+// of objc methods that are "seldom overridden" and so the compiler replaces the
+// objc_msgSend with a call to one of the dispatch functions. That will check
+// whether the method has been overridden, and directly call the Foundation
+// implementation if not.
+// This table is supposed to be complete. If ones get added in the future, we
+// will have to add them to the table.
+const char *AppleObjCTrampolineHandler::g_opt_dispatch_names[] = {
+ "objc_alloc",
+ "objc_autorelease",
+ "objc_release",
+ "objc_retain",
+ "objc_alloc_init",
+ "objc_allocWithZone",
+ "objc_opt_class",
+ "objc_opt_isKindOfClass",
+ "objc_opt_new",
+ "objc_opt_respondsToSelector",
+ "objc_opt_self",
+};
+
AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
const ProcessSP &process_sp, const ModuleSP &objc_module_sp)
: m_process_wp(), m_objc_module_sp(objc_module_sp),
@@ -751,9 +771,24 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i));
}
}
+
+ // Similarly, cache the addresses of the "optimized dispatch" function.
+ for (size_t i = 0; i != llvm::array_lengthof(g_opt_dispatch_names); i++) {
+ ConstString name_const_str(g_opt_dispatch_names[i]);
+ const Symbol *msgSend_symbol =
+ m_objc_module_sp->FindFirstSymbolWithNameAndType(name_const_str,
+ eSymbolTypeCode);
+ if (msgSend_symbol && msgSend_symbol->ValueIsAddress()) {
+ lldb::addr_t sym_addr =
+ msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target);
+
+ m_opt_dispatch_map.emplace(sym_addr, i);
+ }
+ }
// Build our vtable dispatch handler here:
- m_vtables_up.reset(new AppleObjCVTables(process_sp, m_objc_module_sp));
+ m_vtables_up =
+ std::make_unique<AppleObjCVTables>(process_sp, m_objc_module_sp);
if (m_vtables_up)
m_vtables_up->ReadRegions();
}
@@ -804,8 +839,8 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
}
// Next make the runner function for our implementation utility function.
- ClangASTContext *clang_ast_context =
- ClangASTContext::GetScratch(thread.GetProcess()->GetTarget());
+ TypeSystemClang *clang_ast_context =
+ TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget());
if (!clang_ast_context)
return LLDB_INVALID_ADDRESS;
@@ -846,45 +881,53 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
return args_addr;
}
+const AppleObjCTrampolineHandler::DispatchFunction *
+AppleObjCTrampolineHandler::FindDispatchFunction(lldb::addr_t addr) {
+ MsgsendMap::iterator pos;
+ pos = m_msgSend_map.find(addr);
+ if (pos != m_msgSend_map.end()) {
+ return &g_dispatch_functions[(*pos).second];
+ }
+ return nullptr;
+}
+
+void
+AppleObjCTrampolineHandler::ForEachDispatchFunction(
+ std::function<void(lldb::addr_t,
+ const DispatchFunction &)> callback) {
+ for (auto elem : m_msgSend_map) {
+ callback(elem.first, g_dispatch_functions[elem.second]);
+ }
+}
+
ThreadPlanSP
AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
bool stop_others) {
ThreadPlanSP ret_plan_sp;
lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();
- DispatchFunction this_dispatch;
- bool found_it = false;
+ DispatchFunction vtable_dispatch
+ = {"vtable", 0, false, false, DispatchFunction::eFixUpFixed};
// First step is to look and see if we are in one of the known ObjC
// dispatch functions. We've already compiled a table of same, so
// consult it.
- MsgsendMap::iterator pos;
- pos = m_msgSend_map.find(curr_pc);
- if (pos != m_msgSend_map.end()) {
- this_dispatch = g_dispatch_functions[(*pos).second];
- found_it = true;
- }
-
+ const DispatchFunction *this_dispatch = FindDispatchFunction(curr_pc);
+
// Next check to see if we are in a vtable region:
- if (!found_it) {
+ if (!this_dispatch && m_vtables_up) {
uint32_t flags;
- if (m_vtables_up) {
- found_it = m_vtables_up->IsAddressInVTables(curr_pc, flags);
- if (found_it) {
- this_dispatch.name = "vtable";
- this_dispatch.stret_return =
- (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) ==
- AppleObjCVTables::eOBJC_TRAMPOLINE_STRET;
- this_dispatch.is_super = false;
- this_dispatch.is_super2 = false;
- this_dispatch.fixedup = DispatchFunction::eFixUpFixed;
- }
+ if (m_vtables_up->IsAddressInVTables(curr_pc, flags)) {
+ vtable_dispatch.stret_return =
+ (flags & AppleObjCVTables::eOBJC_TRAMPOLINE_STRET) ==
+ AppleObjCVTables::eOBJC_TRAMPOLINE_STRET;
+ this_dispatch = &vtable_dispatch;
}
}
- if (found_it) {
+ if (this_dispatch) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
// We are decoding a method dispatch. First job is to pull the
@@ -901,7 +944,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
TargetSP target_sp(thread.CalculateTarget());
- ClangASTContext *clang_ast_context = ClangASTContext::GetScratch(*target_sp);
+ TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp);
if (!clang_ast_context)
return ret_plan_sp;
@@ -921,7 +964,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
// the return struct pointer, and the object is the second, and
// the selector is the third. Otherwise the object is the first
// and the selector the second.
- if (this_dispatch.stret_return) {
+ if (this_dispatch->stret_return) {
obj_index = 1;
sel_index = 2;
argument_values.PushValue(void_ptr_value);
@@ -963,8 +1006,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
// run-to-address plan directly. Otherwise we have to figure out
// where the implementation lives.
- if (this_dispatch.is_super) {
- if (this_dispatch.is_super2) {
+ if (this_dispatch->is_super) {
+ if (this_dispatch->is_super2) {
// In the objc_msgSendSuper2 case, we don't get the object
// directly, we get a structure containing the object and the
// class to which the super message is being sent. So we need
@@ -1087,25 +1130,25 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
// flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
flag_value.SetCompilerType(clang_int_type);
- if (this_dispatch.stret_return)
+ if (this_dispatch->stret_return)
flag_value.GetScalar() = 1;
else
flag_value.GetScalar() = 0;
dispatch_values.PushValue(flag_value);
- if (this_dispatch.is_super)
+ if (this_dispatch->is_super)
flag_value.GetScalar() = 1;
else
flag_value.GetScalar() = 0;
dispatch_values.PushValue(flag_value);
- if (this_dispatch.is_super2)
+ if (this_dispatch->is_super2)
flag_value.GetScalar() = 1;
else
flag_value.GetScalar() = 0;
dispatch_values.PushValue(flag_value);
- switch (this_dispatch.fixedup) {
+ switch (this_dispatch->fixedup) {
case DispatchFunction::eFixUpNone:
flag_value.GetScalar() = 0;
dispatch_values.PushValue(flag_value);
@@ -1135,7 +1178,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
// stop_others value passed in to us here:
const bool trampoline_stop_others = false;
ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>(
- thread, this, dispatch_values, isa_addr, sel_addr,
+ thread, *this, dispatch_values, isa_addr, sel_addr,
trampoline_stop_others);
if (log) {
StreamString s;
@@ -1144,6 +1187,26 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
}
}
}
+
+ // Finally, check if we have hit an "optimized dispatch" function. This will
+ // either directly call the base implementation or dispatch an objc_msgSend
+ // if the method has been overridden. So we just do a "step in/step out",
+ // setting a breakpoint on objc_msgSend, and if we hit the msgSend, we
+ // will automatically step in again. That's the job of the
+ // AppleThreadPlanStepThroughDirectDispatch.
+ if (!this_dispatch && !ret_plan_sp) {
+ MsgsendMap::iterator pos;
+ pos = m_opt_dispatch_map.find(curr_pc);
+ if (pos != m_opt_dispatch_map.end()) {
+
+ const char *opt_name = g_opt_dispatch_names[(*pos).second];
+
+ bool trampoline_stop_others = false;
+ LazyBool step_in_should_stop = eLazyBoolCalculate;
+ ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch> (
+ thread, *this, opt_name, trampoline_stop_others, step_in_should_stop);
+ }
+ }
return ret_plan_sp;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index d120d671eeb3..27aebd8594df 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_AppleObjCTrampolineHandler_h_
-#define lldb_AppleObjCTrampolineHandler_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
#include <map>
#include <mutex>
@@ -47,6 +47,9 @@ public:
lldb::addr_t SetupDispatchFunction(Thread &thread,
ValueList &dispatch_values);
+ const DispatchFunction *FindDispatchFunction(lldb::addr_t addr);
+ void ForEachDispatchFunction(std::function<void(lldb::addr_t,
+ const DispatchFunction &)>);
private:
static const char *g_lookup_implementation_function_name;
@@ -96,7 +99,6 @@ private:
void Dump(Stream &s);
- public:
bool m_valid;
AppleObjCVTables *m_owner;
lldb::addr_t m_header_addr;
@@ -136,11 +138,13 @@ private:
};
static const DispatchFunction g_dispatch_functions[];
+ static const char *g_opt_dispatch_names[];
- typedef std::map<lldb::addr_t, int> MsgsendMap; // This table maps an dispatch
+ using MsgsendMap = std::map<lldb::addr_t, int>; // This table maps an dispatch
// fn address to the index in
// g_dispatch_functions
MsgsendMap m_msgSend_map;
+ MsgsendMap m_opt_dispatch_map;
lldb::ProcessWP m_process_wp;
lldb::ModuleSP m_objc_module_sp;
const char *m_lookup_implementation_function_code;
@@ -155,4 +159,4 @@ private:
} // namespace lldb_private
-#endif // lldb_AppleObjCTrampolineHandler_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTRAMPOLINEHANDLER_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 66f04bef6cbd..b19d3d90d4b7 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -1,4 +1,4 @@
-//===-- AppleObjCTypeEncodingParser.cpp -------------------------*- C++ -*-===//
+//===-- AppleObjCTypeEncodingParser.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,13 +8,15 @@
#include "AppleObjCTypeEncodingParser.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StringLexer.h"
+#include "clang/Basic/TargetInfo.h"
+
#include <vector>
using namespace lldb_private;
@@ -23,17 +25,16 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
ObjCLanguageRuntime &runtime)
: ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) {
if (!m_scratch_ast_ctx_up)
- m_scratch_ast_ctx_up.reset(new ClangASTContext(runtime.GetProcess()
- ->GetTarget()
- .GetArchitecture()
- .GetTriple()));
+ m_scratch_ast_ctx_up = std::make_unique<TypeSystemClang>(
+ "AppleObjCTypeEncodingParser ASTContext",
+ runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple());
}
std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) {
StreamString buffer;
while (type.HasAtLeast(1) && type.Peek() != '=')
buffer.Printf("%c", type.Next());
- return buffer.GetString();
+ return std::string(buffer.GetString());
}
std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) {
@@ -43,7 +44,7 @@ std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) {
StringLexer::Character next = type.Next();
UNUSED_IF_ASSERT_DISABLED(next);
assert(next == '"');
- return buffer.GetString();
+ return std::string(buffer.GetString());
}
uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
@@ -61,7 +62,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement()
: name(""), type(clang::QualType()), bitfield(0) {}
AppleObjCTypeEncodingParser::StructElement
-AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx,
+AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
StringLexer &type,
bool for_expression) {
StructElement retval;
@@ -76,19 +77,19 @@ AppleObjCTypeEncodingParser::ReadStructElement(ClangASTContext &ast_ctx,
}
clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
- ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) {
+ TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '{', '}',
clang::TTK_Struct);
}
clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
- ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) {
+ TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '(', ')',
clang::TTK_Union);
}
clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
- ClangASTContext &ast_ctx, StringLexer &type, bool for_expression,
+ TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression,
char opener, char closer, uint32_t kind) {
if (!type.NextIf(opener))
return clang::QualType();
@@ -123,29 +124,30 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
return clang::QualType(); // This is where we bail out. Sorry!
CompilerType union_type(ast_ctx.CreateRecordType(
- nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
+ nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind,
+ lldb::eLanguageTypeC));
if (union_type) {
- ClangASTContext::StartTagDeclarationDefinition(union_type);
+ TypeSystemClang::StartTagDeclarationDefinition(union_type);
unsigned int count = 0;
for (auto element : elements) {
if (element.name.empty()) {
StreamString elem_name;
elem_name.Printf("__unnamed_%u", count);
- element.name = elem_name.GetString();
+ element.name = std::string(elem_name.GetString());
}
- ClangASTContext::AddFieldToRecordType(
+ TypeSystemClang::AddFieldToRecordType(
union_type, element.name.c_str(), ast_ctx.GetType(element.type),
lldb::eAccessPublic, element.bitfield);
++count;
}
- ClangASTContext::CompleteTagDeclarationDefinition(union_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(union_type);
}
return ClangUtil::GetQualType(union_type);
}
clang::QualType AppleObjCTypeEncodingParser::BuildArray(
- ClangASTContext &ast_ctx, StringLexer &type, bool for_expression) {
+ TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('['))
return clang::QualType();
uint32_t size = ReadNumber(type);
@@ -163,7 +165,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray(
// consume but ignore the type info and always return an 'id'; if anything,
// dynamic typing will resolve things for us anyway
clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
- ClangASTContext &clang_ast_ctx, StringLexer &type, bool for_expression) {
+ TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('@'))
return clang::QualType();
@@ -247,7 +249,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx,
+AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx,
StringLexer &type, bool for_expression,
uint32_t *bitfield_bit_size) {
if (!type.HasAtLeast(1))
@@ -353,7 +355,7 @@ AppleObjCTypeEncodingParser::BuildType(ClangASTContext &clang_ast_ctx,
}
}
-CompilerType AppleObjCTypeEncodingParser::RealizeType(ClangASTContext &ast_ctx,
+CompilerType AppleObjCTypeEncodingParser::RealizeType(TypeSystemClang &ast_ctx,
const char *name,
bool for_expression) {
if (name && name[0]) {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index e43711bf4ee4..9a108967e1ab 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AppleObjCTypeEncodingParser_h_
-#define liblldb_AppleObjCTypeEncodingParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H
#include "clang/AST/ASTContext.h"
@@ -22,7 +22,7 @@ public:
AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime);
~AppleObjCTypeEncodingParser() override = default;
- CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name,
+ CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name,
bool for_expression) override;
private:
@@ -35,29 +35,29 @@ private:
~StructElement() = default;
};
- clang::QualType BuildType(ClangASTContext &clang_ast_ctx, StringLexer &type,
+ clang::QualType BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type,
bool for_expression,
uint32_t *bitfield_bit_size = nullptr);
- clang::QualType BuildStruct(ClangASTContext &ast_ctx, StringLexer &type,
+ clang::QualType BuildStruct(TypeSystemClang &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildAggregate(ClangASTContext &clang_ast_ctx,
+ clang::QualType BuildAggregate(TypeSystemClang &clang_ast_ctx,
StringLexer &type, bool for_expression,
char opener, char closer, uint32_t kind);
- clang::QualType BuildUnion(ClangASTContext &ast_ctx, StringLexer &type,
+ clang::QualType BuildUnion(TypeSystemClang &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildArray(ClangASTContext &ast_ctx, StringLexer &type,
+ clang::QualType BuildArray(TypeSystemClang &ast_ctx, StringLexer &type,
bool for_expression);
std::string ReadStructName(StringLexer &type);
- StructElement ReadStructElement(ClangASTContext &ast_ctx, StringLexer &type,
+ StructElement ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildObjCObjectPointerType(ClangASTContext &clang_ast_ctx,
+ clang::QualType BuildObjCObjectPointerType(TypeSystemClang &clang_ast_ctx,
StringLexer &type,
bool for_expression);
@@ -70,4 +70,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_AppleObjCTypeEncodingParser_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index af630eee7265..653e007c7b5f 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -1,4 +1,4 @@
-//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp
+//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp-----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -29,7 +29,7 @@ using namespace lldb_private;
// ThreadPlanStepThroughObjCTrampoline constructor
AppleThreadPlanStepThroughObjCTrampoline::
AppleThreadPlanStepThroughObjCTrampoline(
- Thread &thread, AppleObjCTrampolineHandler *trampoline_handler,
+ Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
bool stop_others)
: ThreadPlan(ThreadPlan::eKindGeneric,
@@ -48,31 +48,30 @@ void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
// Setting up the memory space for the called function text might require
// allocations, i.e. a nested function call. This needs to be done as a
// PreResumeAction.
- m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller,
- (void *)this);
+ m_process.AddPreResumeAction(PreResumeInitializeFunctionCaller, (void *)this);
}
bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() {
if (!m_func_sp) {
DiagnosticManager diagnostics;
m_args_addr =
- m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
+ m_trampoline_handler.SetupDispatchFunction(GetThread(), m_input_values);
if (m_args_addr == LLDB_INVALID_ADDRESS) {
return false;
}
m_impl_function =
- m_trampoline_handler->GetLookupImplementationFunctionCaller();
+ m_trampoline_handler.GetLookupImplementationFunctionCaller();
ExecutionContext exc_ctx;
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetIgnoreBreakpoints(true);
options.SetStopOthers(m_stop_others);
- m_thread.CalculateExecutionContext(exc_ctx);
+ GetThread().CalculateExecutionContext(exc_ctx);
m_func_sp = m_impl_function->GetThreadPlanToCallFunction(
exc_ctx, m_args_addr, options, diagnostics);
m_func_sp->SetOkayToDiscard(true);
- m_thread.QueueThreadPlan(m_func_sp, false);
+ PushPlan(m_func_sp);
}
return true;
}
@@ -132,7 +131,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
if (!m_run_to_sp) {
Value target_addr_value;
ExecutionContext exc_ctx;
- m_thread.CalculateExecutionContext(exc_ctx);
+ GetThread().CalculateExecutionContext(exc_ctx);
m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr,
target_addr_value);
m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr);
@@ -145,19 +144,19 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
SetPlanComplete();
return true;
}
- if (m_trampoline_handler->AddrIsMsgForward(target_addr)) {
+ if (m_trampoline_handler.AddrIsMsgForward(target_addr)) {
LLDB_LOGF(log,
"Implementation lookup returned msgForward function: 0x%" PRIx64
", stopping.",
target_addr);
- SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
+ SymbolContext sc = GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
eSymbolContextEverything);
Status status;
const bool abort_other_plans = false;
const bool first_insn = true;
const uint32_t frame_idx = 0;
- m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop(
+ m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop(
abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion,
eVoteNoOpinion, frame_idx, status);
if (m_run_to_sp && status.Success())
@@ -180,11 +179,10 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
// Extract the target address from the value:
m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>(
- m_thread, target_so_addr, m_stop_others);
- m_thread.QueueThreadPlan(m_run_to_sp, false);
- m_run_to_sp->SetPrivate(true);
+ GetThread(), target_so_addr, m_stop_others);
+ PushPlan(m_run_to_sp);
return false;
- } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) {
+ } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) {
// Third stage, work the run to target plan.
SetPlanComplete();
return true;
@@ -199,3 +197,227 @@ bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {
}
bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; }
+
+// Objective-C uses optimized dispatch functions for some common and seldom
+// overridden methods. For instance
+// [object respondsToSelector:];
+// will get compiled to:
+// objc_opt_respondsToSelector(object);
+// This checks whether the selector has been overridden, directly calling the
+// implementation if it hasn't and calling objc_msgSend if it has.
+//
+// We need to get into the overridden implementation. We'll do that by
+// setting a breakpoint on objc_msgSend, and doing a "step out". If we stop
+// at objc_msgSend, we can step through to the target of the send, and see if
+// that's a place we want to stop.
+//
+// A couple of complexities. The checking code might call some other method,
+// so we might see objc_msgSend more than once. Also, these optimized dispatch
+// functions might dispatch more than one message at a time (e.g. alloc followed
+// by init.) So we can't give up at the first objc_msgSend.
+// That means among other things that we have to handle the "ShouldStopHere" -
+// since we can't just return control to the plan that's controlling us on the
+// first step.
+
+AppleThreadPlanStepThroughDirectDispatch ::
+ AppleThreadPlanStepThroughDirectDispatch(
+ Thread &thread, AppleObjCTrampolineHandler &handler,
+ llvm::StringRef dispatch_func_name, bool stop_others,
+ LazyBool step_in_avoids_code_without_debug_info)
+ : ThreadPlanStepOut(thread, nullptr, true /* first instruction */,
+ stop_others, eVoteNoOpinion, eVoteNoOpinion,
+ 0 /* Step out of zeroth frame */,
+ eLazyBoolNo /* Our parent plan will decide this
+ when we are done */
+ ,
+ true /* Run to branch for inline step out */,
+ false /* Don't gather the return value */),
+ m_trampoline_handler(handler),
+ m_dispatch_func_name(std::string(dispatch_func_name)),
+ m_at_msg_send(false), m_stop_others(stop_others) {
+ // Set breakpoints on the dispatch functions:
+ auto bkpt_callback = [&] (lldb::addr_t addr,
+ const AppleObjCTrampolineHandler
+ ::DispatchFunction &dispatch) {
+ m_msgSend_bkpts.push_back(GetTarget().CreateBreakpoint(addr,
+ true /* internal */,
+ false /* hard */));
+ m_msgSend_bkpts.back()->SetThreadID(GetThread().GetID());
+ };
+ handler.ForEachDispatchFunction(bkpt_callback);
+
+ // We'll set the step-out plan in the DidPush so it gets queued in the right
+ // order.
+
+ bool avoid_nodebug = true;
+
+ switch (step_in_avoids_code_without_debug_info) {
+ case eLazyBoolYes:
+ avoid_nodebug = true;
+ break;
+ case eLazyBoolNo:
+ avoid_nodebug = false;
+ break;
+ case eLazyBoolCalculate:
+ avoid_nodebug = GetThread().GetStepInAvoidsNoDebug();
+ break;
+ }
+ if (avoid_nodebug)
+ GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
+ else
+ GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
+ // We only care about step in. Our parent plan will figure out what to
+ // do when we've stepped out again.
+ GetFlags().Clear(ThreadPlanShouldStopHere::eStepOutAvoidNoDebug);
+}
+
+AppleThreadPlanStepThroughDirectDispatch::
+ ~AppleThreadPlanStepThroughDirectDispatch() {
+ for (BreakpointSP bkpt_sp : m_msgSend_bkpts) {
+ GetTarget().RemoveBreakpointByID(bkpt_sp->GetID());
+ }
+}
+
+void AppleThreadPlanStepThroughDirectDispatch::GetDescription(
+ Stream *s, lldb::DescriptionLevel level) {
+ switch (level) {
+ case lldb::eDescriptionLevelBrief:
+ s->PutCString("Step through ObjC direct dispatch function.");
+ break;
+ default:
+ s->Printf("Step through ObjC direct dispatch '%s' using breakpoints: ",
+ m_dispatch_func_name.c_str());
+ bool first = true;
+ for (auto bkpt_sp : m_msgSend_bkpts) {
+ if (!first) {
+ s->PutCString(", ");
+ }
+ first = false;
+ s->Printf("%d", bkpt_sp->GetID());
+ }
+ (*s) << ".";
+ break;
+ }
+}
+
+bool
+AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) {
+ if (ThreadPlanStepOut::DoPlanExplainsStop(event_ptr))
+ return true;
+
+ StopInfoSP stop_info_sp = GetPrivateStopInfo();
+
+ // Check if the breakpoint is one of ours msgSend dispatch breakpoints.
+
+ StopReason stop_reason = eStopReasonNone;
+ if (stop_info_sp)
+ stop_reason = stop_info_sp->GetStopReason();
+
+ // See if this is one of our msgSend breakpoints:
+ if (stop_reason == eStopReasonBreakpoint) {
+ ProcessSP process_sp = GetThread().GetProcess();
+ uint64_t break_site_id = stop_info_sp->GetValue();
+ BreakpointSiteSP site_sp
+ = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
+ // Some other plan might have deleted the site's last owner before this
+ // got to us. In which case, it wasn't our breakpoint...
+ if (!site_sp)
+ return false;
+
+ for (BreakpointSP break_sp : m_msgSend_bkpts) {
+ if (site_sp->IsBreakpointAtThisSite(break_sp->GetID())) {
+ // If we aren't the only one with a breakpoint on this site, then we
+ // should just stop and return control to the user.
+ if (site_sp->GetNumberOfOwners() > 1) {
+ SetPlanComplete(true);
+ return false;
+ }
+ m_at_msg_send = true;
+ return true;
+ }
+ }
+ }
+
+ // We're done here. If one of our sub-plans explained the stop, they
+ // would have already answered true to PlanExplainsStop, and if they were
+ // done, we'll get called to figure out what to do in ShouldStop...
+ return false;
+}
+
+bool AppleThreadPlanStepThroughDirectDispatch
+ ::DoWillResume(lldb::StateType resume_state, bool current_plan) {
+ ThreadPlanStepOut::DoWillResume(resume_state, current_plan);
+ m_at_msg_send = false;
+ return true;
+}
+
+bool AppleThreadPlanStepThroughDirectDispatch::ShouldStop(Event *event_ptr) {
+ // If step out plan finished, that means we didn't find our way into a method
+ // implementation. Either we went directly to the default implementation,
+ // of the overridden implementation didn't have debug info.
+ // So we should mark ourselves as done.
+ const bool step_out_should_stop = ThreadPlanStepOut::ShouldStop(event_ptr);
+ if (step_out_should_stop) {
+ SetPlanComplete(true);
+ return true;
+ }
+
+ // If we have a step through plan, then w're in the process of getting
+ // through an ObjC msgSend. If we arrived at the target function, then
+ // check whether we have debug info, and if we do, stop.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
+ if (m_objc_step_through_sp && m_objc_step_through_sp->IsPlanComplete()) {
+ // If the plan failed for some reason, we should probably just let the
+ // step over plan get us out of here... We don't need to do anything about
+ // the step through plan, it is done and will get popped when we continue.
+ if (!m_objc_step_through_sp->PlanSucceeded()) {
+ LLDB_LOGF(log, "ObjC Step through plan failed. Stepping out.");
+ }
+ Status error;
+ if (InvokeShouldStopHereCallback(eFrameCompareYounger, error)) {
+ SetPlanComplete(true);
+ return true;
+ }
+ // If we didn't want to stop at this msgSend, there might be another so
+ // we should just continue on with the step out and see if our breakpoint
+ // triggers again.
+ m_objc_step_through_sp.reset();
+ for (BreakpointSP bkpt_sp : m_msgSend_bkpts) {
+ bkpt_sp->SetEnabled(true);
+ }
+ return false;
+ }
+
+ // If we hit an msgSend breakpoint, then we should queue the step through
+ // plan:
+
+ if (m_at_msg_send) {
+ LanguageRuntime *objc_runtime
+ = GetThread().GetProcess()->GetLanguageRuntime(eLanguageTypeObjC);
+ // There's no way we could have gotten here without an ObjC language
+ // runtime.
+ assert(objc_runtime);
+ m_objc_step_through_sp
+ = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others);
+ // If we failed to find the target for this dispatch, just keep going and
+ // let the step out complete.
+ if (!m_objc_step_through_sp) {
+ LLDB_LOG(log, "Couldn't find target for message dispatch, continuing.");
+ return false;
+ }
+ // Otherwise push the step through plan and continue.
+ GetThread().QueueThreadPlan(m_objc_step_through_sp, false);
+ for (BreakpointSP bkpt_sp : m_msgSend_bkpts) {
+ bkpt_sp->SetEnabled(false);
+ }
+ return false;
+ }
+ return true;
+}
+
+bool AppleThreadPlanStepThroughDirectDispatch::MischiefManaged() {
+ if (IsPlanComplete())
+ return true;
+ return ThreadPlanStepOut::MischiefManaged();
+}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 96f37851a35f..89aed89f1ab1 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_
-#define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H
#include "AppleObjCTrampolineHandler.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-types.h"
@@ -20,7 +23,7 @@ namespace lldb_private {
class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan {
public:
AppleThreadPlanStepThroughObjCTrampoline(
- Thread &thread, AppleObjCTrampolineHandler *trampoline_handler,
+ Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
bool stop_others);
@@ -52,25 +55,62 @@ protected:
private:
bool InitializeFunctionCaller();
- AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this
- // doesn't go away on us?
- // SP maybe?
- lldb::addr_t m_args_addr; // Stores the address for our step through function
- // result structure.
- // lldb::addr_t m_object_addr; // This is only for Description.
+ AppleObjCTrampolineHandler &m_trampoline_handler; /// The handler itself.
+ lldb::addr_t m_args_addr; /// Stores the address for our step through function
+ /// result structure.
ValueList m_input_values;
- lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to
- // cache the implementation.
+ lldb::addr_t m_isa_addr; /// isa_addr and sel_addr are the keys we will use to
+ /// cache the implementation.
lldb::addr_t m_sel_addr;
- lldb::ThreadPlanSP m_func_sp; // This is the function call plan. We fill it
- // at start, then set it
- // to NULL when this plan is done. That way we know to go to:
- lldb::ThreadPlanSP m_run_to_sp; // The plan that runs to the target.
- FunctionCaller *m_impl_function; // This is a pointer to a impl function that
- // is owned by the client that pushes this plan.
- bool m_stop_others;
+ lldb::ThreadPlanSP m_func_sp; /// This is the function call plan. We fill it
+ /// at start, then set it to NULL when this plan
+ /// is done. That way we know to go on to:
+ lldb::ThreadPlanSP m_run_to_sp; /// The plan that runs to the target.
+ FunctionCaller *m_impl_function; /// This is a pointer to a impl function that
+ /// is owned by the client that pushes this
+ /// plan.
+ bool m_stop_others; /// Whether we should stop other threads.
+};
+
+class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut {
+public:
+ AppleThreadPlanStepThroughDirectDispatch(
+ Thread &thread, AppleObjCTrampolineHandler &handler,
+ llvm::StringRef dispatch_func_name, bool stop_others,
+ LazyBool step_in_avoids_code_without_debug_info);
+
+ ~AppleThreadPlanStepThroughDirectDispatch() override;
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
+
+ bool ShouldStop(Event *event_ptr) override;
+
+ bool StopOthers() override { return m_stop_others; }
+
+ bool MischiefManaged() override;
+
+ bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
+
+ void SetFlagsToDefault() override {
+ GetFlags().Set(ThreadPlanStepInRange::GetDefaultFlagsValue());
+ }
+
+protected:
+ bool DoPlanExplainsStop(Event *event_ptr) override;
+
+ AppleObjCTrampolineHandler &m_trampoline_handler;
+ std::string m_dispatch_func_name; /// Which dispatch function we're stepping
+ /// through.
+ lldb::ThreadPlanSP m_objc_step_through_sp; /// When we hit an objc_msgSend,
+ /// we'll use this plan to get to
+ /// its target.
+ std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc
+ /// dispatch functions.
+ bool m_at_msg_send; /// Are we currently handling an msg_send
+ bool m_stop_others; /// Whether we should stop other threads.
+
};
} // namespace lldb_private
-#endif // lldb_AppleThreadPlanStepThroughObjCTrampoline_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 9eb493f83c84..2ccf9b33f9d8 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -1,4 +1,4 @@
-//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
+//===-- ObjCLanguageRuntime.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,11 +9,11 @@
#include "ObjCLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/MappedHash.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
@@ -41,7 +41,7 @@ ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process)
m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(),
m_negative_complete_class_cache() {}
-bool ObjCLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) {
+bool ObjCLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
static ConstString g_self = ConstString("self");
static ConstString g_cmd = ConstString("_cmd");
return name == g_self || name == g_cmd;
@@ -127,9 +127,9 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
for (uint32_t i = 0; i < types.GetSize(); ++i) {
TypeSP type_sp(types.GetTypeAtIndex(i));
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ if (TypeSystemClang::IsObjCObjectOrInterfaceType(
type_sp->GetForwardCompilerType())) {
- if (type_sp->IsCompleteObjCClass()) {
+ if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) {
m_complete_class_cache[name] = type_sp;
return type_sp;
}
@@ -387,9 +387,9 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
CompilerType class_type;
bool is_pointer_type = false;
- if (ClangASTContext::IsObjCObjectPointerType(base_type, &class_type))
+ if (TypeSystemClang::IsObjCObjectPointerType(base_type, &class_type))
is_pointer_type = true;
- else if (ClangASTContext::IsObjCObjectOrInterfaceType(base_type))
+ else if (TypeSystemClang::IsObjCObjectOrInterfaceType(base_type))
class_type = base_type;
else
return llvm::None;
@@ -397,7 +397,7 @@ ObjCLanguageRuntime::GetRuntimeType(CompilerType base_type) {
if (!class_type)
return llvm::None;
- ConstString class_name(class_type.GetConstTypeName());
+ ConstString class_name(class_type.GetTypeName());
if (!class_name)
return llvm::None;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index b9a4d5dae08a..c43acf54bbcd 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjCLanguageRuntime_h_
-#define liblldb_ObjCLanguageRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H
#include <functional>
#include <map>
@@ -17,7 +17,6 @@
#include "llvm/Support/Casting.h"
#include "lldb/Breakpoint/BreakpointPrecondition.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Symbol/CompilerType.h"
@@ -29,6 +28,7 @@ class CommandObjectObjC_ClassTable_Dump;
namespace lldb_private {
+class TypeSystemClang;
class UtilityFunction;
class ObjCLanguageRuntime : public LanguageRuntime {
@@ -144,12 +144,12 @@ public:
public:
virtual ~EncodingToType();
- virtual CompilerType RealizeType(ClangASTContext &ast_ctx, const char *name,
+ virtual CompilerType RealizeType(TypeSystemClang &ast_ctx, const char *name,
bool for_expression) = 0;
virtual CompilerType RealizeType(const char *name, bool for_expression);
protected:
- std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_up;
+ std::unique_ptr<TypeSystemClang> m_scratch_ast_ctx_up;
};
class ObjCExceptionPrecondition : public BreakpointPrecondition {
@@ -186,7 +186,8 @@ public:
TaggedPointerVendor() = default;
private:
- DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor);
+ TaggedPointerVendor(const TaggedPointerVendor &) = delete;
+ const TaggedPointerVendor &operator=(const TaggedPointerVendor &) = delete;
};
~ObjCLanguageRuntime() override;
@@ -299,7 +300,7 @@ public:
/// Check whether the name is "self" or "_cmd" and should show up in
/// "frame variable".
- bool IsWhitelistedRuntimeValue(ConstString name) override;
+ bool IsAllowedRuntimeValue(ConstString name) override;
protected:
// Classes that inherit from ObjCLanguageRuntime can see and modify these
@@ -417,9 +418,10 @@ protected:
void ReadObjCLibraryIfNeeded(const ModuleList &module_list);
- DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime);
+ ObjCLanguageRuntime(const ObjCLanguageRuntime &) = delete;
+ const ObjCLanguageRuntime &operator=(const ObjCLanguageRuntime &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_ObjCLanguageRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_OBJCLANGUAGERUNTIME_H
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index b396781e6726..6858c7134d33 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -1,4 +1,4 @@
-//===-- RenderScriptExpressionOpts.cpp --------------------------*- C++ -*-===//
+//===-- RenderScriptExpressionOpts.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -86,7 +86,7 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
llvm::StringRef real_triple =
m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple();
const llvm::Target *target_info =
- llvm::TargetRegistry::lookupTarget(real_triple, err);
+ llvm::TargetRegistry::lookupTarget(std::string(real_triple), err);
if (!target_info) {
if (log)
log->Warning("couldn't determine real target architecture: '%s'",
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
index 3ec4e37b6db0..52da677128e2 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_RENDERSCRIPT_EXPROPTS_H
-#define LLDB_RENDERSCRIPT_EXPROPTS_H
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 4edb8dec6082..dd9312234d8b 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -1,4 +1,4 @@
-//===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===//
+//===-- RenderScriptRuntime.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -46,6 +46,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_renderscript;
+LLDB_PLUGIN_DEFINE(RenderScriptRuntime)
+
#define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")"
char RenderScriptRuntime::ID = 0;
@@ -791,6 +793,9 @@ RenderScriptRuntime::CreateInstance(Process *process,
Searcher::CallbackReturn
RSBreakpointResolver::SearchCallback(SearchFilter &filter,
SymbolContext &context, Address *) {
+ BreakpointSP breakpoint_sp = GetBreakpoint();
+ assert(breakpoint_sp);
+
ModuleSP module = context.module_sp;
if (!module || !IsRenderScriptScriptModule(module))
@@ -811,7 +816,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
if (kernel_sym) {
Address bp_addr = kernel_sym->GetAddress();
if (filter.AddressPasses(bp_addr))
- m_breakpoint->AddLocation(bp_addr);
+ breakpoint_sp->AddLocation(bp_addr);
}
return Searcher::eCallbackReturnContinue;
@@ -821,6 +826,9 @@ Searcher::CallbackReturn
RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
lldb_private::SymbolContext &context,
Address *) {
+ BreakpointSP breakpoint_sp = GetBreakpoint();
+ assert(breakpoint_sp);
+
// We need to have access to the list of reductions currently parsed, as
// reduce names don't actually exist as symbols in a module. They are only
// identifiable by parsing the .rs.info packet, or finding the expand symbol.
@@ -867,7 +875,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
if (!SkipPrologue(module, address)) {
LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
}
- m_breakpoint->AddLocation(address, &new_bp);
+ breakpoint_sp->AddLocation(address, &new_bp);
LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s",
__FUNCTION__, new_bp ? "new" : "existing",
kernel_name.GetCString(),
@@ -882,7 +890,8 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
SearchFilter &filter, SymbolContext &context, Address *addr) {
- if (!m_breakpoint)
+ BreakpointSP breakpoint_sp = GetBreakpoint();
+ if (!breakpoint_sp)
return eCallbackReturnContinue;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
@@ -892,7 +901,8 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
return Searcher::eCallbackReturnContinue;
std::vector<std::string> names;
- m_breakpoint->GetNames(names);
+ Breakpoint& breakpoint = *breakpoint_sp;
+ breakpoint.GetNames(names);
if (names.empty())
return eCallbackReturnContinue;
@@ -932,7 +942,7 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
}
bool new_bp;
- m_breakpoint->AddLocation(address, &new_bp);
+ breakpoint.AddLocation(address, &new_bp);
LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__,
new_bp ? "new " : "", k.m_name.AsCString());
@@ -1029,8 +1039,8 @@ bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
}
lldb::BreakpointResolverSP
-RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bp, bool catch_bp,
- bool throw_bp) {
+RenderScriptRuntime::CreateExceptionResolver(const lldb::BreakpointSP &bp,
+ bool catch_bp, bool throw_bp) {
BreakpointResolverSP resolver_sp;
return resolver_sp;
}
@@ -1513,7 +1523,7 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
script->type = ScriptDetails::eScriptC;
script->cache_dir = cache_dir;
script->res_name = res_name;
- script->shared_lib = strm.GetString();
+ script->shared_lib = std::string(strm.GetString());
script->context = addr_t(args[eRsContext]);
}
@@ -3129,7 +3139,7 @@ void RenderScriptRuntime::DumpKernels(Stream &strm) const {
strm.Printf("Resource '%s':", module->m_resname.c_str());
strm.EOL();
for (const auto &kernel : module->m_kernels) {
- strm.Indent(kernel.m_name.AsCString());
+ strm.Indent(kernel.m_name.GetStringRef());
strm.EOL();
}
}
@@ -3939,9 +3949,10 @@ void RSModuleDescriptor::Dump(Stream &strm) const {
}
void RSGlobalDescriptor::Dump(Stream &strm) const {
- strm.Indent(m_name.AsCString());
+ strm.Indent(m_name.GetStringRef());
VariableList var_list;
- m_module->m_module->FindGlobalVariables(m_name, nullptr, 1U, var_list);
+ m_module->m_module->FindGlobalVariables(m_name, CompilerDeclContext(), 1U,
+ var_list);
if (var_list.GetSize() == 1) {
auto var = var_list.GetVariableAtIndex(0);
auto type = var->GetType();
@@ -3964,12 +3975,12 @@ void RSGlobalDescriptor::Dump(Stream &strm) const {
}
void RSKernelDescriptor::Dump(Stream &strm) const {
- strm.Indent(m_name.AsCString());
+ strm.Indent(m_name.GetStringRef());
strm.EOL();
}
void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const {
- stream.Indent(m_reduce_name.AsCString());
+ stream.Indent(m_reduce_name.GetStringRef());
stream.IndentMore();
stream.EOL();
stream.Indent();
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index c3740ba55a11..5e3726548369 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RenderScriptRuntime_h_
-#define liblldb_RenderScriptRuntime_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
#include <array>
#include <map>
@@ -24,6 +24,10 @@
#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
+namespace clang {
+class TargetOptions;
+}
+
namespace lldb_private {
namespace lldb_renderscript {
@@ -54,7 +58,7 @@ struct RSCoordinate {
// for .expand kernels as a fallback.
class RSBreakpointResolver : public BreakpointResolver {
public:
- RSBreakpointResolver(Breakpoint *bp, ConstString name)
+ RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name)
: BreakpointResolver(bp, BreakpointResolver::NameResolver),
m_kernel_name(name) {}
@@ -73,9 +77,9 @@ public:
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
- CopyForBreakpoint(Breakpoint &breakpoint) override {
+ CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
lldb::BreakpointResolverSP ret_sp(
- new RSBreakpointResolver(&breakpoint, m_kernel_name));
+ new RSBreakpointResolver(breakpoint, m_kernel_name));
return ret_sp;
}
@@ -96,7 +100,7 @@ public:
};
RSReduceBreakpointResolver(
- Breakpoint *breakpoint, ConstString reduce_name,
+ const lldb::BreakpointSP &breakpoint, ConstString reduce_name,
std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules,
int kernel_types = eKernelTypeAll)
: BreakpointResolver(breakpoint, BreakpointResolver::NameResolver),
@@ -123,9 +127,9 @@ public:
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
- CopyForBreakpoint(Breakpoint &breakpoint) override {
+ CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver(
- &breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
+ breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
return ret_sp;
}
@@ -246,7 +250,8 @@ typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList;
class RSScriptGroupBreakpointResolver : public BreakpointResolver {
public:
- RSScriptGroupBreakpointResolver(Breakpoint *bp, ConstString name,
+ RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp,
+ ConstString name,
const RSScriptGroupList &groups,
bool stop_on_all)
: BreakpointResolver(bp, BreakpointResolver::NameResolver),
@@ -268,9 +273,9 @@ public:
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
- CopyForBreakpoint(Breakpoint &breakpoint) override {
+ CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver(
- &breakpoint, m_group_name, m_script_groups, m_stop_on_all));
+ breakpoint, m_group_name, m_script_groups, m_stop_on_all));
return ret_sp;
}
@@ -343,9 +348,9 @@ public:
bool CouldHaveDynamicValue(ValueObject &in_value) override;
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bp,
- bool catch_bp,
- bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(const lldb::BreakpointSP &bp,
+ bool catch_bp, bool throw_bp) override;
bool LoadModule(const lldb::ModuleSP &module_sp);
@@ -402,6 +407,8 @@ public:
return false;
}
+ bool GetOverrideExprOptions(clang::TargetOptions &prototype);
+
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -421,7 +428,8 @@ protected:
void InitSearchFilter(lldb::TargetSP target) {
if (!m_filtersp)
- m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
+ m_filtersp =
+ std::make_shared<SearchFilterForUnconstrainedSearches>(target);
}
void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
@@ -577,11 +585,9 @@ private:
// any previous stored allocation which has the same address.
AllocationDetails *CreateAllocation(lldb::addr_t address);
- bool GetOverrideExprOptions(clang::TargetOptions &prototype) override;
-
bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override;
};
} // namespace lldb_private
-#endif // liblldb_RenderScriptRuntime_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
index 45d0d028d047..b6f8b20c90c3 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp
@@ -1,4 +1,4 @@
-//===-- RenderScriptScriptGroup.cpp -----------------------------*- C++ -*-===//
+//===-- RenderScriptScriptGroup.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
index c25e240f6d52..03d3a7823a98 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RenderScriptScriptGroup_h_
-#define liblldb_RenderScriptScriptGroup_h_
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H
#include "lldb/Interpreter/CommandInterpreter.h"
lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(
lldb_private::CommandInterpreter &interpreter);
-#endif // liblldb_RenderScriptScriptGroup_h_
+#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
index 4ddff3ad9c4c..f51190e0c82c 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -1,4 +1,4 @@
-//===-- RenderScriptx86ABIFixups.cpp ----------------------------*- C++ -*-===//
+//===-- RenderScriptx86ABIFixups.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,7 +10,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
@@ -158,12 +157,11 @@ bool fixupX86StructRetCalls(llvm::Module &module) {
assert(new_func_type &&
"failed to clone functionType for Renderscript ABI fixup");
- llvm::CallSite call_site(call_inst);
llvm::Function *func = call_inst->getCalledFunction();
assert(func && "cannot resolve function in RenderScriptRuntime");
// Copy the original call arguments
- std::vector<llvm::Value *> new_call_args(call_site.arg_begin(),
- call_site.arg_end());
+ std::vector<llvm::Value *> new_call_args(call_inst->arg_begin(),
+ call_inst->arg_end());
// Allocate enough space to store the return value of the original function
// we pass a pointer to this allocation as the StructRet param, and then
@@ -189,15 +187,17 @@ bool fixupX86StructRetCalls(llvm::Module &module) {
->setName("new_func_ptr_load_cast");
// load the new function address ready for a jump
llvm::LoadInst *new_func_addr_load =
- new llvm::LoadInst(new_func_ptr, "load_func_pointer", call_inst);
+ new llvm::LoadInst(new_func_ptr->getType()->getPointerElementType(),
+ new_func_ptr, "load_func_pointer", call_inst);
// and create a callinstruction from it
llvm::CallInst *new_call_inst =
llvm::CallInst::Create(new_func_type, new_func_addr_load, new_call_args,
"new_func_call", call_inst);
new_call_inst->setCallingConv(call_inst->getCallingConv());
new_call_inst->setTailCall(call_inst->isTailCall());
- llvm::LoadInst *lldb_save_result_address =
- new llvm::LoadInst(return_value_alloc, "save_return_val", call_inst);
+ llvm::LoadInst *lldb_save_result_address = new llvm::LoadInst(
+ return_value_alloc->getType()->getPointerElementType(),
+ return_value_alloc, "save_return_val", call_inst);
// Now remove the old broken call
call_inst->replaceAllUsesWith(lldb_save_result_address);
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h
index a5efc999aea4..7836fff4a3a9 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_RENDERSCRIPT_X86_H
-#define LLDB_RENDERSCRIPT_X86_H
+#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H
+#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H
#include "llvm/IR/Module.h"
diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
index e0d2c5d0eef8..333113a0b17a 100644
--- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
+++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
@@ -1,4 +1,4 @@
-//===-- MemoryHistoryASan.cpp -----------------------------------*- C++ -*-===//
+//===-- MemoryHistoryASan.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -28,6 +28,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(MemoryHistoryASan)
+
MemoryHistorySP MemoryHistoryASan::CreateInstance(const ProcessSP &process_sp) {
if (!process_sp.get())
return nullptr;
@@ -136,7 +138,12 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp,
pcs.push_back(pc);
}
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs);
+ // The ASAN runtime already massages the return addresses into call
+ // addresses, we don't want LLDB's unwinder to try to locate the previous
+ // instruction again as this might lead to us reporting a different line.
+ bool pcs_are_call_addresses = true;
+ HistoryThread *history_thread =
+ new HistoryThread(*process_sp, tid, pcs, pcs_are_call_addresses);
ThreadSP new_thread_sp(history_thread);
std::ostringstream thread_name_with_number;
thread_name_with_number << thread_name << " Thread " << tid;
diff --git a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
index 266576b0cd96..e9fe37d344a4 100644
--- a/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
+++ b/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_MemoryHistoryASan_h_
-#define liblldb_MemoryHistoryASan_h_
+#ifndef LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H
+#define LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H
#include "lldb/Target/ABI.h"
#include "lldb/Target/MemoryHistory.h"
@@ -45,4 +45,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_MemoryHistoryASan_h_
+#endif // LLDB_SOURCE_PLUGINS_MEMORYHISTORY_ASAN_MEMORYHISTORYASAN_H
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 512b5bebf07f..83cf9f8bd269 100644
--- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -1,4 +1,4 @@
-//===-- ObjectContainerBSDArchive.cpp ---------------------------*- C++ -*-===//
+//===-- ObjectContainerBSDArchive.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -40,6 +40,8 @@ typedef struct ar_hdr {
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive)
+
ObjectContainerBSDArchive::Object::Object()
: ar_name(), modification_time(0), uid(0), gid(0), mode(0), size(0),
file_offset(0), file_size(0) {}
@@ -86,7 +88,7 @@ ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data,
return LLDB_INVALID_OFFSET;
str.assign((const char *)data.GetData(&offset, 16), 16);
- if (str.find("#1/") == 0) {
+ if (llvm::StringRef(str).startswith("#1/")) {
// If the name is longer than 16 bytes, or contains an embedded space then
// it will use this format where the length of the name is here and the
// name characters are after this header.
diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index 5d9c01315a66..f6862afff8a0 100644
--- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjectContainerBSDArchive_h_
-#define liblldb_ObjectContainerBSDArchive_h_
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H
+#define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ObjectContainer.h"
@@ -174,4 +174,4 @@ protected:
Archive::shared_ptr m_archive_sp;
};
-#endif // liblldb_ObjectContainerBSDArchive_h_
+#endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index b83b2efb492f..bd8eeedce57d 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -1,4 +1,4 @@
-//===-- BreakpadRecords.cpp ----------------------------------- -*- C++ -*-===//
+//===-- BreakpadRecords.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -205,7 +205,7 @@ llvm::Optional<InfoRecord> InfoRecord::parse(llvm::StringRef Line) {
// use this as the UUID. Otherwise, we should revert back to the module ID.
UUID ID;
if (Line.trim().empty()) {
- if (Str.empty() || ID.SetFromStringRef(Str, Str.size() / 2) != Str.size())
+ if (Str.empty() || !ID.SetFromStringRef(Str))
return llvm::None;
}
return InfoRecord(std::move(ID));
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 27bef975125d..1620a1210b84 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
-#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-types.h"
@@ -183,4 +183,4 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);
} // namespace breakpad
} // namespace lldb_private
-#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 3b9e0e2092a9..7a9163ddb880 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -1,4 +1,4 @@
-//===-- ObjectFileBreakpad.cpp -------------------------------- -*- C++ -*-===//
+//===-- ObjectFileBreakpad.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -16,6 +16,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::breakpad;
+LLDB_PLUGIN_DEFINE(ObjectFileBreakpad)
+
namespace {
struct Header {
ArchSpec arch;
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index cb4bba01fb71..8724feaa422d 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
-#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ArchSpec.h"
@@ -103,4 +103,4 @@ private:
} // namespace breakpad
} // namespace lldb_private
-#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
index aa9871071b0e..f0496beba2ef 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
@@ -1,4 +1,4 @@
-//===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===//
+//===-- ELFHeader.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
index bb228e269d40..963cc850736f 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
@@ -17,8 +17,8 @@
/// reading both 32 and 64 bit instances of the object.
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ELFHeader_h_
-#define liblldb_ELFHeader_h_
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
#include "llvm/BinaryFormat/ELF.h"
@@ -391,4 +391,4 @@ struct ELFRela {
} // End namespace elf.
-#endif // #ifndef liblldb_ELFHeader_h_
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_ELFHEADER_H
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 8b62afa18cd6..bca575b7f884 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1,4 +1,4 @@
-//===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//
+//===-- ObjectFileELF.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -51,6 +51,8 @@ using namespace lldb_private;
using namespace elf;
using namespace llvm::ELF;
+LLDB_PLUGIN_DEFINE(ObjectFileELF)
+
namespace {
// ELF note owner definitions
@@ -206,7 +208,9 @@ unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
} // end anonymous namespace
-static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; }
+static user_id_t SegmentID(size_t PHdrIndex) {
+ return ~user_id_t(PHdrIndex);
+}
bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
// Read all fields.
@@ -537,7 +541,8 @@ size_t ObjectFileELF::GetModuleSpecifications(
__FUNCTION__, file.GetPath().c_str());
}
- data_sp = MapFileData(file, -1, file_offset);
+ if (data_sp->GetByteSize() < length)
+ data_sp = MapFileData(file, -1, file_offset);
if (data_sp)
data.SetData(data_sp);
// In case there is header extension in the section #0, the header we
@@ -576,8 +581,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
func_cat,
"Calculating module crc32 %s with size %" PRIu64 " KiB",
file.GetLastPathComponent().AsCString(),
- (FileSystem::Instance().GetByteSize(file) - file_offset) /
- 1024);
+ (length - file_offset) / 1024);
// For core files - which usually don't happen to have a
// gnu_debuglink, and are pretty bulky - calculating whole
@@ -899,7 +903,7 @@ size_t ObjectFileELF::ParseDependentModules() {
if (m_filespec_up)
return m_filespec_up->GetSize();
- m_filespec_up.reset(new FileSpecList());
+ m_filespec_up = std::make_unique<FileSpecList>();
if (!ParseSectionHeaders())
return 0;
@@ -1235,7 +1239,7 @@ void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
lldb::offset_t Offset = 0;
uint8_t FormatVersion = data.GetU8(&Offset);
- if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
+ if (FormatVersion != llvm::ELFAttrs::Format_Version)
return;
Offset = Offset + sizeof(uint32_t); // Section Length
@@ -1588,6 +1592,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
.Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
.Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
.Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
+ .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
.Case("types", eSectionTypeDWARFDebugTypes)
.Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
.Default(eSectionTypeOther);
@@ -1696,7 +1701,7 @@ class VMAddressProvider {
public:
VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
- : ObjectType(Type), SegmentName(SegmentName) {}
+ : ObjectType(Type), SegmentName(std::string(SegmentName)) {}
std::string GetNextSegmentName() const {
return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
@@ -2230,8 +2235,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (!mangled_name.empty())
mangled.SetMangledName(ConstString((mangled_name + suffix).str()));
- ConstString demangled =
- mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
+ ConstString demangled = mangled.GetDemangledName();
llvm::StringRef demangled_name = demangled.GetStringRef();
if (!demangled_name.empty())
mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
@@ -2713,7 +2717,7 @@ Symtab *ObjectFileELF::GetSymtab() {
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
if (symtab) {
- m_symtab_up.reset(new Symtab(symtab->GetObjectFile()));
+ m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
}
@@ -2730,7 +2734,7 @@ Symtab *ObjectFileELF::GetSymtab() {
.get();
if (dynsym) {
if (!m_symtab_up)
- m_symtab_up.reset(new Symtab(dynsym->GetObjectFile()));
+ m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
}
}
@@ -2757,7 +2761,8 @@ Symtab *ObjectFileELF::GetSymtab() {
assert(reloc_header);
if (m_symtab_up == nullptr)
- m_symtab_up.reset(new Symtab(reloc_section->GetObjectFile()));
+ m_symtab_up =
+ std::make_unique<Symtab>(reloc_section->GetObjectFile());
ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
reloc_id);
@@ -2767,17 +2772,17 @@ Symtab *ObjectFileELF::GetSymtab() {
if (DWARFCallFrameInfo *eh_frame =
GetModule()->GetUnwindTable().GetEHFrameInfo()) {
if (m_symtab_up == nullptr)
- m_symtab_up.reset(new Symtab(this));
+ m_symtab_up = std::make_unique<Symtab>(this);
ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
}
// If we still don't have any symtab then create an empty instance to avoid
// do the section lookup next time.
if (m_symtab_up == nullptr)
- m_symtab_up.reset(new Symtab(this));
+ m_symtab_up = std::make_unique<Symtab>(this);
// In the event that there's no symbol entry for the entry point we'll
- // artifically create one. We delegate to the symtab object the figuring
+ // artificially create one. We delegate to the symtab object the figuring
// out of the proper size, this will usually make it span til the next
// symbol it finds in the section. This means that if there are missing
// symbols the entry point might span beyond its function definition.
@@ -2874,7 +2879,7 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
return;
// First we save the new symbols into a separate list and add them to the
- // symbol table after we colleced all symbols we want to add. This is
+ // symbol table after we collected all symbols we want to add. This is
// neccessary because adding a new symbol invalidates the internal index of
// the symtab what causing the next lookup to be slow because it have to
// recalculate the index first.
@@ -2953,7 +2958,8 @@ void ObjectFileELF::Dump(Stream *s) {
s->EOL();
SectionList *section_list = GetSectionList();
if (section_list)
- section_list->Dump(s, nullptr, true, UINT32_MAX);
+ section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
+ UINT32_MAX);
Symtab *symtab = GetSymtab();
if (symtab)
symtab->Dump(s, nullptr, eSortOrderNone);
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 3b273896cb59..062271f1caf0 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjectFileELF_h_
-#define liblldb_ObjectFileELF_h_
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
#include <stdint.h>
@@ -328,9 +328,6 @@ private:
/// section index 0 is never valid).
lldb::user_id_t GetSectionIndexByName(const char *name);
- // Returns the ID of the first section that has the given type.
- lldb::user_id_t GetSectionIndexByType(unsigned type);
-
/// Returns the section header with the given id or NULL.
const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id);
@@ -397,4 +394,4 @@ private:
std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();
};
-#endif // liblldb_ObjectFileELF_h_
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index c55b96d9110b..93c2c9f945fe 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -1,4 +1,4 @@
-//===-- ObjectFileJIT.cpp ---------------------------------------*- C++ -*-===//
+//===-- ObjectFileJIT.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -39,6 +39,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ObjectFileJIT)
+
char ObjectFileJIT::ID;
void ObjectFileJIT::Initialize() {
@@ -118,7 +120,7 @@ Symtab *ObjectFileJIT::GetSymtab() {
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
if (m_symtab_up == nullptr) {
- m_symtab_up.reset(new Symtab(this));
+ m_symtab_up = std::make_unique<Symtab>(this);
std::lock_guard<std::recursive_mutex> symtab_guard(
m_symtab_up->GetMutex());
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
@@ -137,7 +139,7 @@ bool ObjectFileJIT::IsStripped() {
void ObjectFileJIT::CreateSections(SectionList &unified_section_list) {
if (!m_sections_up) {
- m_sections_up.reset(new SectionList());
+ m_sections_up = std::make_unique<SectionList>();
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
if (delegate_sp) {
delegate_sp->PopulateSectionList(this, *m_sections_up);
@@ -161,7 +163,8 @@ void ObjectFileJIT::Dump(Stream *s) {
SectionList *sections = GetSectionList();
if (sections)
- sections->Dump(s, nullptr, true, UINT32_MAX);
+ sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
+ UINT32_MAX);
if (m_symtab_up)
m_symtab_up->Dump(s, nullptr, eSortOrderNone);
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index c992683cfc3c..a3a1acea916a 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ObjectFileJIT_h_
-#define liblldb_ObjectFileJIT_h_
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H
#include "lldb/Core/Address.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -104,4 +104,4 @@ protected:
lldb::ObjectFileJITDelegateWP m_delegate_wp;
};
-#endif // liblldb_ObjectFileJIT_h_
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
new file mode 100644
index 000000000000..91150fa02ebc
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -0,0 +1,466 @@
+//===-- ObjectFileWasm.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFileWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(ObjectFileWasm)
+
+static const uint32_t kWasmHeaderSize =
+ sizeof(llvm::wasm::WasmMagic) + sizeof(llvm::wasm::WasmVersion);
+
+/// Checks whether the data buffer starts with a valid Wasm module header.
+static bool ValidateModuleHeader(const DataBufferSP &data_sp) {
+ if (!data_sp || data_sp->GetByteSize() < kWasmHeaderSize)
+ return false;
+
+ if (llvm::identify_magic(toStringRef(data_sp->GetData())) !=
+ llvm::file_magic::wasm_object)
+ return false;
+
+ uint8_t *Ptr = data_sp->GetBytes() + sizeof(llvm::wasm::WasmMagic);
+
+ uint32_t version = llvm::support::endian::read32le(Ptr);
+ return version == llvm::wasm::WasmVersion;
+}
+
+static llvm::Optional<ConstString>
+GetWasmString(llvm::DataExtractor &data, llvm::DataExtractor::Cursor &c) {
+ // A Wasm string is encoded as a vector of UTF-8 codes.
+ // Vectors are encoded with their u32 length followed by the element
+ // sequence.
+ uint64_t len = data.getULEB128(c);
+ if (!c) {
+ consumeError(c.takeError());
+ return llvm::None;
+ }
+
+ if (len >= (uint64_t(1) << 32)) {
+ return llvm::None;
+ }
+
+ llvm::SmallVector<uint8_t, 32> str_storage;
+ data.getU8(c, str_storage, len);
+ if (!c) {
+ consumeError(c.takeError());
+ return llvm::None;
+ }
+
+ llvm::StringRef str = toStringRef(makeArrayRef(str_storage));
+ return ConstString(str);
+}
+
+char ObjectFileWasm::ID;
+
+void ObjectFileWasm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications);
+}
+
+void ObjectFileWasm::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString ObjectFileWasm::GetPluginNameStatic() {
+ static ConstString g_name("wasm");
+ return g_name;
+}
+
+ObjectFile *
+ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp,
+ offset_t data_offset, const FileSpec *file,
+ offset_t file_offset, offset_t length) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+
+ if (!data_sp) {
+ data_sp = MapFileData(*file, length, file_offset);
+ if (!data_sp) {
+ LLDB_LOGF(log, "Failed to create ObjectFileWasm instance for file %s",
+ file->GetPath().c_str());
+ return nullptr;
+ }
+ data_offset = 0;
+ }
+
+ assert(data_sp);
+ if (!ValidateModuleHeader(data_sp)) {
+ LLDB_LOGF(log,
+ "Failed to create ObjectFileWasm instance: invalid Wasm header");
+ return nullptr;
+ }
+
+ // Update the data to contain the entire file if it doesn't contain it
+ // already.
+ if (data_sp->GetByteSize() < length) {
+ data_sp = MapFileData(*file, length, file_offset);
+ if (!data_sp) {
+ LLDB_LOGF(log,
+ "Failed to create ObjectFileWasm instance: cannot read file %s",
+ file->GetPath().c_str());
+ return nullptr;
+ }
+ data_offset = 0;
+ }
+
+ std::unique_ptr<ObjectFileWasm> objfile_up(new ObjectFileWasm(
+ module_sp, data_sp, data_offset, file, file_offset, length));
+ ArchSpec spec = objfile_up->GetArchitecture();
+ if (spec && objfile_up->SetModulesArchitecture(spec)) {
+ LLDB_LOGF(log,
+ "%p ObjectFileWasm::CreateInstance() module = %p (%s), file = %s",
+ static_cast<void *>(objfile_up.get()),
+ static_cast<void *>(objfile_up->GetModule().get()),
+ objfile_up->GetModule()->GetSpecificationDescription().c_str(),
+ file ? file->GetPath().c_str() : "<NULL>");
+ return objfile_up.release();
+ }
+
+ LLDB_LOGF(log, "Failed to create ObjectFileWasm instance");
+ return nullptr;
+}
+
+ObjectFile *ObjectFileWasm::CreateMemoryInstance(const ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ const ProcessSP &process_sp,
+ addr_t header_addr) {
+ if (!ValidateModuleHeader(data_sp))
+ return nullptr;
+
+ std::unique_ptr<ObjectFileWasm> objfile_up(
+ new ObjectFileWasm(module_sp, data_sp, process_sp, header_addr));
+ ArchSpec spec = objfile_up->GetArchitecture();
+ if (spec && objfile_up->SetModulesArchitecture(spec))
+ return objfile_up.release();
+ return nullptr;
+}
+
+bool ObjectFileWasm::DecodeNextSection(lldb::offset_t *offset_ptr) {
+ // Buffer sufficient to read a section header and find the pointer to the next
+ // section.
+ const uint32_t kBufferSize = 1024;
+ DataExtractor section_header_data = ReadImageData(*offset_ptr, kBufferSize);
+
+ llvm::DataExtractor data = section_header_data.GetAsLLVM();
+ llvm::DataExtractor::Cursor c(0);
+
+ // Each section consists of:
+ // - a one-byte section id,
+ // - the u32 size of the contents, in bytes,
+ // - the actual contents.
+ uint8_t section_id = data.getU8(c);
+ uint64_t payload_len = data.getULEB128(c);
+ if (!c)
+ return !llvm::errorToBool(c.takeError());
+
+ if (payload_len >= (uint64_t(1) << 32))
+ return false;
+
+ if (section_id == llvm::wasm::WASM_SEC_CUSTOM) {
+ // Custom sections have the id 0. Their contents consist of a name
+ // identifying the custom section, followed by an uninterpreted sequence
+ // of bytes.
+ lldb::offset_t prev_offset = c.tell();
+ llvm::Optional<ConstString> sect_name = GetWasmString(data, c);
+ if (!sect_name)
+ return false;
+
+ if (payload_len < c.tell() - prev_offset)
+ return false;
+
+ uint32_t section_length = payload_len - (c.tell() - prev_offset);
+ m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), section_length,
+ section_id, *sect_name});
+ *offset_ptr += (c.tell() + section_length);
+ } else if (section_id <= llvm::wasm::WASM_SEC_EVENT) {
+ m_sect_infos.push_back(section_info{*offset_ptr + c.tell(),
+ static_cast<uint32_t>(payload_len),
+ section_id, ConstString()});
+ *offset_ptr += (c.tell() + payload_len);
+ } else {
+ // Invalid section id.
+ return false;
+ }
+ return true;
+}
+
+bool ObjectFileWasm::DecodeSections() {
+ lldb::offset_t offset = kWasmHeaderSize;
+ if (IsInMemory()) {
+ offset += m_memory_addr;
+ }
+
+ while (DecodeNextSection(&offset))
+ ;
+ return true;
+}
+
+size_t ObjectFileWasm::GetModuleSpecifications(
+ const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+ offset_t file_offset, offset_t length, ModuleSpecList &specs) {
+ if (!ValidateModuleHeader(data_sp)) {
+ return 0;
+ }
+
+ ModuleSpec spec(file, ArchSpec("wasm32-unknown-unknown-wasm"));
+ specs.Append(spec);
+ return 1;
+}
+
+ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP &data_sp,
+ offset_t data_offset, const FileSpec *file,
+ offset_t offset, offset_t length)
+ : ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
+ m_arch("wasm32-unknown-unknown-wasm") {
+ m_data.SetAddressByteSize(4);
+}
+
+ObjectFileWasm::ObjectFileWasm(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr)
+ : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
+ m_arch("wasm32-unknown-unknown-wasm") {}
+
+bool ObjectFileWasm::ParseHeader() {
+ // We already parsed the header during initialization.
+ return true;
+}
+
+Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
+
+void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
+ if (m_sections_up)
+ return;
+
+ m_sections_up = std::make_unique<SectionList>();
+
+ if (m_sect_infos.empty()) {
+ DecodeSections();
+ }
+
+ for (const section_info &sect_info : m_sect_infos) {
+ SectionType section_type = eSectionTypeOther;
+ ConstString section_name;
+ offset_t file_offset = sect_info.offset & 0xffffffff;
+ addr_t vm_addr = file_offset;
+ size_t vm_size = sect_info.size;
+
+ if (llvm::wasm::WASM_SEC_CODE == sect_info.id) {
+ section_type = eSectionTypeCode;
+ section_name = ConstString("code");
+
+ // A code address in DWARF for WebAssembly is the offset of an
+ // instruction relative within the Code section of the WebAssembly file.
+ // For this reason Section::GetFileAddress() must return zero for the
+ // Code section.
+ vm_addr = 0;
+ } else {
+ section_type =
+ llvm::StringSwitch<SectionType>(sect_info.name.GetStringRef())
+ .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev)
+ .Case(".debug_addr", eSectionTypeDWARFDebugAddr)
+ .Case(".debug_aranges", eSectionTypeDWARFDebugAranges)
+ .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex)
+ .Case(".debug_frame", eSectionTypeDWARFDebugFrame)
+ .Case(".debug_info", eSectionTypeDWARFDebugInfo)
+ .Case(".debug_line", eSectionTypeDWARFDebugLine)
+ .Case(".debug_line_str", eSectionTypeDWARFDebugLineStr)
+ .Case(".debug_loc", eSectionTypeDWARFDebugLoc)
+ .Case(".debug_loclists", eSectionTypeDWARFDebugLocLists)
+ .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo)
+ .Case(".debug_macro", eSectionTypeDWARFDebugMacro)
+ .Case(".debug_names", eSectionTypeDWARFDebugNames)
+ .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames)
+ .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
+ .Case(".debug_ranges", eSectionTypeDWARFDebugRanges)
+ .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists)
+ .Case(".debug_str", eSectionTypeDWARFDebugStr)
+ .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
+ .Case(".debug_types", eSectionTypeDWARFDebugTypes)
+ .Default(eSectionTypeOther);
+ if (section_type == eSectionTypeOther)
+ continue;
+ section_name = sect_info.name;
+ if (!IsInMemory()) {
+ vm_size = 0;
+ vm_addr = 0;
+ }
+ }
+
+ SectionSP section_sp(
+ new Section(GetModule(), // Module to which this section belongs.
+ this, // ObjectFile to which this section belongs and
+ // should read section data from.
+ section_type, // Section ID.
+ section_name, // Section name.
+ section_type, // Section type.
+ vm_addr, // VM address.
+ vm_size, // VM size in bytes of this section.
+ file_offset, // Offset of this section in the file.
+ sect_info.size, // Size of the section as found in the file.
+ 0, // Alignment of the section
+ 0, // Flags for this section.
+ 1)); // Number of host bytes per target byte
+ m_sections_up->AddSection(section_sp);
+ unified_section_list.AddSection(section_sp);
+ }
+}
+
+bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
+ bool value_is_offset) {
+ /// In WebAssembly, linear memory is disjointed from code space. The VM can
+ /// load multiple instances of a module, which logically share the same code.
+ /// We represent a wasm32 code address with 64-bits, like:
+ /// 63 32 31 0
+ /// +---------------+---------------+
+ /// + module_id | offset |
+ /// +---------------+---------------+
+ /// where the lower 32 bits represent a module offset (relative to the module
+ /// start not to the beginning of the code section) and the higher 32 bits
+ /// uniquely identify the module in the WebAssembly VM.
+ /// In other words, we assume that each WebAssembly module is loaded by the
+ /// engine at a 64-bit address that starts at the boundary of 4GB pages, like
+ /// 0x0000000400000000 for module_id == 4.
+ /// These 64-bit addresses will be used to request code ranges for a specific
+ /// module from the WebAssembly engine.
+
+ assert(m_memory_addr == LLDB_INVALID_ADDRESS ||
+ m_memory_addr == load_address);
+
+ ModuleSP module_sp = GetModule();
+ if (!module_sp)
+ return false;
+
+ DecodeSections();
+
+ size_t num_loaded_sections = 0;
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return false;
+
+ const size_t num_sections = section_list->GetSize();
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (target.SetSectionLoadAddress(
+ section_sp, load_address | section_sp->GetFileOffset())) {
+ ++num_loaded_sections;
+ }
+ }
+
+ return num_loaded_sections > 0;
+}
+
+DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) {
+ DataExtractor data;
+ if (m_file) {
+ if (offset < GetByteSize()) {
+ size = std::min(static_cast<uint64_t>(size), GetByteSize() - offset);
+ auto buffer_sp = MapFileData(m_file, size, offset);
+ return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
+ }
+ } else {
+ ProcessSP process_sp(m_process_wp.lock());
+ if (process_sp) {
+ auto data_up = std::make_unique<DataBufferHeap>(size, 0);
+ Status readmem_error;
+ size_t bytes_read = process_sp->ReadMemory(
+ offset, data_up->GetBytes(), data_up->GetByteSize(), readmem_error);
+ if (bytes_read > 0) {
+ DataBufferSP buffer_sp(data_up.release());
+ data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
+ }
+ }
+ }
+
+ data.SetByteOrder(GetByteOrder());
+ return data;
+}
+
+llvm::Optional<FileSpec> ObjectFileWasm::GetExternalDebugInfoFileSpec() {
+ static ConstString g_sect_name_external_debug_info("external_debug_info");
+
+ for (const section_info &sect_info : m_sect_infos) {
+ if (g_sect_name_external_debug_info == sect_info.name) {
+ const uint32_t kBufferSize = 1024;
+ DataExtractor section_header_data =
+ ReadImageData(sect_info.offset, kBufferSize);
+ llvm::DataExtractor data = section_header_data.GetAsLLVM();
+ llvm::DataExtractor::Cursor c(0);
+ llvm::Optional<ConstString> symbols_url = GetWasmString(data, c);
+ if (symbols_url)
+ return FileSpec(symbols_url->GetStringRef());
+ }
+ }
+ return llvm::None;
+}
+
+void ObjectFileWasm::Dump(Stream *s) {
+ ModuleSP module_sp(GetModule());
+ if (!module_sp)
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+
+ llvm::raw_ostream &ostream = s->AsRawOstream();
+ ostream << static_cast<void *>(this) << ": ";
+ s->Indent();
+ ostream << "ObjectFileWasm, file = '";
+ m_file.Dump(ostream);
+ ostream << "', arch = ";
+ ostream << GetArchitecture().GetArchitectureName() << "\n";
+
+ SectionList *sections = GetSectionList();
+ if (sections) {
+ sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
+ UINT32_MAX);
+ }
+ ostream << "\n";
+ DumpSectionHeaders(ostream);
+ ostream << "\n";
+}
+
+void ObjectFileWasm::DumpSectionHeader(llvm::raw_ostream &ostream,
+ const section_info_t &sh) {
+ ostream << llvm::left_justify(sh.name.GetStringRef(), 16) << " "
+ << llvm::format_hex(sh.offset, 10) << " "
+ << llvm::format_hex(sh.size, 10) << " " << llvm::format_hex(sh.id, 6)
+ << "\n";
+}
+
+void ObjectFileWasm::DumpSectionHeaders(llvm::raw_ostream &ostream) {
+ ostream << "Section Headers\n";
+ ostream << "IDX name addr size id\n";
+ ostream << "==== ---------------- ---------- ---------- ------\n";
+
+ uint32_t idx = 0;
+ for (auto pos = m_sect_infos.begin(); pos != m_sect_infos.end();
+ ++pos, ++idx) {
+ ostream << "[" << llvm::format_decimal(idx, 2) << "] ";
+ ObjectFileWasm::DumpSectionHeader(ostream, *pos);
+ }
+}
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
new file mode 100644
index 000000000000..b6e906a7b15f
--- /dev/null
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -0,0 +1,151 @@
+//===-- ObjectFileWasm.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+
+namespace lldb_private {
+namespace wasm {
+
+/// Generic Wasm object file reader.
+///
+/// This class provides a generic wasm32 reader plugin implementing the
+/// ObjectFile protocol.
+class ObjectFileWasm : public ObjectFile {
+public:
+ static void Initialize();
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic() {
+ return "WebAssembly object file reader.";
+ }
+
+ static ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
+ static size_t GetModuleSpecifications(const FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ ModuleSpecList &specs);
+
+ /// PluginInterface protocol.
+ /// \{
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+ uint32_t GetPluginVersion() override { return 1; }
+ /// \}
+
+ /// LLVM RTTI support
+ /// \{
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+ /// \}
+
+ /// ObjectFile Protocol.
+ /// \{
+ bool ParseHeader() override;
+
+ lldb::ByteOrder GetByteOrder() const override {
+ return m_arch.GetByteOrder();
+ }
+
+ bool IsExecutable() const override { return false; }
+
+ uint32_t GetAddressByteSize() const override {
+ return m_arch.GetAddressByteSize();
+ }
+
+ AddressClass GetAddressClass(lldb::addr_t file_addr) override {
+ return AddressClass::eInvalid;
+ }
+
+ Symtab *GetSymtab() override;
+
+ bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
+
+ void CreateSections(SectionList &unified_section_list) override;
+
+ void Dump(Stream *s) override;
+
+ ArchSpec GetArchitecture() override { return m_arch; }
+
+ UUID GetUUID() override { return m_uuid; }
+
+ uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
+
+ Type CalculateType() override { return eTypeSharedLibrary; }
+
+ Strata CalculateStrata() override { return eStrataUser; }
+
+ bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+ bool value_is_offset) override;
+
+ lldb_private::Address GetBaseAddress() override {
+ return IsInMemory() ? Address(m_memory_addr) : Address(0);
+ }
+ /// \}
+
+ /// A Wasm module that has external DWARF debug information should contain a
+ /// custom section named "external_debug_info", whose payload is an UTF-8
+ /// encoded string that points to a Wasm module that contains the debug
+ /// information for this module.
+ llvm::Optional<FileSpec> GetExternalDebugInfoFileSpec();
+
+private:
+ ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+ ObjectFileWasm(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &header_data_sp,
+ const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+ /// Wasm section decoding routines.
+ /// \{
+ bool DecodeNextSection(lldb::offset_t *offset_ptr);
+ bool DecodeSections();
+ /// \}
+
+ /// Read a range of bytes from the Wasm module.
+ DataExtractor ReadImageData(lldb::offset_t offset, uint32_t size);
+
+ typedef struct section_info {
+ lldb::offset_t offset;
+ uint32_t size;
+ uint32_t id;
+ ConstString name;
+ } section_info_t;
+
+ /// Wasm section header dump routines.
+ /// \{
+ void DumpSectionHeader(llvm::raw_ostream &ostream, const section_info_t &sh);
+ void DumpSectionHeaders(llvm::raw_ostream &ostream);
+ /// \}
+
+ std::vector<section_info_t> m_sect_infos;
+ ArchSpec m_arch;
+ UUID m_uuid;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index b04ac61c99a1..417aa2e21436 100644
--- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -1,4 +1,4 @@
-//===-- OperatingSystemPython.cpp --------------------------------*- C++-*-===//
+//===-- OperatingSystemPython.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -39,6 +39,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(OperatingSystemPython)
+
void OperatingSystemPython::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
@@ -337,7 +339,7 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
thread->GetID());
if (reg_context_data) {
- std::string value = reg_context_data->GetValue();
+ std::string value = std::string(reg_context_data->GetValue());
DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
if (data_sp->GetByteSize()) {
RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory(
diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 261f44c230f9..97c2f22b505f 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformFreeBSD.cpp -------------------------------------*- C++ -*-===//
+//===-- PlatformFreeBSD.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -36,6 +36,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_freebsd;
+LLDB_PLUGIN_DEFINE(PlatformFreeBSD)
+
static uint32_t g_initialize_count = 0;
diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index e3a3aa7145f0..56f2f2771d12 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformFreeBSD_h_
-#define liblldb_PlatformFreeBSD_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
@@ -62,10 +62,11 @@ public:
lldb::addr_t offset) override;
private:
- DISALLOW_COPY_AND_ASSIGN(PlatformFreeBSD);
+ PlatformFreeBSD(const PlatformFreeBSD &) = delete;
+ const PlatformFreeBSD &operator=(const PlatformFreeBSD &) = delete;
};
} // namespace platform_freebsd
} // namespace lldb_private
-#endif // liblldb_PlatformFreeBSD_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_FREEBSD_PLATFORMFREEBSD_H
diff --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 53f819e6a272..caebd79c853e 100644
--- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformNetBSD.cpp -------------------------------------*- C++ -*-===//
+//===-- PlatformNetBSD.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -34,6 +34,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_netbsd;
+LLDB_PLUGIN_DEFINE(PlatformNetBSD)
+
static uint32_t g_initialize_count = 0;
@@ -329,14 +331,14 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Hook up process PTY if we have one (which we should for local debugging
// with llgs).
- int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
process_sp->SetSTDIOFileDescriptor(pty_fd);
LLDB_LOG(log, "hooked up STDIO pty to process");
} else
LLDB_LOG(log, "not using process STDIO pty");
} else {
- LLDB_LOG(log, "process launch failed: {0}", error);
+ LLDB_LOG(log, "{0}", error);
// FIXME figure out appropriate cleanup here. Do we delete the target? Do
// we delete the process? Does our caller do that?
}
diff --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index 0584d92d6c99..d53e58418884 100644
--- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformNetBSD_h_
-#define liblldb_PlatformNetBSD_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
@@ -60,10 +60,11 @@ public:
lldb::addr_t offset) override;
private:
- DISALLOW_COPY_AND_ASSIGN(PlatformNetBSD);
+ PlatformNetBSD(const PlatformNetBSD &) = delete;
+ const PlatformNetBSD &operator=(const PlatformNetBSD &) = delete;
};
} // namespace platform_netbsd
} // namespace lldb_private
-#endif // liblldb_PlatformNetBSD_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_NETBSD_PLATFORMNETBSD_H
diff --git a/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index 1b63e2da0a4f..a743970990a6 100644
--- a/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformOpenBSD.cpp -------------------------------------*- C++ -*-===//
+//===-- PlatformOpenBSD.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -34,6 +34,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_openbsd;
+LLDB_PLUGIN_DEFINE(PlatformOpenBSD)
+
static uint32_t g_initialize_count = 0;
diff --git a/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
index 3cb724f30325..9cfe32c3720c 100644
--- a/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
+++ b/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformOpenBSD_h_
-#define liblldb_PlatformOpenBSD_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
@@ -54,10 +54,11 @@ public:
lldb::addr_t offset) override;
private:
- DISALLOW_COPY_AND_ASSIGN(PlatformOpenBSD);
+ PlatformOpenBSD(const PlatformOpenBSD &) = delete;
+ const PlatformOpenBSD &operator=(const PlatformOpenBSD &) = delete;
};
} // namespace platform_openbsd
} // namespace lldb_private
-#endif // liblldb_PlatformOpenBSD_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_OPENBSD_PLATFORMOPENBSD_H
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 2b64be63a623..180ea1d2cfd1 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformPOSIX.cpp ---------------------------------------*- C++ -*-===//
+//===-- PlatformPOSIX.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,9 +8,9 @@
#include "PlatformPOSIX.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -22,7 +22,6 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ProcessLaunchInfo.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -64,148 +63,6 @@ lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
return m_options.at(&interpreter).get();
}
-Status
-PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
- lldb::ModuleSP &exe_module_sp,
- const FileSpecList *module_search_paths_ptr) {
- Status error;
- // Nothing special to do here, just use the actual file and architecture
-
- char exe_path[PATH_MAX];
- ModuleSpec resolved_module_spec(module_spec);
-
- if (IsHost()) {
- // If we have "ls" as the exe_file, resolve the executable location based
- // on the current path variables
- if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
- resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
- }
-
- if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- FileSystem::Instance().ResolveExecutableLocation(
- resolved_module_spec.GetFileSpec());
-
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- error.Clear();
- else {
- const uint32_t permissions = FileSystem::Instance().GetPermissions(
- resolved_module_spec.GetFileSpec());
- if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
- error.SetErrorStringWithFormat(
- "executable '%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- else
- error.SetErrorStringWithFormat(
- "unable to find executable for '%s'",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- } else {
- if (m_remote_platform_sp) {
- error =
- GetCachedExecutable(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr, *m_remote_platform_sp);
- } else {
- // We may connect to a process and use the provided executable (Don't use
- // local $PATH).
-
- // Resolve any executable within a bundle on MacOSX
- Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
-
- if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
- error.Clear();
- else
- error.SetErrorStringWithFormat("the platform is not currently "
- "connected, and '%s' doesn't exist in "
- "the system root.",
- exe_path);
- }
- }
-
- if (error.Success()) {
- if (resolved_module_spec.GetArchitecture().IsValid()) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr, nullptr, nullptr);
- if (error.Fail()) {
- // If we failed, it may be because the vendor and os aren't known. If
- // that is the case, try setting them to the host architecture and give
- // it another try.
- llvm::Triple &module_triple =
- resolved_module_spec.GetArchitecture().GetTriple();
- bool is_vendor_specified =
- (module_triple.getVendor() != llvm::Triple::UnknownVendor);
- bool is_os_specified =
- (module_triple.getOS() != llvm::Triple::UnknownOS);
- if (!is_vendor_specified || !is_os_specified) {
- const llvm::Triple &host_triple =
- HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
-
- if (!is_vendor_specified)
- module_triple.setVendorName(host_triple.getVendorName());
- if (!is_os_specified)
- module_triple.setOSName(host_triple.getOSName());
-
- error = ModuleList::GetSharedModule(resolved_module_spec,
- exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
- }
- }
-
- // TODO find out why exe_module_sp might be NULL
- if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
- exe_module_sp.reset();
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain the architecture %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
- } else {
- // No valid architecture was specified, ask the platform for the
- // architectures that we should be using (in the correct order) and see
- // if we can find a match that way
- StreamString arch_names;
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, resolved_module_spec.GetArchitecture());
- ++idx) {
- error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
- module_search_paths_ptr, nullptr, nullptr);
- // Did we find an executable using one of the
- if (error.Success()) {
- if (exe_module_sp && exe_module_sp->GetObjectFile())
- break;
- else
- error.SetErrorToGenericError();
- }
-
- if (idx > 0)
- arch_names.PutCString(", ");
- arch_names.PutCString(
- resolved_module_spec.GetArchitecture().GetArchitectureName());
- }
-
- if (error.Fail() || !exe_module_sp) {
- if (FileSystem::Instance().Readable(
- resolved_module_spec.GetFileSpec())) {
- error.SetErrorStringWithFormat(
- "'%s' doesn't contain any '%s' platform architectures: %s",
- resolved_module_spec.GetFileSpec().GetPath().c_str(),
- GetPluginName().GetCString(), arch_names.GetData());
- } else {
- error.SetErrorStringWithFormat(
- "'%s' is not readable",
- resolved_module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- }
- }
-
- return error;
-}
-
static uint32_t chown_file(Platform *platform, const char *path,
uint32_t uid = UINT32_MAX,
uint32_t gid = UINT32_MAX) {
@@ -429,7 +286,7 @@ std::string PlatformPOSIX::GetPlatformSpecificConnectionInformation() {
if (GetLocalCacheDirectory() && *GetLocalCacheDirectory())
stream.Printf("cache dir: %s", GetLocalCacheDirectory());
if (stream.GetSize())
- return stream.GetString();
+ return std::string(stream.GetString());
else
return "";
}
@@ -679,7 +536,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper";
Process *process = exe_ctx.GetProcessSP().get();
// Insert the dlopen shim defines into our generic expression:
- std::string expr(GetLibdlFunctionDeclarations(process));
+ std::string expr(std::string(GetLibdlFunctionDeclarations(process)));
expr.append(dlopen_wrapper_code);
Status utility_error;
DiagnosticManager diagnostics;
@@ -706,7 +563,7 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
FunctionCaller *do_dlopen_function = nullptr;
// Fetch the clang types we will need:
- ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget());
+ TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
if (!ast)
return nullptr;
@@ -950,9 +807,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
Value return_value;
// Fetch the clang types we will need:
- ClangASTContext *ast = ClangASTContext::GetScratch(process->GetTarget());
+ TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
if (!ast) {
- error.SetErrorString("dlopen error: Unable to get ClangASTContext");
+ error.SetErrorString("dlopen error: Unable to get TypeSystemClang");
return LLDB_INVALID_IMAGE_TOKEN;
}
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 5858f99088e6..72c54f4147c2 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformPOSIX_h_
-#define liblldb_PlatformPOSIX_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H
#include <map>
#include <memory>
@@ -37,10 +37,6 @@ public:
const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
- lldb_private::Status ResolveExecutable(
- const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const lldb_private::FileSpecList *module_search_paths_ptr) override;
-
lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
lldb_private::Debugger &debugger,
lldb_private::Target *target, // Can be nullptr, if
@@ -105,7 +101,8 @@ protected:
llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process);
private:
- DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX);
+ PlatformPOSIX(const PlatformPOSIX &) = delete;
+ const PlatformPOSIX &operator=(const PlatformPOSIX &) = delete;
};
-#endif // liblldb_PlatformPOSIX_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_POSIX_PLATFORMPOSIX_H
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 1e62ddfe94fd..21bf7f4ac46d 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -1,4 +1,4 @@
-//===-- PlatformRemoteGDBServer.cpp -----------------------------*- C++ -*-===//
+//===-- PlatformRemoteGDBServer.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -35,6 +35,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_gdb_server;
+LLDB_PLUGIN_DEFINE_ADV(PlatformRemoteGDBServer, PlatformGDB)
+
static bool g_initialized = false;
void PlatformRemoteGDBServer::Initialize() {
@@ -286,40 +288,55 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
"execute 'platform disconnect' to close the "
"current connection",
GetHostname());
+ return error;
+ }
+
+ if (args.GetArgumentCount() != 1) {
+ error.SetErrorString(
+ "\"platform connect\" takes a single argument: <connect-url>");
+ return error;
+ }
+
+ const char *url = args.GetArgumentAtIndex(0);
+ if (!url)
+ return Status("URL is null.");
+
+ int port;
+ llvm::StringRef scheme, hostname, pathname;
+ if (!UriParser::Parse(url, scheme, hostname, port, pathname))
+ return Status("Invalid URL: %s", url);
+
+ // We're going to reuse the hostname when we connect to the debugserver.
+ m_platform_scheme = std::string(scheme);
+ m_platform_hostname = std::string(hostname);
+
+ m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>());
+ if (repro::Reproducer::Instance().IsReplaying()) {
+ error = m_gdb_replay_server.Connect(m_gdb_client);
+ if (error.Success())
+ m_gdb_replay_server.StartAsyncThread();
} else {
- if (args.GetArgumentCount() == 1) {
- m_gdb_client.SetConnection(new ConnectionFileDescriptor());
- // we're going to reuse the hostname when we connect to the debugserver
- int port;
- std::string path;
- const char *url = args.GetArgumentAtIndex(0);
- if (!url)
- return Status("URL is null.");
- llvm::StringRef scheme, hostname, pathname;
- if (!UriParser::Parse(url, scheme, hostname, port, pathname))
- return Status("Invalid URL: %s", url);
- m_platform_scheme = scheme;
- m_platform_hostname = hostname;
- path = pathname;
-
- const ConnectionStatus status = m_gdb_client.Connect(url, &error);
- if (status == eConnectionStatusSuccess) {
- if (m_gdb_client.HandshakeWithServer(&error)) {
- m_gdb_client.GetHostInfo();
- // If a working directory was set prior to connecting, send it down
- // now
- if (m_working_dir)
- m_gdb_client.SetWorkingDir(m_working_dir);
- } else {
- m_gdb_client.Disconnect();
- if (error.Success())
- error.SetErrorString("handshake failed");
- }
- }
- } else {
- error.SetErrorString(
- "\"platform connect\" takes a single argument: <connect-url>");
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ repro::GDBRemoteProvider &provider =
+ g->GetOrCreate<repro::GDBRemoteProvider>();
+ m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
}
+ m_gdb_client.Connect(url, &error);
+ }
+
+ if (error.Fail())
+ return error;
+
+ if (m_gdb_client.HandshakeWithServer(&error)) {
+ m_gdb_client.GetHostInfo();
+ // If a working directory was set prior to connecting, send it down
+ // now.
+ if (m_working_dir)
+ m_gdb_client.SetWorkingDir(m_working_dir);
+ } else {
+ m_gdb_client.Disconnect();
+ if (error.Success())
+ error.SetErrorString("handshake failed");
}
return error;
}
@@ -486,10 +503,10 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
"gdb-remote", nullptr);
if (process_sp) {
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
// Retry the connect remote one time...
if (error.Fail())
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
if (error.Success())
error = process_sp->Launch(launch_info);
else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) {
@@ -572,7 +589,7 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
target->CreateProcess(attach_info.GetListenerForProcess(debugger),
"gdb-remote", nullptr);
if (process_sp) {
- error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
+ error = process_sp->ConnectRemote(connect_url.c_str());
if (error.Success()) {
ListenerSP listener_sp = attach_info.GetHijackListener();
if (listener_sp)
@@ -725,7 +742,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
response.GetResponseType() != response.eResponse)
return m_remote_signals_sp;
- auto object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ auto object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (!object_sp || !object_sp->IsValid())
return m_remote_signals_sp;
@@ -772,7 +790,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
std::string description{""};
object_sp = dict->GetValueForKey("description");
if (object_sp && object_sp->IsValid())
- description = object_sp->GetStringValue();
+ description = std::string(object_sp->GetStringValue());
remote_signals_sp->AddSignal(signo, name.str().c_str(), suppress, stop,
notify, description.c_str());
@@ -811,7 +829,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
result.Printf(":%u", port);
if (path)
result.Write(path, strlen(path));
- return result.GetString();
+ return std::string(result.GetString());
}
lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess(
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 13edcbab9f59..0602be1fa377 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_PlatformRemoteGDBServer_h_
-#define liblldb_PlatformRemoteGDBServer_h_
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
#include <string>
-#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h"
#include "lldb/Target/Platform.h"
namespace lldb_private {
@@ -164,6 +165,7 @@ public:
protected:
process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
+ process_gdb_remote::GDBRemoteCommunicationReplayServer m_gdb_replay_server;
std::string m_platform_description; // After we connect we can get a more
// complete description of what we are
// connected to
@@ -192,10 +194,12 @@ private:
llvm::Optional<std::string> DoGetUserName(UserIDResolver::id_t uid) override;
llvm::Optional<std::string> DoGetGroupName(UserIDResolver::id_t uid) override;
- DISALLOW_COPY_AND_ASSIGN(PlatformRemoteGDBServer);
+ PlatformRemoteGDBServer(const PlatformRemoteGDBServer &) = delete;
+ const PlatformRemoteGDBServer &
+ operator=(const PlatformRemoteGDBServer &) = delete;
};
} // namespace platform_gdb_server
} // namespace lldb_private
-#endif // liblldb_PlatformRemoteGDBServer_h_
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_GDB_SERVER_PLATFORMREMOTEGDBSERVER_H
diff --git a/lldb/source/Plugins/Plugins.def.in b/lldb/source/Plugins/Plugins.def.in
new file mode 100644
index 000000000000..bf54598fb2f3
--- /dev/null
+++ b/lldb/source/Plugins/Plugins.def.in
@@ -0,0 +1,37 @@
+/*===- lldb/source/Plugin/Plugins.def ---------------------------*- C++ -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file enumerates all of the plugins supported by this build of LLDB. *|
+|* Clients of this file should define the LLDB_PLUGIN macro to be a *|
+|* function-like macro with a single parameter (the name of the plugin) *|
+|* including this file will then enumerate all of the plugins. Script *|
+|* interpreter plugins can be enumerated separately by defining *|
+|* LLDB_SCRIPT_PLUGIN in which case they are not part of LLDB_PLUGIN. *|
+|* *|
+|* *|
+|* The set of plugins supported by LLDB is generated at configuration *|
+|* time, at which point this header is generated. Do not modify this *|
+|* header directly. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLDB_PLUGIN
+# error Please define the macro LLDB_PLUGIN(PluginName)
+#endif
+
+#ifndef LLDB_SCRIPT_PLUGIN
+#define LLDB_SCRIPT_PLUGIN(p) LLDB_PLUGIN(p)
+#endif
+
+@LLDB_ENUM_PLUGINS@
+@LLDB_PROCESS_WINDOWS_PLUGIN@
+@LLDB_PROCESS_GDB_PLUGIN@
+
+#undef LLDB_PLUGIN
+#undef LLDB_SCRIPT_PLUGIN
diff --git a/lldb/source/Plugins/Process/Darwin/CFBundle.cpp b/lldb/source/Plugins/Process/Darwin/CFBundle.cpp
deleted file mode 100644
index 3cdd2fa575e7..000000000000
--- a/lldb/source/Plugins/Process/Darwin/CFBundle.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- CFBundle.cpp --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFBundle.h"
-#include "CFString.h"
-
-// CFBundle constructor
-CFBundle::CFBundle(const char *path)
- : CFReleaser<CFBundleRef>(), m_bundle_url() {
- if (path && path[0])
- SetPath(path);
-}
-
-// CFBundle copy constructor
-CFBundle::CFBundle(const CFBundle &rhs)
- : CFReleaser<CFBundleRef>(rhs), m_bundle_url(rhs.m_bundle_url) {}
-
-// CFBundle copy constructor
-CFBundle &CFBundle::operator=(const CFBundle &rhs) {
- *this = rhs;
- return *this;
-}
-
-// Destructor
-CFBundle::~CFBundle() {}
-
-// Set the path for a bundle by supplying a
-bool CFBundle::SetPath(const char *path) {
- CFAllocatorRef alloc = kCFAllocatorDefault;
- // Release our old bundle and ULR
- reset(); // This class is a CFReleaser<CFBundleRef>
- m_bundle_url.reset();
- // Make a CFStringRef from the supplied path
- CFString cf_path;
- cf_path.SetFileSystemRepresentation(path);
- if (cf_path.get()) {
- // Make our Bundle URL
- m_bundle_url.reset(::CFURLCreateWithFileSystemPath(
- alloc, cf_path.get(), kCFURLPOSIXPathStyle, true));
- if (m_bundle_url.get()) {
- reset(::CFBundleCreate(alloc, m_bundle_url.get()));
- }
- }
- return get() != NULL;
-}
-
-CFStringRef CFBundle::GetIdentifier() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return ::CFBundleGetIdentifier(bundle);
- return NULL;
-}
-
-CFURLRef CFBundle::CopyExecutableURL() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return CFBundleCopyExecutableURL(bundle);
- return NULL;
-}
diff --git a/lldb/source/Plugins/Process/Darwin/CFBundle.h b/lldb/source/Plugins/Process/Darwin/CFBundle.h
deleted file mode 100644
index f49dc30f1f8f..000000000000
--- a/lldb/source/Plugins/Process/Darwin/CFBundle.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- CFBundle.h ----------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFBundle_h__
-#define __CFBundle_h__
-
-#include "CFUtils.h"
-
-class CFBundle : public CFReleaser<CFBundleRef> {
-public:
- // Constructors and Destructors
- CFBundle(const char *path = NULL);
- CFBundle(const CFBundle &rhs);
- CFBundle &operator=(const CFBundle &rhs);
- virtual ~CFBundle();
- bool SetPath(const char *path);
-
- CFStringRef GetIdentifier() const;
-
- CFURLRef CopyExecutableURL() const;
-
-protected:
- CFReleaser<CFURLRef> m_bundle_url;
-};
-
-#endif // #ifndef __CFBundle_h__
diff --git a/lldb/source/Plugins/Process/Darwin/CFString.cpp b/lldb/source/Plugins/Process/Darwin/CFString.cpp
deleted file mode 100644
index 4dcc05c86657..000000000000
--- a/lldb/source/Plugins/Process/Darwin/CFString.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-//===-- CFString.cpp --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFString.h"
-#include <glob.h>
-#include <string>
-
-// CFString constructor
-CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
-
-// CFString copy constructor
-CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {}
-
-// CFString copy constructor
-CFString &CFString::operator=(const CFString &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
- : CFReleaser<CFStringRef>() {
- if (cstr && cstr[0]) {
- reset(
- ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
- }
-}
-
-// Destructor
-CFString::~CFString() {}
-
-const char *CFString::GetFileSystemRepresentation(std::string &s) {
- return CFString::FileSystemRepresentation(get(), s);
-}
-
-CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
- CFStringRef new_value = NULL;
- if (path && path[0])
- new_value =
- ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
- reset(new_value);
- return get();
-}
-
-CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
- CFStringRef new_value = NULL;
- if (cf_type != NULL) {
- CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
-
- if (cf_type_id == ::CFStringGetTypeID()) {
- // Retain since we are using the existing object
- new_value = (CFStringRef)::CFRetain(cf_type);
- } else if (cf_type_id == ::CFURLGetTypeID()) {
- new_value =
- ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
- }
- }
- reset(new_value);
- return get();
-}
-
-CFStringRef
-CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
- std::string expanded_path;
- if (CFString::GlobPath(path, expanded_path))
- SetFileSystemRepresentation(expanded_path.c_str());
- else
- reset();
- return get();
-}
-
-const char *CFString::UTF8(std::string &str) {
- return CFString::UTF8(get(), str);
-}
-
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR and
-// returns the C string pointer that is contained in STR when successful, else
-// NULL is returned. This allows the std::string parameter to own the extracted
-// string,
-// and also allows that string to be returned as a C string pointer that can be
-// used.
-
-const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
- if (cf_str) {
- const CFStringEncoding encoding = kCFStringEncodingUTF8;
- CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
- max_utf8_str_len =
- CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
- if (max_utf8_str_len > 0) {
- str.resize(max_utf8_str_len);
- if (!str.empty()) {
- if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
- str.resize(strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- return NULL;
-}
-
-// Static function that puts a copy of the file system representation of CF_STR
-// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter to
-// own the extracted string, and also allows that string to be returned as a C
-// string pointer that can be used.
-
-const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
- std::string &str) {
- if (cf_str) {
- CFIndex max_length =
- ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
- if (max_length > 0) {
- str.resize(max_length);
- if (!str.empty()) {
- if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
- str.size())) {
- str.erase(::strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- str.erase();
- return NULL;
-}
-
-CFIndex CFString::GetLength() const {
- CFStringRef str = get();
- if (str)
- return CFStringGetLength(str);
- return 0;
-}
-
-const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
- glob_t globbuf;
- if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
- expanded_path = globbuf.gl_pathv[0];
- ::globfree(&globbuf);
- } else
- expanded_path.clear();
-
- return expanded_path.c_str();
-}
diff --git a/lldb/source/Plugins/Process/Darwin/CFString.h b/lldb/source/Plugins/Process/Darwin/CFString.h
deleted file mode 100644
index d1bd5682689e..000000000000
--- a/lldb/source/Plugins/Process/Darwin/CFString.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- CFString.h ----------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFString_h__
-#define __CFString_h__
-
-#include "CFUtils.h"
-#include <iosfwd>
-
-class CFString : public CFReleaser<CFStringRef> {
-public:
- // Constructors and Destructors
- CFString(CFStringRef cf_str = NULL);
- CFString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
- CFString(const CFString &rhs);
- CFString &operator=(const CFString &rhs);
- virtual ~CFString();
-
- const char *GetFileSystemRepresentation(std::string &str);
- CFStringRef SetFileSystemRepresentation(const char *path);
- CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type);
- CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path);
- const char *UTF8(std::string &str);
- CFIndex GetLength() const;
- static const char *UTF8(CFStringRef cf_str, std::string &str);
- static const char *FileSystemRepresentation(CFStringRef cf_str,
- std::string &str);
- static const char *GlobPath(const char *path, std::string &expanded_path);
-};
-
-#endif // #ifndef __CFString_h__
diff --git a/lldb/source/Plugins/Process/Darwin/CFUtils.h b/lldb/source/Plugins/Process/Darwin/CFUtils.h
deleted file mode 100644
index b567524ce63a..000000000000
--- a/lldb/source/Plugins/Process/Darwin/CFUtils.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 3/5/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFUtils_h__
-#define __CFUtils_h__
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#ifdef __cplusplus
-
-// Templatized CF helper class that can own any CF pointer and will
-// call CFRelease() on any valid pointer it owns unless that pointer is
-// explicitly released using the release() member function.
-template <class T> class CFReleaser {
-public:
- // Type names for the avlue
- typedef T element_type;
-
- // Constructors and destructors
- CFReleaser(T ptr = NULL) : _ptr(ptr) {}
- CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
- if (get())
- ::CFRetain(get());
- }
- virtual ~CFReleaser() { reset(); }
-
- // Assignments
- CFReleaser &operator=(const CFReleaser<T> &copy) {
- if (copy != *this) {
- // Replace our owned pointer with the new one
- reset(copy.get());
- // Retain the current pointer that we own
- if (get())
- ::CFRetain(get());
- }
- }
- // Get the address of the contained type
- T *ptr_address() { return &_ptr; }
-
- // Access the pointer itself
- const T get() const { return _ptr; }
- T get() { return _ptr; }
-
- // Set a new value for the pointer and CFRelease our old
- // value if we had a valid one.
- void reset(T ptr = NULL) {
- if (ptr != _ptr) {
- if (_ptr != NULL)
- ::CFRelease(_ptr);
- _ptr = ptr;
- }
- }
-
- // Release ownership without calling CFRelease
- T release() {
- T tmp = _ptr;
- _ptr = NULL;
- return tmp;
- }
-
-private:
- element_type _ptr;
-};
-
-#endif // #ifdef __cplusplus
-#endif // #ifndef __CFUtils_h__
diff --git a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
deleted file mode 100644
index f70ef97a2bc5..000000000000
--- a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ /dev/null
@@ -1,638 +0,0 @@
-//===-- DarwinProcessLauncher.cpp -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-//
-// DarwinProcessLauncher.cpp
-// lldb
-//
-// Created by Todd Fiala on 8/30/16.
-//
-//
-
-#include "DarwinProcessLauncher.h"
-
-// C includes
-#include <spawn.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-
-#ifndef _POSIX_SPAWN_DISABLE_ASLR
-#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
-#endif
-
-// LLDB includes
-#include "lldb/lldb-enumerations.h"
-
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-#include "llvm/Support/Errno.h"
-
-#include "CFBundle.h"
-#include "CFString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_darwin;
-using namespace lldb_private::darwin_process_launcher;
-
-namespace {
-static LaunchFlavor g_launch_flavor = LaunchFlavor::Default;
-}
-
-namespace lldb_private {
-namespace darwin_process_launcher {
-
-static uint32_t GetCPUTypeForLocalProcess(::pid_t pid) {
- int mib[CTL_MAXNAME] = {
- 0,
- };
- size_t len = CTL_MAXNAME;
- if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
- return 0;
-
- mib[len] = pid;
- len++;
-
- cpu_type_t cpu;
- size_t cpu_len = sizeof(cpu);
- if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
- cpu = 0;
- return cpu;
-}
-
-static bool ResolveExecutablePath(const char *path, char *resolved_path,
- size_t resolved_path_size) {
- if (path == NULL || path[0] == '\0')
- return false;
-
- char max_path[PATH_MAX];
- std::string result;
- CFString::GlobPath(path, result);
-
- if (result.empty())
- result = path;
-
- struct stat path_stat;
- if (::stat(path, &path_stat) == 0) {
- if ((path_stat.st_mode & S_IFMT) == S_IFDIR) {
- CFBundle bundle(path);
- CFReleaser<CFURLRef> url(bundle.CopyExecutableURL());
- if (url.get()) {
- if (::CFURLGetFileSystemRepresentation(
- url.get(), true, (UInt8 *)resolved_path, resolved_path_size))
- return true;
- }
- }
- }
-
- if (realpath(path, max_path)) {
- // Found the path relatively...
- ::strncpy(resolved_path, max_path, resolved_path_size);
- return strlen(resolved_path) + 1 < resolved_path_size;
- } else {
- // Not a relative path, check the PATH environment variable if the
- const char *PATH = getenv("PATH");
- if (PATH) {
- const char *curr_path_start = PATH;
- const char *curr_path_end;
- while (curr_path_start && *curr_path_start) {
- curr_path_end = strchr(curr_path_start, ':');
- if (curr_path_end == NULL) {
- result.assign(curr_path_start);
- curr_path_start = NULL;
- } else if (curr_path_end > curr_path_start) {
- size_t len = curr_path_end - curr_path_start;
- result.assign(curr_path_start, len);
- curr_path_start += len + 1;
- } else
- break;
-
- result += '/';
- result += path;
- struct stat s;
- if (stat(result.c_str(), &s) == 0) {
- ::strncpy(resolved_path, result.c_str(), resolved_path_size);
- return result.size() + 1 < resolved_path_size;
- }
- }
- }
- }
- return false;
-}
-
-// TODO check if we have a general purpose fork and exec. We may be
-// able to get rid of this entirely.
-static Status ForkChildForPTraceDebugging(const char *path, char const *argv[],
- char const *envp[], ::pid_t *pid,
- int *pty_fd) {
- Status error;
- if (!path || !argv || !envp || !pid || !pty_fd) {
- error.SetErrorString("invalid arguments");
- return error;
- }
-
- // Use a fork that ties the child process's stdin/out/err to a pseudo
- // terminal so we can read it in our MachProcess::STDIOThread as unbuffered
- // io.
- PseudoTerminal pty;
- char fork_error[256];
- memset(fork_error, 0, sizeof(fork_error));
- *pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error)));
- if (*pid < 0) {
- // Status during fork.
- *pid = static_cast<::pid_t>(LLDB_INVALID_PROCESS_ID);
- error.SetErrorStringWithFormat("%s(): fork failed: %s", __FUNCTION__,
- fork_error);
- return error;
- } else if (pid == 0) {
- // Child process
-
- // Debug this process.
- ::ptrace(PT_TRACE_ME, 0, 0, 0);
-
- // Get BSD signals as mach exceptions.
- ::ptrace(PT_SIGEXC, 0, 0, 0);
-
- // If our parent is setgid, lets make sure we don't inherit those extra
- // powers due to nepotism.
- if (::setgid(getgid()) == 0) {
- // Let the child have its own process group. We need to execute this call
- // in both the child and parent to avoid a race condition between the two
- // processes.
-
- // Set the child process group to match its pid.
- ::setpgid(0, 0);
-
- // Sleep a bit to before the exec call.
- ::sleep(1);
-
- // Turn this process into the given executable.
- ::execv(path, (char *const *)argv);
- }
- // Exit with error code. Child process should have taken over in above exec
- // call and if the exec fails it will exit the child process below.
- ::exit(127);
- } else {
- // Parent process
- // Let the child have its own process group. We need to execute this call
- // in both the child and parent to avoid a race condition between the two
- // processes.
-
- // Set the child process group to match its pid
- ::setpgid(*pid, *pid);
- if (pty_fd) {
- // Release our master pty file descriptor so the pty class doesn't close
- // it and so we can continue to use it in our STDIO thread
- *pty_fd = pty.ReleaseMasterFileDescriptor();
- }
- }
- return error;
-}
-
-static Status
-CreatePosixSpawnFileAction(const FileAction &action,
- posix_spawn_file_actions_t *file_actions) {
- Status error;
-
- // Log it.
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log) {
- StreamString stream;
- stream.PutCString("converting file action for posix_spawn(): ");
- action.Dump(stream);
- stream.Flush();
- log->PutCString(stream.GetString().c_str());
- }
-
- // Validate args.
- if (!file_actions) {
- error.SetErrorString("mandatory file_actions arg is null");
- return error;
- }
-
- // Build the posix file action.
- switch (action.GetAction()) {
- case FileAction::eFileActionOpen: {
- const int error_code = ::posix_spawn_file_actions_addopen(
- file_actions, action.GetFD(), action.GetPath(),
- action.GetActionArgument(), 0);
- if (error_code != 0) {
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
- break;
- }
-
- case FileAction::eFileActionClose: {
- const int error_code =
- ::posix_spawn_file_actions_addclose(file_actions, action.GetFD());
- if (error_code != 0) {
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
- break;
- }
-
- case FileAction::eFileActionDuplicate: {
- const int error_code = ::posix_spawn_file_actions_adddup2(
- file_actions, action.GetFD(), action.GetActionArgument());
- if (error_code != 0) {
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
- break;
- }
-
- case FileAction::eFileActionNone:
- default:
- LLDB_LOGF(log, "%s(): unsupported file action %u", __FUNCTION__,
- action.GetAction());
- break;
- }
-
- return error;
-}
-
-static Status PosixSpawnChildForPTraceDebugging(const char *path,
- ProcessLaunchInfo &launch_info,
- ::pid_t *pid,
- cpu_type_t *actual_cpu_type) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!pid) {
- error.SetErrorStringWithFormat("%s(): pid arg cannot be null",
- __FUNCTION__);
- return error;
- }
-
- posix_spawnattr_t attr;
- short flags;
- if (log) {
- StreamString stream;
- stream.Printf("%s(path='%s',...)\n", __FUNCTION__, path);
- launch_info.Dump(stream, nullptr);
- stream.Flush();
- log->PutCString(stream.GetString().c_str());
- }
-
- int error_code;
- if ((error_code = ::posix_spawnattr_init(&attr)) != 0) {
- LLDB_LOGF(log, "::posix_spawnattr_init(&attr) failed");
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
-
- // Ensure we clean up the spawnattr structure however we exit this function.
- std::unique_ptr<posix_spawnattr_t, int (*)(posix_spawnattr_t *)> spawnattr_up(
- &attr, ::posix_spawnattr_destroy);
-
- flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF |
- POSIX_SPAWN_SETSIGMASK;
- if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
- flags |= _POSIX_SPAWN_DISABLE_ASLR;
-
- sigset_t no_signals;
- sigset_t all_signals;
- sigemptyset(&no_signals);
- sigfillset(&all_signals);
- ::posix_spawnattr_setsigmask(&attr, &no_signals);
- ::posix_spawnattr_setsigdefault(&attr, &all_signals);
-
- if ((error_code = ::posix_spawnattr_setflags(&attr, flags)) != 0) {
- LLDB_LOG(log,
- "::posix_spawnattr_setflags(&attr, "
- "POSIX_SPAWN_START_SUSPENDED{0}) failed: {1}",
- flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR"
- : "",
- llvm::sys::StrError(error_code));
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
-
-#if !defined(__arm__)
-
- // We don't need to do this for ARM, and we really shouldn't now that we have
- // multiple CPU subtypes and no posix_spawnattr call that allows us to set
- // which CPU subtype to launch...
- cpu_type_t desired_cpu_type = launch_info.GetArchitecture().GetMachOCPUType();
- if (desired_cpu_type != LLDB_INVALID_CPUTYPE) {
- size_t ocount = 0;
- error_code =
- ::posix_spawnattr_setbinpref_np(&attr, 1, &desired_cpu_type, &ocount);
- if (error_code != 0) {
- LLDB_LOG(log,
- "::posix_spawnattr_setbinpref_np(&attr, 1, "
- "cpu_type = {0:x8}, count => {1}): {2}",
- desired_cpu_type, ocount, llvm::sys::StrError(error_code));
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
- if (ocount != 1) {
- error.SetErrorStringWithFormat("posix_spawnattr_setbinpref_np "
- "did not set the expected number "
- "of cpu_type entries: expected 1 "
- "but was %zu",
- ocount);
- return error;
- }
- }
-#endif
-
- posix_spawn_file_actions_t file_actions;
- if ((error_code = ::posix_spawn_file_actions_init(&file_actions)) != 0) {
- LLDB_LOG(log, "::posix_spawn_file_actions_init(&file_actions) failed: {0}",
- llvm::sys::StrError(error_code));
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
-
- // Ensure we clean up file actions however we exit this. When the
- // file_actions_up below goes out of scope, we'll get our file action
- // cleanup.
- std::unique_ptr<posix_spawn_file_actions_t,
- int (*)(posix_spawn_file_actions_t *)>
- file_actions_up(&file_actions, ::posix_spawn_file_actions_destroy);
-
- // We assume the caller has setup the file actions appropriately. We are not
- // in the business of figuring out what we really need here. lldb-server will
- // have already called FinalizeFileActions() as well to button these up
- // properly.
- const size_t num_actions = launch_info.GetNumFileActions();
- for (size_t action_index = 0; action_index < num_actions; ++action_index) {
- const FileAction *const action =
- launch_info.GetFileActionAtIndex(action_index);
- if (!action)
- continue;
-
- error = CreatePosixSpawnFileAction(*action, &file_actions);
- if (!error.Success()) {
- LLDB_LOGF(log,
- "%s(): error converting FileAction to posix_spawn "
- "file action: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- }
-
- // TODO: Verify if we can set the working directory back immediately
- // after the posix_spawnp call without creating a race condition???
- const char *const working_directory =
- launch_info.GetWorkingDirectory().GetCString();
- if (working_directory && working_directory[0])
- ::chdir(working_directory);
-
- auto argv = launch_info.GetArguments().GetArgumentVector();
- auto envp = launch_info.GetEnvironmentEntries().GetArgumentVector();
- error_code = ::posix_spawnp(pid, path, &file_actions, &attr,
- (char *const *)argv, (char *const *)envp);
- if (error_code != 0) {
- LLDB_LOG(log,
- "::posix_spawnp(pid => {0}, path = '{1}', file_actions "
- "= {2}, attr = {3}, argv = {4}, envp = {5}) failed: {6}",
- pid, path, &file_actions, &attr, argv, envp,
- llvm::sys::StrError(error_code));
- error.SetError(error_code, eErrorTypePOSIX);
- return error;
- }
-
- // Validate we got a pid.
- if (pid == LLDB_INVALID_PROCESS_ID) {
- error.SetErrorString("posix_spawn() did not indicate a failure but it "
- "failed to return a pid, aborting.");
- return error;
- }
-
- if (actual_cpu_type) {
- *actual_cpu_type = GetCPUTypeForLocalProcess(*pid);
- LLDB_LOGF(log,
- "%s(): cpu type for launched process pid=%i: "
- "cpu_type=0x%8.8x",
- __FUNCTION__, *pid, *actual_cpu_type);
- }
-
- return error;
-}
-
-Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
- LaunchFlavor *launch_flavor) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!launch_flavor) {
- error.SetErrorString("mandatory launch_flavor field was null");
- return error;
- }
-
- if (log) {
- StreamString stream;
- stream.Printf("NativeProcessDarwin::%s(): launching with the "
- "following launch info:",
- __FUNCTION__);
- launch_info.Dump(stream, nullptr);
- stream.Flush();
- log->PutCString(stream.GetString().c_str());
- }
-
- // Retrieve the binary name given to us.
- char given_path[PATH_MAX];
- given_path[0] = '\0';
- launch_info.GetExecutableFile().GetPath(given_path, sizeof(given_path));
-
- // Determine the manner in which we'll launch.
- *launch_flavor = g_launch_flavor;
- if (*launch_flavor == LaunchFlavor::Default) {
- // Our default launch method is posix spawn
- *launch_flavor = LaunchFlavor::PosixSpawn;
-#if defined WITH_FBS
- // Check if we have an app bundle, if so launch using BackBoard Services.
- if (strstr(given_path, ".app")) {
- *launch_flavor = eLaunchFlavorFBS;
- }
-#elif defined WITH_BKS
- // Check if we have an app bundle, if so launch using BackBoard Services.
- if (strstr(given_path, ".app")) {
- *launch_flavor = eLaunchFlavorBKS;
- }
-#elif defined WITH_SPRINGBOARD
- // Check if we have an app bundle, if so launch using SpringBoard.
- if (strstr(given_path, ".app")) {
- *launch_flavor = eLaunchFlavorSpringBoard;
- }
-#endif
- }
-
- // Attempt to resolve the binary name to an absolute path.
- char resolved_path[PATH_MAX];
- resolved_path[0] = '\0';
-
- LLDB_LOGF(log, "%s(): attempting to resolve given binary path: \"%s\"",
- __FUNCTION__, given_path);
-
- // If we fail to resolve the path to our executable, then just use what we
- // were given and hope for the best
- if (!ResolveExecutablePath(given_path, resolved_path,
- sizeof(resolved_path))) {
- LLDB_LOGF(log,
- "%s(): failed to resolve binary path, using "
- "what was given verbatim and hoping for the best",
- __FUNCTION__);
- ::strncpy(resolved_path, given_path, sizeof(resolved_path));
- } else {
- LLDB_LOGF(log, "%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
- resolved_path);
- }
-
- char launch_err_str[PATH_MAX];
- launch_err_str[0] = '\0';
-
- // TODO figure out how to handle QSetProcessEvent
- // const char *process_event = ctx.GetProcessEvent();
-
- // Ensure the binary is there.
- struct stat path_stat;
- if (::stat(resolved_path, &path_stat) == -1) {
- error.SetErrorToErrno();
- return error;
- }
-
- // Fork a child process for debugging
- // state_callback(eStateLaunching);
-
- const auto argv = launch_info.GetArguments().GetConstArgumentVector();
- const auto envp =
- launch_info.GetEnvironmentEntries().GetConstArgumentVector();
-
- switch (*launch_flavor) {
- case LaunchFlavor::ForkExec: {
- ::pid_t pid = LLDB_INVALID_PROCESS_ID;
- error = ForkChildForPTraceDebugging(resolved_path, argv, envp, &pid,
- pty_master_fd);
- if (error.Success()) {
- launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
- } else {
- // Reset any variables that might have been set during a failed launch
- // attempt.
- if (pty_master_fd)
- *pty_master_fd = -1;
-
- // We're done.
- return error;
- }
- } break;
-
-#ifdef WITH_FBS
- case LaunchFlavor::FBS: {
- const char *app_ext = strstr(path, ".app");
- if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
- std::string app_bundle_path(path, app_ext + strlen(".app"));
- m_flags |= eMachProcessFlagsUsingFBS;
- if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
- no_stdio, disable_aslr, event_data,
- launch_err) != 0)
- return m_pid; // A successful SBLaunchForDebug() returns and assigns a
- // non-zero m_pid.
- else
- break; // We tried a FBS launch, but didn't succeed lets get out
- }
- } break;
-#endif
-
-#ifdef WITH_BKS
- case LaunchFlavor::BKS: {
- const char *app_ext = strstr(path, ".app");
- if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
- std::string app_bundle_path(path, app_ext + strlen(".app"));
- m_flags |= eMachProcessFlagsUsingBKS;
- if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
- no_stdio, disable_aslr, event_data,
- launch_err) != 0)
- return m_pid; // A successful SBLaunchForDebug() returns and assigns a
- // non-zero m_pid.
- else
- break; // We tried a BKS launch, but didn't succeed lets get out
- }
- } break;
-#endif
-
-#ifdef WITH_SPRINGBOARD
- case LaunchFlavor::SpringBoard: {
- // .../whatever.app/whatever ?
- // Or .../com.apple.whatever.app/whatever -- be careful of ".app" in
- // "com.apple.whatever" here
- const char *app_ext = strstr(path, ".app/");
- if (app_ext == NULL) {
- // .../whatever.app ?
- int len = strlen(path);
- if (len > 5) {
- if (strcmp(path + len - 4, ".app") == 0) {
- app_ext = path + len - 4;
- }
- }
- }
- if (app_ext) {
- std::string app_bundle_path(path, app_ext + strlen(".app"));
- if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio,
- disable_aslr, launch_err) != 0)
- return m_pid; // A successful SBLaunchForDebug() returns and assigns a
- // non-zero m_pid.
- else
- break; // We tried a springboard launch, but didn't succeed lets get out
- }
- } break;
-#endif
-
- case LaunchFlavor::PosixSpawn: {
- ::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
- // Retrieve paths for stdin/stdout/stderr.
- cpu_type_t actual_cpu_type = 0;
- error = PosixSpawnChildForPTraceDebugging(resolved_path, launch_info, &pid,
- &actual_cpu_type);
- if (error.Success()) {
- launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
- if (pty_master_fd)
- *pty_master_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- } else {
- // Reset any variables that might have been set during a failed launch
- // attempt.
- if (pty_master_fd)
- *pty_master_fd = -1;
-
- // We're done.
- return error;
- }
- break;
- }
-
- default:
- // Invalid launch flavor.
- error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): unknown "
- "launch flavor %d",
- __FUNCTION__, (int)*launch_flavor);
- return error;
- }
-
- if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
- // If we don't have a valid process ID and no one has set the error, then
- // return a generic error.
- if (error.Success())
- error.SetErrorStringWithFormat("%s(): failed to launch, no reason "
- "specified",
- __FUNCTION__);
- }
-
- // We're done with the launch side of the operation.
- return error;
-}
-}
-} // namespaces
diff --git a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.h b/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
deleted file mode 100644
index 0e65b56a143e..000000000000
--- a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- DarwinProcessLauncher.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DarwinProcessLauncher_h
-#define DarwinProcessLauncher_h
-
-// C headers
-#include <mach/machine.h>
-#include <sys/types.h>
-
-// C++ headers
-#include <functional>
-
-// LLDB headers
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-
-#include "LaunchFlavor.h"
-
-namespace lldb_private {
-namespace darwin_process_launcher {
-// =============================================================================
-/// Launches a process for debugging.
-///
-/// \param[inout] launch_info
-/// Specifies details about the process to launch (e.g. path, architecture,
-/// etc.). On output, includes the launched ProcessID (pid).
-///
-/// \param[out] pty_master_fd
-/// Returns the master side of the pseudo-terminal used to communicate
-/// with stdin/stdout from the launched process. May be nullptr.
-///
-/// \param[out] launch_flavor
-/// Contains the launch flavor used when launching the process.
-// =============================================================================
-Status
-LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
- lldb_private::process_darwin::LaunchFlavor *launch_flavor);
-
-} // darwin_process_launcher
-} // lldb_private
-
-#endif /* DarwinProcessLauncher_h */
diff --git a/lldb/source/Plugins/Process/Darwin/LaunchFlavor.h b/lldb/source/Plugins/Process/Darwin/LaunchFlavor.h
deleted file mode 100644
index cfd76d1b9c3c..000000000000
--- a/lldb/source/Plugins/Process/Darwin/LaunchFlavor.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- LaunchFlavor.h ---------------------------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LaunchFlavor_h
-#define LaunchFlavor_h
-
-namespace lldb_private {
-namespace process_darwin {
-
-enum class LaunchFlavor {
- Default = 0,
- PosixSpawn = 1,
- ForkExec = 2,
-#ifdef WITH_SPRINGBOARD
- SpringBoard = 3,
-#endif
-#ifdef WITH_BKS
- BKS = 4,
-#endif
-#ifdef WITH_FBS
- FBS = 5
-#endif
-};
-}
-} // namespaces
-
-#endif /* LaunchFlavor_h */
diff --git a/lldb/source/Plugins/Process/Darwin/MachException.cpp b/lldb/source/Plugins/Process/Darwin/MachException.cpp
deleted file mode 100644
index 073ad64b300c..000000000000
--- a/lldb/source/Plugins/Process/Darwin/MachException.cpp
+++ /dev/null
@@ -1,514 +0,0 @@
-//===-- MachException.cpp ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 6/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachException.h"
-
-// C includes
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <sys/types.h>
-
-// C++ includes
-#include <mutex>
-
-// LLDB includes
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Stream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_darwin;
-
-// Routine mach_exception_raise
-extern "C" kern_return_t
-catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread,
- mach_port_t task, exception_type_t exception,
- mach_exception_data_t code,
- mach_msg_type_number_t codeCnt);
-
-extern "C" kern_return_t catch_mach_exception_raise_state(
- mach_port_t exception_port, exception_type_t exception,
- const mach_exception_data_t code, mach_msg_type_number_t codeCnt,
- int *flavor, const thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt);
-
-// Routine mach_exception_raise_state_identity
-extern "C" kern_return_t catch_mach_exception_raise_state_identity(
- mach_port_t exception_port, mach_port_t thread, mach_port_t task,
- exception_type_t exception, mach_exception_data_t code,
- mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt);
-
-extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
- mach_msg_header_t *OutHeadP);
-
-static MachException::Data *g_message = NULL;
-
-extern "C" kern_return_t catch_mach_exception_raise_state(
- mach_port_t exc_port, exception_type_t exc_type,
- const mach_exception_data_t exc_data, mach_msg_type_number_t exc_data_count,
- int *flavor, const thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt) {
- // TODO change to LIBLLDB_LOG_EXCEPTION
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log) {
- LLDB_LOGF(log,
- "::%s(exc_port = 0x%4.4x, exc_type = %d (%s), "
- "exc_data = 0x%llx, exc_data_count = %d)",
- __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type),
- (uint64_t)exc_data, exc_data_count);
- }
- return KERN_FAILURE;
-}
-
-extern "C" kern_return_t catch_mach_exception_raise_state_identity(
- mach_port_t exc_port, mach_port_t thread_port, mach_port_t task_port,
- exception_type_t exc_type, mach_exception_data_t exc_data,
- mach_msg_type_number_t exc_data_count, int *flavor,
- thread_state_t old_state, mach_msg_type_number_t old_stateCnt,
- thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log) {
- LLDB_LOGF(log,
- "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
- "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = "
- "{ 0x%llx, 0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
- }
-
- return KERN_FAILURE;
-}
-
-extern "C" kern_return_t
-catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
- mach_port_t task_port, exception_type_t exc_type,
- mach_exception_data_t exc_data,
- mach_msg_type_number_t exc_data_count) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log) {
- LLDB_LOGF(log,
- "::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
- "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] "
- "= { 0x%llx, 0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
- }
-
- if (task_port == g_message->task_port) {
- g_message->task_port = task_port;
- g_message->thread_port = thread_port;
- g_message->exc_type = exc_type;
- g_message->exc_data.resize(exc_data_count);
- ::memcpy(&g_message->exc_data[0], exc_data,
- g_message->exc_data.size() * sizeof(mach_exception_data_type_t));
- return KERN_SUCCESS;
- }
- return KERN_FAILURE;
-}
-
-bool MachException::Data::GetStopInfo(struct ThreadStopInfo *stop_info,
- const UnixSignals &signals,
- Stream &stream) const {
- if (!stop_info)
- return false;
-
- // Zero out the structure.
- memset(stop_info, 0, sizeof(struct ThreadStopInfo));
-
- if (exc_type == 0) {
- stop_info->reason = eStopReasonInvalid;
- return true;
- }
-
- // We always stop with a mach exception.
- stop_info->reason = eStopReasonException;
- // Save the EXC_XXXX exception type.
- stop_info->details.exception.type = exc_type;
-
- // Fill in a text description
- const char *exc_name = MachException::Name(exc_type);
- if (exc_name)
- stream.Printf("%s", exc_name);
- else
- stream.Printf("%i", exc_type);
-
- stop_info->details.exception.data_count = exc_data.size();
-
- int soft_signal = SoftSignal();
- if (soft_signal) {
- const char *sig_str = signals.GetSignalAsCString(soft_signal);
- stream.Printf(" EXC_SOFT_SIGNAL( %i ( %s ))", soft_signal,
- sig_str ? sig_str : "unknown signal");
- } else {
- // No special disassembly for exception data, just print it.
- size_t idx;
- stream.Printf(" data[%llu] = {",
- (uint64_t)stop_info->details.exception.data_count);
-
- for (idx = 0; idx < stop_info->details.exception.data_count; ++idx) {
- stream.Printf(
- "0x%llx%c", (uint64_t)exc_data[idx],
- ((idx + 1 == stop_info->details.exception.data_count) ? '}' : ','));
- }
- }
-
- // Copy the exception data
- for (size_t i = 0; i < stop_info->details.exception.data_count; i++)
- stop_info->details.exception.data[i] = exc_data[i];
-
- return true;
-}
-
-Status MachException::Message::Receive(mach_port_t port,
- mach_msg_option_t options,
- mach_msg_timeout_t timeout,
- mach_port_t notify_port) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- mach_msg_timeout_t mach_msg_timeout =
- options & MACH_RCV_TIMEOUT ? timeout : 0;
- if (log && ((options & MACH_RCV_TIMEOUT) == 0)) {
- // Dump this log message if we have no timeout in case it never returns
- LLDB_LOGF(log,
- "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
- "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = 0, rcv_size = %llu, "
- "rcv_name = %#x, timeout = %u, notify = %#x)",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
- (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
- notify_port);
- }
-
- mach_msg_return_t mach_err =
- ::mach_msg(&exc_msg.hdr,
- options, // options
- 0, // Send size
- sizeof(exc_msg.data), // Receive size
- port, // exception port to watch for
- // exception on
- mach_msg_timeout, // timeout in msec (obeyed only
- // if MACH_RCV_TIMEOUT is ORed
- // into the options parameter)
- notify_port);
- error.SetError(mach_err, eErrorTypeMachKernel);
-
- // Dump any errors we get
- if (error.Fail() && log) {
- LLDB_LOGF(log,
- "::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
- "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %lu, rcv_name "
- "= %#x, timeout = %u, notify = %#x) failed: %s",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
- sizeof(exc_msg.data), port, mach_msg_timeout, notify_port,
- error.AsCString());
- }
- return error;
-}
-
-void MachException::Message::Dump(Stream &stream) const {
- stream.Printf(" exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
- "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
- "0x%8.8x }\n",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id);
-
- stream.Printf(" reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
- "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
- "0x%8.8x }",
- reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id);
-}
-
-bool MachException::Message::CatchExceptionRaise(task_t task) {
- bool success = false;
- state.task_port = task;
- g_message = &state;
- // The exc_server function is the MIG generated server handling function to
- // handle messages from the kernel relating to the occurrence of an exception
- // in a thread. Such messages are delivered to the exception port set via
- // thread_set_exception_ports or task_set_exception_ports. When an exception
- // occurs in a thread, the thread sends an exception message to its exception
- // port, blocking in the kernel waiting for the receipt of a reply. The
- // exc_server function performs all necessary argument handling for this
- // kernel message and calls catch_exception_raise,
- // catch_exception_raise_state or catch_exception_raise_state_identity, which
- // should handle the exception. If the called routine returns KERN_SUCCESS, a
- // reply message will be sent, allowing the thread to continue from the point
- // of the exception; otherwise, no reply message is sent and the called
- // routine must have dealt with the exception thread directly.
- if (mach_exc_server(&exc_msg.hdr, &reply_msg.hdr)) {
- success = true;
- } else {
- Log *log(
- GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- LLDB_LOGF(log,
- "MachException::Message::%s(): mach_exc_server "
- "returned zero...",
- __FUNCTION__);
- }
- g_message = NULL;
- return success;
-}
-
-Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
- int signal) {
- // Reply to the exception...
- Status error;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- // If we had a soft signal, we need to update the thread first so it can
- // continue without signaling
- int soft_signal = state.SoftSignal();
- if (soft_signal) {
- int state_pid = -1;
- if (inferior_task == state.task_port) {
- // This is our task, so we can update the signal to send to it
- state_pid = inferior_pid;
- soft_signal = signal;
- } else {
- auto mach_err = ::pid_for_task(state.task_port, &state_pid);
- if (mach_err) {
- error.SetError(mach_err, eErrorTypeMachKernel);
- LLDB_LOGF(log,
- "MachException::Message::%s(): pid_for_task() "
- "failed: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- }
-
- lldbassert(state_pid != -1);
- if (state_pid != -1) {
- errno = 0;
- caddr_t thread_port_caddr = (caddr_t)(uintptr_t)state.thread_port;
- if (::ptrace(PT_THUPDATE, state_pid, thread_port_caddr, soft_signal) != 0)
- error.SetError(errno, eErrorTypePOSIX);
-
- if (!error.Success()) {
- LLDB_LOGF(log,
- "::ptrace(request = PT_THUPDATE, pid = "
- "0x%4.4x, tid = 0x%4.4x, signal = %i)",
- state_pid, state.thread_port, soft_signal);
- return error;
- }
- }
- }
-
- LLDB_LOGF(log,
- "::mach_msg ( msg->{bits = %#x, size = %u, remote_port "
- "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %u, rcv_name "
- "= %#x, timeout = %u, notify = %#x)",
- reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
- MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
- MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-
- auto mach_err =
- ::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
- reply_msg.hdr.msgh_size, 0, MACH_PORT_NULL,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (mach_err)
- error.SetError(mach_err, eErrorTypeMachKernel);
-
- // Log our error if we have one.
- if (error.Fail() && log) {
- if (error.GetError() == MACH_SEND_INTERRUPTED) {
- log->PutCString("::mach_msg() - send interrupted");
- // TODO: keep retrying to reply???
- } else if (state.task_port == inferior_task) {
- LLDB_LOGF(log,
- "mach_msg(): returned an error when replying "
- "to a mach exception: error = %u (%s)",
- error.GetError(), error.AsCString());
- } else {
- LLDB_LOGF(log, "::mach_msg() - failed (child of task): %u (%s)",
- error.GetError(), error.AsCString());
- }
- }
-
- return error;
-}
-
-#define PREV_EXC_MASK_ALL \
- (EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | \
- EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT | \
- EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT | \
- EXC_MASK_MACHINE)
-
-// Don't listen for EXC_RESOURCE, it should really get handled by the system
-// handler.
-
-#ifndef EXC_RESOURCE
-#define EXC_RESOURCE 11
-#endif
-
-#ifndef EXC_MASK_RESOURCE
-#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
-#endif
-
-#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
-
-Status MachException::PortInfo::Save(task_t task) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- LLDB_LOGF(log, "MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
- task);
-
- // Be careful to be able to have debugserver built on a newer OS than what it
- // is currently running on by being able to start with all exceptions and
- // back off to just what is supported on the current system
- mask = LLDB_EXC_MASK;
-
- count = (sizeof(ports) / sizeof(ports[0]));
- auto mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
- behaviors, flavors);
- if (mach_err)
- error.SetError(mach_err, eErrorTypeMachKernel);
-
- if (log) {
- if (error.Success()) {
- LLDB_LOGF(log,
- "::task_get_exception_ports(task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors)",
- task, mask, count);
- } else {
- LLDB_LOGF(log,
- "::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, "
- "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)",
- task, mask, count, error.GetError(), error.AsCString());
- }
- }
-
- if ((error.GetError() == KERN_INVALID_ARGUMENT) &&
- (mask != PREV_EXC_MASK_ALL)) {
- mask = PREV_EXC_MASK_ALL;
- count = (sizeof(ports) / sizeof(ports[0]));
- mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
- behaviors, flavors);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (log) {
- if (error.Success()) {
- LLDB_LOGF(log,
- "::task_get_exception_ports(task = 0x%4.4x, "
- "mask = 0x%x, maskCnt => %u, ports, behaviors, "
- "flavors)",
- task, mask, count);
- } else {
- LLDB_LOGF(log,
- "::task_get_exception_ports(task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors) "
- "error: %u (%s)",
- task, mask, count, error.GetError(), error.AsCString());
- }
- }
- }
- if (error.Fail()) {
- mask = 0;
- count = 0;
- }
- return error;
-}
-
-Status MachException::PortInfo::Restore(task_t task) {
- Status error;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- LLDB_LOGF(log, "MachException::PortInfo::Restore(task = 0x%4.4x)", task);
-
- uint32_t i = 0;
- if (count > 0) {
- for (i = 0; i < count; i++) {
- auto mach_err = ::task_set_exception_ports(task, masks[i], ports[i],
- behaviors[i], flavors[i]);
- if (mach_err)
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (log) {
- if (error.Success()) {
- LLDB_LOGF(log,
- "::task_set_exception_ports(task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x)",
- task, masks[i], ports[i], behaviors[i], flavors[i]);
- } else {
- LLDB_LOGF(log,
- "::task_set_exception_ports(task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x): "
- "error %u (%s)",
- task, masks[i], ports[i], behaviors[i], flavors[i],
- error.GetError(), error.AsCString());
- }
- }
-
- // Bail if we encounter any errors
- if (error.Fail())
- break;
- }
- }
-
- count = 0;
- return error;
-}
-
-const char *MachException::Name(exception_type_t exc_type) {
- switch (exc_type) {
- case EXC_BAD_ACCESS:
- return "EXC_BAD_ACCESS";
- case EXC_BAD_INSTRUCTION:
- return "EXC_BAD_INSTRUCTION";
- case EXC_ARITHMETIC:
- return "EXC_ARITHMETIC";
- case EXC_EMULATION:
- return "EXC_EMULATION";
- case EXC_SOFTWARE:
- return "EXC_SOFTWARE";
- case EXC_BREAKPOINT:
- return "EXC_BREAKPOINT";
- case EXC_SYSCALL:
- return "EXC_SYSCALL";
- case EXC_MACH_SYSCALL:
- return "EXC_MACH_SYSCALL";
- case EXC_RPC_ALERT:
- return "EXC_RPC_ALERT";
-#ifdef EXC_CRASH
- case EXC_CRASH:
- return "EXC_CRASH";
-#endif
- default:
- break;
- }
- return NULL;
-}
diff --git a/lldb/source/Plugins/Process/Darwin/MachException.h b/lldb/source/Plugins/Process/Darwin/MachException.h
deleted file mode 100644
index 18e49173b020..000000000000
--- a/lldb/source/Plugins/Process/Darwin/MachException.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===-- MachException.h -----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 6/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachException_h__
-#define __MachException_h__
-
-#include <mach/mach.h>
-#include <vector>
-
-#include "lldb/Host/Debug.h"
-#include "lldb/lldb-private-forward.h"
-#include "lldb/lldb-types.h"
-
-namespace lldb_private {
-namespace process_darwin {
-
-typedef union MachMessageTag {
- mach_msg_header_t hdr;
- char data[1024];
-} MachMessage;
-
-class MachException {
-public:
- struct PortInfo {
- exception_mask_t mask; // the exception mask for this device which may be a
- // subset of EXC_MASK_ALL...
- exception_mask_t masks[EXC_TYPES_COUNT];
- mach_port_t ports[EXC_TYPES_COUNT];
- exception_behavior_t behaviors[EXC_TYPES_COUNT];
- thread_state_flavor_t flavors[EXC_TYPES_COUNT];
- mach_msg_type_number_t count;
-
- Status Save(task_t task);
-
- Status Restore(task_t task);
- };
-
- struct Data {
- task_t task_port;
- thread_t thread_port;
- exception_type_t exc_type;
- std::vector<mach_exception_data_type_t> exc_data;
- Data()
- : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0),
- exc_data() {}
-
- void Clear() {
- task_port = TASK_NULL;
- thread_port = THREAD_NULL;
- exc_type = 0;
- exc_data.clear();
- }
-
- bool IsValid() const {
- return task_port != TASK_NULL && thread_port != THREAD_NULL &&
- exc_type != 0;
- }
-
- // Return the SoftSignal for this MachException data, or zero if there is
- // none
- int SoftSignal() const {
- if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 &&
- exc_data[0] == EXC_SOFT_SIGNAL)
- return static_cast<int>(exc_data[1]);
- return 0;
- }
-
- bool IsBreakpoint() const {
- return (exc_type == EXC_BREAKPOINT ||
- ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
- }
-
- bool GetStopInfo(ThreadStopInfo *stop_info, const UnixSignals &signals,
- Stream &stream) const;
- };
-
- struct Message {
- MachMessage exc_msg;
- MachMessage reply_msg;
- Data state;
-
- Message() : state() {
- memset(&exc_msg, 0, sizeof(exc_msg));
- memset(&reply_msg, 0, sizeof(reply_msg));
- }
-
- bool CatchExceptionRaise(task_t task);
-
- Status Reply(::pid_t inferior_pid, task_t inferior_task, int signal);
-
- Status Receive(mach_port_t receive_port, mach_msg_option_t options,
- mach_msg_timeout_t timeout,
- mach_port_t notify_port = MACH_PORT_NULL);
-
- void Dump(Stream &stream) const;
-
- typedef std::vector<Message> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- enum {
- e_actionForward, // Forward signal to inferior process
- e_actionStop, // Stop when this signal is received
- };
- struct Action {
- task_t task_port; // Set to TASK_NULL for any TASK
- thread_t thread_port; // Set to THREAD_NULL for any thread
- exception_type_t exc_mask; // Mach exception mask to watch for
- std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to
- // exception data, or
- // empty to ignore
- // exc_data value for
- // exception
- std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare
- // to exception data
- // after masking, or
- // empty to ignore
- // exc_data value
- // for exception
- uint8_t flags; // Action flags describing what to do with the exception
- };
-
- static const char *Name(exception_type_t exc_type);
-};
-
-} // namespace process_darwin
-} // namespace lldb_private
-
-#endif
diff --git a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
deleted file mode 100644
index 18dbdda9a33b..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ /dev/null
@@ -1,1535 +0,0 @@
-//===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeProcessDarwin.h"
-
-// C includes
-#include <mach/mach_init.h>
-#include <mach/mach_traps.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-
-// C++ includes
-// LLDB includes
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "CFBundle.h"
-#include "CFString.h"
-#include "DarwinProcessLauncher.h"
-
-#include "MachException.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_darwin;
-using namespace lldb_private::darwin_process_launcher;
-
-// Hidden Impl
-
-namespace {
-struct hack_task_dyld_info {
- mach_vm_address_t all_image_info_addr;
- mach_vm_size_t all_image_info_size;
-};
-}
-
-// Public Static Methods
-
-Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info,
- NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
- NativeProcessProtocolSP &native_process_sp) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- Status error;
-
- // Verify the working directory is valid if one was specified.
- FileSpec working_dir(launch_info.GetWorkingDirectory());
- if (working_dir) {
- FileInstance::Instance().Resolve(working_dir);
- if (!FileSystem::Instance().IsDirectory(working_dir)) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
- }
- }
-
- // Launch the inferior.
- int pty_master_fd = -1;
- LaunchFlavor launch_flavor = LaunchFlavor::Default;
-
- error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);
-
- // Handle launch failure.
- if (!error.Success()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() failed to launch process: "
- "%s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Handle failure to return a pid.
- if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() launch succeeded but no "
- "pid was returned! Aborting.",
- __FUNCTION__);
- return error;
- }
-
- // Create the Darwin native process impl.
- std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
- new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
- if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
- native_process_sp.reset();
- error.SetErrorStringWithFormat("failed to register the native delegate");
- return error;
- }
-
- // Finalize the processing needed to debug the launched process with a
- // NativeProcessDarwin instance.
- error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
- if (!error.Success()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() aborting, failed to finalize"
- " the launching of the process: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Return the process and process id to the caller through the launch args.
- native_process_sp = np_darwin_sp;
- return error;
-}
-
-Status NativeProcessProtocol::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- LLDB_LOGF(log, "NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
- pid);
-
- // Retrieve the architecture for the running process.
- ArchSpec process_arch;
- Status error = ResolveProcessArchitecture(pid, process_arch);
- if (!error.Success())
- return error;
-
- // TODO get attach to return this value.
- const int pty_master_fd = -1;
- std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
- new NativeProcessDarwin(pid, pty_master_fd));
-
- if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
- error.SetErrorStringWithFormat("failed to register the native "
- "delegate");
- return error;
- }
-
- native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
- if (!error.Success())
- return error;
-
- native_process_sp = native_process_darwin_sp;
- return error;
-}
-
-// ctor/dtor
-
-NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
- : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
- m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
- m_exception_thread(nullptr), m_exception_messages_mutex(),
- m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
- m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
- m_waitpid_reader_handle() {
- // TODO add this to the NativeProcessProtocol constructor.
- m_terminal_fd = pty_master_fd;
-}
-
-NativeProcessDarwin::~NativeProcessDarwin() {}
-
-// Instance methods
-
-Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
- MainLoop &main_loop) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- error = StartExceptionThread();
- if (!error.Success()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failure starting the "
- "mach exception port monitor thread: %s",
- __FUNCTION__, error.AsCString());
-
- // Terminate the inferior process. There's nothing meaningful we can do if
- // we can't receive signals and exceptions. Since we launched the process,
- // it's fair game for us to kill it.
- ::ptrace(PT_KILL, m_pid, 0, 0);
- SetState(eStateExited);
-
- return error;
- }
-
- StartSTDIOThread();
-
- if (launch_flavor == LaunchFlavor::PosixSpawn) {
- SetState(eStateAttaching);
- errno = 0;
- int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
- if (err == 0) {
- // m_flags |= eMachProcessFlagsAttached;
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): successfully spawned "
- "process with pid %" PRIu64,
- __FUNCTION__, m_pid);
- } else {
- error.SetErrorToErrno();
- SetState(eStateExited);
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): error: failed to "
- "attach to spawned pid %" PRIu64 " (error=%d (%s))",
- __FUNCTION__, m_pid, (int)error.GetError(), error.AsCString());
- return error;
- }
- }
-
- LLDB_LOGF(log, "NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
- __FUNCTION__, m_pid);
-
- // Spawn a thread to reap our child inferior process...
- error = StartWaitpidThread(main_loop);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to start waitpid() "
- "thread: %s",
- __FUNCTION__, error.AsCString());
- kill(SIGKILL, static_cast<::pid_t>(m_pid));
- return error;
- }
-
- if (TaskPortForProcessID(error) == TASK_NULL) {
- // We failed to get the task for our process ID which is bad. Kill our
- // process; otherwise, it will be stopped at the entry point and get
- // reparented to someone else and never go away.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): could not get task port "
- "for process, sending SIGKILL and exiting: %s",
- __FUNCTION__, error.AsCString());
- kill(SIGKILL, static_cast<::pid_t>(m_pid));
- return error;
- }
-
- // Indicate that we're stopped, as we always launch suspended.
- SetState(eStateStopped);
-
- // Success.
- return error;
-}
-
-Status NativeProcessDarwin::SaveExceptionPortInfo() {
- return m_exc_port_info.Save(m_task);
-}
-
-bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
- // TODO implement flags
- // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
- return false;
-}
-
-bool NativeProcessDarwin::ProcessUsingBackBoard() const {
- // TODO implement flags
- // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
- return false;
-}
-
-// Called by the exception thread when an exception has been received from our
-// process. The exception message is completely filled and the exception data
-// has already been copied.
-void NativeProcessDarwin::ExceptionMessageReceived(
- const MachException::Message &message) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- if (m_exception_messages.empty()) {
- // Suspend the task the moment we receive our first exception message.
- SuspendTask();
- }
-
- // Use a locker to automatically unlock our mutex in case of exceptions Add
- // the exception to our internal exception stack
- m_exception_messages.push_back(message);
-
- LLDB_LOGF(log, "NativeProcessDarwin::%s(): new queued message count: %lu",
- __FUNCTION__, m_exception_messages.size());
-}
-
-void *NativeProcessDarwin::ExceptionThread(void *arg) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (!arg) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): cannot run mach exception "
- "thread, mandatory process arg was null",
- __FUNCTION__);
- return nullptr;
- }
-
- return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
-}
-
-void *NativeProcessDarwin::DoExceptionThread() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- LLDB_LOGF(log, "NativeProcessDarwin::%s(arg=%p) starting thread...",
- __FUNCTION__, this);
-
- pthread_setname_np("exception monitoring thread");
-
- // Ensure we don't get CPU starved.
- MaybeRaiseThreadPriority();
-
- // We keep a count of the number of consecutive exceptions received so we
- // know to grab all exceptions without a timeout. We do this to get a bunch
- // of related exceptions on our exception port so we can process then
- // together. When we have multiple threads, we can get an exception per
- // thread and they will come in consecutively. The main loop in this thread
- // can stop periodically if needed to service things related to this process.
- //
- // [did we lose some words here?]
- //
- // flag set in the options, so we will wait forever for an exception on
- // 0 our exception port. After we get one exception, we then will use the
- // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
- // exceptions for our process. After we have received the last pending
- // exception, we will get a timeout which enables us to then notify our main
- // thread that we have an exception bundle available. We then wait for the
- // main thread to tell this exception thread to start trying to get
- // exceptions messages again and we start again with a mach_msg read with
- // infinite timeout.
- //
- // We choose to park a thread on this, rather than polling, because the
- // polling is expensive. On devices, we need to minimize overhead caused by
- // the process monitor.
- uint32_t num_exceptions_received = 0;
- Status error;
- task_t task = m_task;
- mach_msg_timeout_t periodic_timeout = 0;
-
-#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
- mach_msg_timeout_t watchdog_elapsed = 0;
- mach_msg_timeout_t watchdog_timeout = 60 * 1000;
- ::pid_t pid = (::pid_t)process->GetID();
- CFReleaser<SBSWatchdogAssertionRef> watchdog;
-
- if (process->ProcessUsingSpringBoard()) {
- // Request a renewal for every 60 seconds if we attached using SpringBoard.
- watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
- LLDB_LOGF(log,
- "::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
- "=> %p",
- pid, watchdog.get());
-
- if (watchdog.get()) {
- ::SBSWatchdogAssertionRenew(watchdog.get());
-
- CFTimeInterval watchdogRenewalInterval =
- ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
- LLDB_LOGF(log,
- "::SBSWatchdogAssertionGetRenewalInterval(%p) => "
- "%g seconds",
- watchdog.get(), watchdogRenewalInterval);
- if (watchdogRenewalInterval > 0.0) {
- watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
- if (watchdog_timeout > 3000) {
- // Give us a second to renew our timeout.
- watchdog_timeout -= 1000;
- } else if (watchdog_timeout > 1000) {
- // Give us a quarter of a second to renew our timeout.
- watchdog_timeout -= 250;
- }
- }
- }
- if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
- periodic_timeout = watchdog_timeout;
- }
-#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
-
-#ifdef WITH_BKS
- CFReleaser<BKSWatchdogAssertionRef> watchdog;
- if (process->ProcessUsingBackBoard()) {
- ::pid_t pid = process->GetID();
- CFAllocatorRef alloc = kCFAllocatorDefault;
- watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
- }
-#endif // #ifdef WITH_BKS
-
- // Do we want to use a weak pointer to the NativeProcessDarwin here, in which
- // case we can guarantee we don't whack the process monitor if we race
- // between this thread and the main one on shutdown?
- while (IsExceptionPortValid()) {
- ::pthread_testcancel();
-
- MachException::Message exception_message;
-
- if (num_exceptions_received > 0) {
- // We don't want a timeout here, just receive as many exceptions as we
- // can since we already have one. We want to get all currently available
- // exceptions for this task at once.
- error = exception_message.Receive(
- GetExceptionPort(),
- MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
- } else if (periodic_timeout > 0) {
- // We need to stop periodically in this loop, so try and get a mach
- // message with a valid timeout (ms).
- error = exception_message.Receive(GetExceptionPort(),
- MACH_RCV_MSG | MACH_RCV_INTERRUPT |
- MACH_RCV_TIMEOUT,
- periodic_timeout);
- } else {
- // We don't need to parse all current exceptions or stop periodically,
- // just wait for an exception forever.
- error = exception_message.Receive(GetExceptionPort(),
- MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
- }
-
- if (error.Success()) {
- // We successfully received an exception.
- if (exception_message.CatchExceptionRaise(task)) {
- ++num_exceptions_received;
- ExceptionMessageReceived(exception_message);
- }
- } else {
- if (error.GetError() == MACH_RCV_INTERRUPTED) {
- // We were interrupted.
-
- // If we have no task port we should exit this thread, as it implies
- // the inferior went down.
- if (!IsExceptionPortValid()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): the inferior "
- "exception port is no longer valid, "
- "canceling exception thread...",
- __FUNCTION__);
- // Should we be setting a process state here?
- break;
- }
-
- // Make sure the inferior task is still valid.
- if (IsTaskValid()) {
- // Task is still ok.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): interrupted, but "
- "the inferior task iss till valid, "
- "continuing...",
- __FUNCTION__);
- continue;
- } else {
- // The inferior task is no longer valid. Time to exit as the process
- // has gone away.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): the inferior task "
- "has exited, and so will we...",
- __FUNCTION__);
- // Does this race at all with our waitpid()?
- SetState(eStateExited);
- break;
- }
- } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
- // We timed out when waiting for exceptions.
-
- if (num_exceptions_received > 0) {
- // We were receiving all current exceptions with a timeout of zero.
- // It is time to go back to our normal looping mode.
- num_exceptions_received = 0;
-
- // Notify our main thread we have a complete exception message bundle
- // available. Get the possibly updated task port back from the
- // process in case we exec'ed and our task port changed.
- task = ExceptionMessageBundleComplete();
-
- // In case we use a timeout value when getting exceptions, make sure
- // our task is still valid.
- if (IsTaskValid(task)) {
- // Task is still ok.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): got a timeout, "
- "continuing...",
- __FUNCTION__);
- continue;
- } else {
- // The inferior task is no longer valid. Time to exit as the
- // process has gone away.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): the inferior "
- "task has exited, and so will we...",
- __FUNCTION__);
- // Does this race at all with our waitpid()?
- SetState(eStateExited);
- break;
- }
- }
-
-#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
- if (watchdog.get()) {
- watchdog_elapsed += periodic_timeout;
- if (watchdog_elapsed >= watchdog_timeout) {
- LLDB_LOGF(log, "SBSWatchdogAssertionRenew(%p)", watchdog.get());
- ::SBSWatchdogAssertionRenew(watchdog.get());
- watchdog_elapsed = 0;
- }
- }
-#endif
- } else {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): continuing after "
- "receiving an unexpected error: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
- // TODO: notify of error?
- }
- }
- }
-
-#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
- if (watchdog.get()) {
- // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
- // when we
- // all are up and running on systems that support it. The SBS framework has
- // a #define that will forward SBSWatchdogAssertionRelease to
- // SBSWatchdogAssertionCancel for now so it should still build either way.
- DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
- watchdog.get());
- ::SBSWatchdogAssertionRelease(watchdog.get());
- }
-#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
-
- LLDB_LOGF(log, "NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
- this);
- return nullptr;
-}
-
-Status NativeProcessDarwin::StartExceptionThread() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
-
- // Make sure we've looked up the inferior port.
- TaskPortForProcessID(error);
-
- // Ensure the inferior task is valid.
- if (!IsTaskValid()) {
- error.SetErrorStringWithFormat("cannot start exception thread: "
- "task 0x%4.4x is not valid",
- m_task);
- return error;
- }
-
- // Get the mach port for the process monitor.
- mach_port_t task_self = mach_task_self();
-
- // Allocate an exception port that we will use to track our child process
- auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
- &m_exception_port);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): mach_port_allocate("
- "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
- "&m_exception_port) failed: %u (%s)",
- __FUNCTION__, task_self, error.GetError(), error.AsCString());
- return error;
- }
-
- // Add the ability to send messages on the new exception port
- mach_err = ::mach_port_insert_right(
- task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): mach_port_insert_right("
- "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
- "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
- "failed: %u (%s)",
- __FUNCTION__, task_self, m_exception_port, m_exception_port,
- error.GetError(), error.AsCString());
- return error;
- }
-
- // Save the original state of the exception ports for our child process.
- error = SaveExceptionPortInfo();
- if (error.Fail() || (m_exc_port_info.mask == 0)) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
- "failed, cannot install exception handler: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Set the ability to get all exceptions on this port.
- mach_err = ::task_set_exception_ports(
- m_task, m_exc_port_info.mask, m_exception_port,
- EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "::task_set_exception_ports (task = 0x%4.4x, "
- "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
- "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
- "%u (%s)",
- m_task, m_exc_port_info.mask, m_exception_port,
- (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
- error.GetError(), error.AsCString());
- return error;
- }
-
- // Create the exception thread.
- auto pthread_err =
- ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
- error.SetError(pthread_err, eErrorTypePOSIX);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to create Mach "
- "exception-handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
- }
-
- return error;
-}
-
-lldb::addr_t
-NativeProcessDarwin::GetDYLDAllImageInfosAddress(Status &error) const {
- error.Clear();
-
- struct hack_task_dyld_info dyld_info;
- mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
- // Make sure that COUNT isn't bigger than our hacked up struct
- // hack_task_dyld_info. If it is, then make COUNT smaller to match.
- if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
- count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
- }
-
- TaskPortForProcessID(error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
-
- auto mach_err =
- ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Success()) {
- // We now have the address of the all image infos structure.
- return dyld_info.all_image_info_addr;
- }
-
- // We don't have it.
- return LLDB_INVALID_ADDRESS;
-}
-
-uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
- int mib[CTL_MAXNAME] = {
- 0,
- };
- size_t len = CTL_MAXNAME;
-
- if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
- return 0;
-
- mib[len] = pid;
- len++;
-
- cpu_type_t cpu;
- size_t cpu_len = sizeof(cpu);
- if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
- cpu = 0;
- return cpu;
-}
-
-uint32_t NativeProcessDarwin::GetCPUType() const {
- if (m_cpu_type == 0 && m_pid != 0)
- m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
- return m_cpu_type;
-}
-
-task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
- // We have a complete bundle of exceptions for our child process.
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): processing %lu exception "
- "messages.",
- __FUNCTION__, m_exception_messages.size());
-
- if (m_exception_messages.empty()) {
- // Not particularly useful...
- return m_task;
- }
-
- bool auto_resume = false;
- m_did_exec = false;
-
- // First check for any SIGTRAP and make sure we didn't exec
- const task_t task = m_task;
- size_t i;
- if (m_pid != 0) {
- bool received_interrupt = false;
- uint32_t num_task_exceptions = 0;
- for (i = 0; i < m_exception_messages.size(); ++i) {
- if (m_exception_messages[i].state.task_port != task) {
- // This is an exception that is not for our inferior, ignore.
- continue;
- }
-
- // This is an exception for the inferior.
- ++num_task_exceptions;
- const int signo = m_exception_messages[i].state.SoftSignal();
- if (signo == SIGTRAP) {
- // SIGTRAP could mean that we exec'ed. We need to check the
- // dyld all_image_infos.infoArray to see if it is NULL and if so, say
- // that we exec'ed.
- const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
- if (aii_addr == LLDB_INVALID_ADDRESS)
- break;
-
- const addr_t info_array_count_addr = aii_addr + 4;
- uint32_t info_array_count = 0;
- size_t bytes_read = 0;
- Status read_error;
- read_error = ReadMemory(info_array_count_addr, // source addr
- &info_array_count, // dest addr
- 4, // byte count
- bytes_read); // #bytes read
- if (read_error.Success() && (bytes_read == 4)) {
- if (info_array_count == 0) {
- // We got the all infos address, and there are zero entries. We
- // think we exec'd.
- m_did_exec = true;
-
- // Force the task port to update itself in case the task port
- // changed after exec
- const task_t old_task = m_task;
- const bool force_update = true;
- const task_t new_task = TaskPortForProcessID(error, force_update);
- if (old_task != new_task) {
- LLDB_LOGF(log,
- "exec: inferior task port changed "
- "from 0x%4.4x to 0x%4.4x",
- old_task, new_task);
- }
- }
- } else {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() warning: "
- "failed to read all_image_infos."
- "infoArrayCount from 0x%8.8llx",
- __FUNCTION__, info_array_count_addr);
- }
- } else if ((m_sent_interrupt_signo != 0) &&
- (signo == m_sent_interrupt_signo)) {
- // We just received the interrupt that we sent to ourselves.
- received_interrupt = true;
- }
- }
-
- if (m_did_exec) {
- cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
- if (m_cpu_type != process_cpu_type) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): arch changed from "
- "0x%8.8x to 0x%8.8x",
- __FUNCTION__, m_cpu_type, process_cpu_type);
- m_cpu_type = process_cpu_type;
- // TODO figure out if we need to do something here.
- // DNBArchProtocol::SetArchitecture (process_cpu_type);
- }
- m_thread_list.Clear();
-
- // TODO hook up breakpoints.
- // m_breakpoints.DisableAll();
- }
-
- if (m_sent_interrupt_signo != 0) {
- if (received_interrupt) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): process "
- "successfully interrupted with signal %i",
- __FUNCTION__, m_sent_interrupt_signo);
-
- // Mark that we received the interrupt signal
- m_sent_interrupt_signo = 0;
- // Now check if we had a case where:
- // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
- // for another reason.
- // 2 - We called NativeProcessDarwin::Resume() (but still
- // haven't gotten the interrupt signal).
- // 3 - We are now incorrectly stopped because we are handling
- // the interrupt signal we missed.
- // 4 - We might need to resume if we stopped only with the
- // interrupt signal that we never handled.
- if (m_auto_resume_signo != 0) {
- // Only auto_resume if we stopped with _only_ the interrupt signal.
- if (num_task_exceptions == 1) {
- auto_resume = true;
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): auto "
- "resuming due to unhandled interrupt "
- "signal %i",
- __FUNCTION__, m_auto_resume_signo);
- }
- m_auto_resume_signo = 0;
- }
- } else {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): didn't get signal "
- "%i after MachProcess::Interrupt()",
- __FUNCTION__, m_sent_interrupt_signo);
- }
- }
- }
-
- // Let all threads recover from stopping and do any clean up based on the
- // previous thread state (if any).
- m_thread_list.ProcessDidStop(*this);
-
- // Let each thread know of any exceptions
- for (i = 0; i < m_exception_messages.size(); ++i) {
- // Let the thread list forward all exceptions on down to each thread.
- if (m_exception_messages[i].state.task_port == task) {
- // This exception is for our inferior.
- m_thread_list.NotifyException(m_exception_messages[i].state);
- }
-
- if (log) {
- StreamString stream;
- m_exception_messages[i].Dump(stream);
- stream.Flush();
- log->PutCString(stream.GetString().c_str());
- }
- }
-
- if (log) {
- StreamString stream;
- m_thread_list.Dump(stream);
- stream.Flush();
- log->PutCString(stream.GetString().c_str());
- }
-
- bool step_more = false;
- if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
-// TODO - need to hook up event system here. !!!!
-#if 0
- // Wait for the eEventProcessRunningStateChanged event to be reset
- // before changing state to stopped to avoid race condition with very
- // fast start/stops.
- struct timespec timeout;
-
- //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms
- DNBTimer::OffsetTimeOfDay(&timeout, 1, 0); // Wait for 250 ms
- m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
- &timeout);
-#endif
- SetState(eStateStopped);
- } else {
- // Resume without checking our current state.
- PrivateResume();
- }
-
- return m_task;
-}
-
-void NativeProcessDarwin::StartSTDIOThread() {
- // TODO implement
-}
-
-Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Strategy: create a thread that sits on waitpid(), waiting for the inferior
- // process to die, reaping it in the process. Arrange for the thread to have
- // a pipe file descriptor that it can send a byte over when the waitpid
- // completes. Have the main loop have a read object for the other side of
- // the pipe, and have the callback for the read do the process termination
- // message sending.
-
- // Create a single-direction communication channel.
- const bool child_inherits = false;
- error = m_waitpid_pipe.CreateNew(child_inherits);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to create waitpid "
- "communication pipe: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Hook up the waitpid reader callback.
-
- // TODO make PipePOSIX derive from IOObject. This is goofy here.
- const bool transfer_ownership = false;
- auto io_sp = IOObjectSP(new NativeFile(m_waitpid_pipe.GetReadFileDescriptor(),
- transfer_ownership));
- m_waitpid_reader_handle = main_loop.RegisterReadObject(
- io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);
-
- // Create the thread.
- auto pthread_err =
- ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
- error.SetError(pthread_err, eErrorTypePOSIX);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to create waitpid "
- "handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
- return error;
- }
-
- return error;
-}
-
-void *NativeProcessDarwin::WaitpidThread(void *arg) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!arg) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): cannot run waitpid "
- "thread, mandatory process arg was null",
- __FUNCTION__);
- return nullptr;
- }
-
- return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
-}
-
-void NativeProcessDarwin::MaybeRaiseThreadPriority() {
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-}
-
-void *NativeProcessDarwin::DoWaitpidThread() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (m_pid == LLDB_INVALID_PROCESS_ID) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): inferior process ID is "
- "not set, cannot waitpid on it",
- __FUNCTION__);
- return nullptr;
- }
-
- // Name the thread.
- pthread_setname_np("waitpid thread");
-
- // Ensure we don't get CPU starved.
- MaybeRaiseThreadPriority();
-
- Status error;
- int status = -1;
-
- while (1) {
- // Do a waitpid.
- ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
- if (child_pid < 0)
- error.SetErrorToErrno();
- if (error.Fail()) {
- if (error.GetError() == EINTR) {
- // This is okay, we can keep going.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) interrupted, continuing",
- __FUNCTION__, m_pid);
- continue;
- }
-
- // This error is not okay, abort.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) aborting due to error: %u (%s)",
- __FUNCTION__, m_pid, error.GetError(), error.AsCString());
- break;
- }
-
- // Log the successful result.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) => %i, status = %i",
- __FUNCTION__, m_pid, child_pid, status);
-
- // Handle the result.
- if (WIFSTOPPED(status)) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ") received a stop, continuing waitpid() loop",
- __FUNCTION__, m_pid);
- continue;
- } else // if (WIFEXITED(status) || WIFSIGNALED(status))
- {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(pid = %" PRIu64 "): "
- "waitpid thread is setting exit status for pid = "
- "%i to %i",
- __FUNCTION__, m_pid, child_pid, status);
-
- error = SendInferiorExitStatusToMainLoop(child_pid, status);
- return nullptr;
- }
- }
-
- // We should never exit as long as our child process is alive. If we get
- // here, something completely unexpected went wrong and we should exit.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): internal error: waitpid thread "
- "exited out of its main loop in an unexpected way. pid = %" PRIu64
- ". Sending exit status of -1.",
- __FUNCTION__, m_pid);
-
- error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
- return nullptr;
-}
-
-Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
- int status) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- size_t bytes_written = 0;
-
- // Send the pid.
- error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
- if (error.Fail() || (bytes_written < sizeof(pid))) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() - failed to write "
- "waitpid exiting pid to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
- return error;
- }
-
- // Send the status.
- bytes_written = 0;
- error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
- if (error.Fail() || (bytes_written < sizeof(status))) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() - failed to write "
- "waitpid exit result to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
- }
- return error;
-}
-
-Status NativeProcessDarwin::HandleWaitpidResult() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Read the pid.
- const bool notify_status = true;
-
- ::pid_t pid = -1;
- size_t bytes_read = 0;
- error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
- if (error.Fail() || (bytes_read < sizeof(pid))) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() - failed to read "
- "waitpid exiting pid from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
- SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
- return error;
- }
-
- // Read the status.
- int status = -1;
- error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
- if (error.Fail() || (bytes_read < sizeof(status))) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s() - failed to read "
- "waitpid exit status from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
- SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
- return error;
- }
-
- // Notify the monitor that our state has changed.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): main loop received waitpid "
- "exit status info: pid=%i (%s), status=%i",
- __FUNCTION__, pid,
- (pid == m_pid) ? "the inferior" : "not the inferior", status);
-
- SetExitStatus(WaitStatus::Decode(status), notify_status);
- return error;
-}
-
-task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
- bool force) const {
- if ((m_task == TASK_NULL) || force) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (m_pid == LLDB_INVALID_PROCESS_ID) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): cannot get task due "
- "to invalid pid",
- __FUNCTION__);
- return TASK_NULL;
- }
-
- const uint32_t num_retries = 10;
- const uint32_t usec_interval = 10000;
-
- mach_port_t task_self = mach_task_self();
- task_t task = TASK_NULL;
-
- for (uint32_t i = 0; i < num_retries; i++) {
- kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
- if (err == 0) {
- // Succeeded. Save and return it.
- error.Clear();
- m_task = task;
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): ::task_for_pid("
- "stub_port = 0x%4.4x, pid = %llu, &task) "
- "succeeded: inferior task port = 0x%4.4x",
- __FUNCTION__, task_self, m_pid, m_task);
- return m_task;
- } else {
- // Failed to get the task for the inferior process.
- error.SetError(err, eErrorTypeMachKernel);
- if (log) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): ::task_for_pid("
- "stub_port = 0x%4.4x, pid = %llu, &task) "
- "failed, err = 0x%8.8x (%s)",
- __FUNCTION__, task_self, m_pid, err, error.AsCString());
- }
- }
-
- // Sleep a bit and try again
- ::usleep(usec_interval);
- }
-
- // We failed to get the task for the inferior process. Ensure that it is
- // cleared out.
- m_task = TASK_NULL;
- }
- return m_task;
-}
-
-void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
- Status &error) {
- error.SetErrorString("TODO: implement");
-}
-
-Status NativeProcessDarwin::PrivateResume() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- m_auto_resume_signo = m_sent_interrupt_signo;
-
- if (log) {
- if (m_auto_resume_signo)
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): task 0x%x resuming (with "
- "unhandled interrupt signal %i)...",
- __FUNCTION__, m_task, m_auto_resume_signo);
- else
- LLDB_LOGF(log, "NativeProcessDarwin::%s(): task 0x%x resuming...",
- __FUNCTION__, m_task);
- }
-
- error = ReplyToAllExceptions();
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): aborting, failed to "
- "reply to exceptions: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- // bool stepOverBreakInstruction = step;
-
- // Let the thread prepare to resume and see if any threads want us to step
- // over a breakpoint instruction (ProcessWillResume will modify the value of
- // stepOverBreakInstruction).
- m_thread_list.ProcessWillResume(*this, m_thread_actions);
-
- // Set our state accordingly
- if (m_thread_actions.NumActionsWithState(eStateStepping))
- SetState(eStateStepping);
- else
- SetState(eStateRunning);
-
- // Now resume our task.
- error = ResumeTask();
- return error;
-}
-
-Status NativeProcessDarwin::ReplyToAllExceptions() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
-
- TaskPortForProcessID(error);
- if (error.Fail()) {
- LLDB_LOGF(log, "NativeProcessDarwin::%s(): no task port, aborting",
- __FUNCTION__);
- return error;
- }
-
- std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- if (m_exception_messages.empty()) {
- // We're done.
- return error;
- }
-
- size_t index = 0;
- for (auto &message : m_exception_messages) {
- if (log) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): replying to exception "
- "%zu...",
- __FUNCTION__, index++);
- }
-
- int thread_reply_signal = 0;
-
- const tid_t tid =
- m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
- const ResumeAction *action = nullptr;
- if (tid != LLDB_INVALID_THREAD_ID)
- action = m_thread_actions.GetActionForThread(tid, false);
-
- if (action) {
- thread_reply_signal = action->signal;
- if (thread_reply_signal)
- m_thread_actions.SetSignalHandledForThread(tid);
- }
-
- error = message.Reply(m_pid, m_task, thread_reply_signal);
- if (error.Fail() && log) {
- // We log any error here, but we don't stop the exception response
- // handling.
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to reply to "
- "exception: %s",
- __FUNCTION__, error.AsCString());
- error.Clear();
- }
- }
-
- // Erase all exception message as we should have used and replied to them all
- // already.
- m_exception_messages.clear();
- return error;
-}
-
-Status NativeProcessDarwin::ResumeTask() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- TaskPortForProcessID(error);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to get task port "
- "for process when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- if (m_task == TASK_NULL) {
- error.SetErrorString("task port retrieval succeeded but task port is "
- "null when attempting to resume the task");
- return error;
- }
-
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): requesting resume of task "
- "0x%4.4x",
- __FUNCTION__, m_task);
-
- // Get the BasicInfo struct to verify that we're suspended before we try to
- // resume the task.
- struct task_basic_info task_info;
- error = GetTaskBasicInfo(m_task, &task_info);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): failed to get task "
- "BasicInfo when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // task_resume isn't counted like task_suspend calls are, so if the task is
- // not suspended, don't try and resume it since it is already running
- if (task_info.suspend_count > 0) {
- auto mach_err = ::task_resume(m_task);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (log) {
- if (error.Success())
- LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x): success", m_task);
- else
- LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x) error: %s", m_task,
- error.AsCString());
- }
- } else {
- LLDB_LOGF(log,
- "::task_resume(target_task = 0x%4.4x): ignored, "
- "already running",
- m_task);
- }
-
- return error;
-}
-
-bool NativeProcessDarwin::IsTaskValid() const {
- if (m_task == TASK_NULL)
- return false;
-
- struct task_basic_info task_info;
- return GetTaskBasicInfo(m_task, &task_info).Success();
-}
-
-bool NativeProcessDarwin::IsTaskValid(task_t task) const {
- if (task == TASK_NULL)
- return false;
-
- struct task_basic_info task_info;
- return GetTaskBasicInfo(task, &task_info).Success();
-}
-
-mach_port_t NativeProcessDarwin::GetExceptionPort() const {
- return m_exception_port;
-}
-
-bool NativeProcessDarwin::IsExceptionPortValid() const {
- return MACH_PORT_VALID(m_exception_port);
-}
-
-Status
-NativeProcessDarwin::GetTaskBasicInfo(task_t task,
- struct task_basic_info *info) const {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Validate args.
- if (info == NULL) {
- error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
- "info arg is null",
- __FUNCTION__);
- return error;
- }
-
- // Grab the task if we don't already have it.
- if (task == TASK_NULL) {
- error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
- "is invalid",
- __FUNCTION__);
- }
-
- mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
- auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
- error.SetError(err, eErrorTypeMachKernel);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "::task_info(target_task = 0x%4.4x, "
- "flavor = TASK_BASIC_INFO, task_info_out => %p, "
- "task_info_outCnt => %u) failed: %u (%s)",
- m_task, info, count, error.GetError(), error.AsCString());
- return error;
- }
-
- Log *verbose_log(
- GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (verbose_log) {
- float user = (float)info->user_time.seconds +
- (float)info->user_time.microseconds / 1000000.0f;
- float system = (float)info->user_time.seconds +
- (float)info->user_time.microseconds / 1000000.0f;
- verbose_LLDB_LOGF(log,
- "task_basic_info = { suspend_count = %i, "
- "virtual_size = 0x%8.8llx, resident_size = "
- "0x%8.8llx, user_time = %f, system_time = %f }",
- info->suspend_count, (uint64_t)info->virtual_size,
- (uint64_t)info->resident_size, user, system);
- }
- return error;
-}
-
-Status NativeProcessDarwin::SuspendTask() {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (m_task == TASK_NULL) {
- error.SetErrorString("task port is null, cannot suspend task");
- LLDB_LOGF(log, "NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
- error.AsCString());
- return error;
- }
-
- auto mach_err = ::task_suspend(m_task);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Fail() && log)
- LLDB_LOGF(log, "::task_suspend(target_task = 0x%4.4x)", m_task);
-
- return error;
-}
-
-Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
- Status error;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
-
- if (CanResume()) {
- m_thread_actions = resume_actions;
- error = PrivateResume();
- return error;
- }
-
- auto state = GetState();
- if (state == eStateRunning) {
- LLDB_LOGF(log,
- "NativeProcessDarwin::%s(): task 0x%x is already "
- "running, ignoring...",
- __FUNCTION__, TaskPortForProcessID(error));
- return error;
- }
-
- // We can't resume from this state.
- error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
- TaskPortForProcessID(error),
- StateAsCString(state));
- return error;
-}
-
-Status NativeProcessDarwin::Halt() {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::Detach() {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::Signal(int signo) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::Interrupt() {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::Kill() {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf,
- size_t size, size_t &bytes_read) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
- size_t size,
- size_t &bytes_read) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
- size_t size, size_t &bytes_written) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
- return LLDB_INVALID_ADDRESS;
-}
-
-size_t NativeProcessDarwin::UpdateThreads() { return 0; }
-
-bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
- return false;
-}
-
-Status NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}
-
-Status NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-Status NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
-
-// NativeProcessProtocol protected interface
-Status NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
- size_t trap_opcode_size_hint, size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) {
- Status error;
- error.SetErrorString("TODO: implement");
- return error;
-}
diff --git a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h
deleted file mode 100644
index 6741d4ddc5d8..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h
+++ /dev/null
@@ -1,337 +0,0 @@
-//===-- NativeProcessDarwin.h --------------------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef NativeProcessDarwin_h
-#define NativeProcessDarwin_h
-
-// NOTE: this code should only be compiled on Apple Darwin systems. It is
-// not cross-platform code and is not intended to build on any other platform.
-// Therefore, platform-specific headers and code are okay here.
-
-// C includes
-#include <mach/mach_types.h>
-
-// C++ includes
-#include <mutex>
-#include <unordered_set>
-
-#include "lldb/Host/Debug.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Pipe.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-types.h"
-
-#include "LaunchFlavor.h"
-#include "MachException.h"
-#include "NativeThreadDarwin.h"
-#include "NativeThreadListDarwin.h"
-
-namespace lldb_private {
-class Status;
-class Scalar;
-
-namespace process_darwin {
-
-/// \class NativeProcessDarwin
-/// Manages communication with the inferior (debugee) process.
-///
-/// Upon construction, this class prepares and launches an inferior process
-/// for debugging.
-///
-/// Changes in the inferior process state are broadcasted.
-class NativeProcessDarwin : public NativeProcessProtocol {
- friend Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
- friend Status NativeProcessProtocol::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
-public:
- ~NativeProcessDarwin() override;
-
- // NativeProcessProtocol Interface
- Status Resume(const ResumeActionList &resume_actions) override;
-
- Status Halt() override;
-
- Status Detach() override;
-
- Status Signal(int signo) override;
-
- Status Interrupt() override;
-
- Status Kill() override;
-
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
- Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
- Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
- Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
- size_t &bytes_written) override;
-
- Status AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) override;
-
- Status DeallocateMemory(lldb::addr_t addr) override;
-
- lldb::addr_t GetSharedLibraryInfoAddress() override;
-
- size_t UpdateThreads() override;
-
- bool GetArchitecture(ArchSpec &arch) const override;
-
- Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) override;
-
- void DoStopIDBumped(uint32_t newBumpId) override;
-
- Status GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) override;
-
- Status GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) override;
-
- NativeThreadDarwinSP GetThreadByID(lldb::tid_t id);
-
- task_t GetTask() const { return m_task; }
-
- // Interface used by NativeRegisterContext-derived classes.
- static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
- void *data = nullptr, size_t data_size = 0,
- long *result = nullptr);
-
- bool SupportHardwareSingleStepping() const;
-
-protected:
- // NativeProcessProtocol protected interface
- Status
- GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
- size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) override;
-
-private:
- /// Mach task-related Member Variables
-
- // The task port for the inferior process.
- mutable task_t m_task;
-
- // True if the inferior process did an exec since we started
- // monitoring it.
- bool m_did_exec;
-
- // The CPU type of this process.
- mutable cpu_type_t m_cpu_type;
-
- /// Exception/Signal Handling Member Variables
-
- // Exception port on which we will receive child exceptions
- mach_port_t m_exception_port;
-
- // Saved state of the child exception port prior to us installing
- // our own intercepting port.
- MachException::PortInfo m_exc_port_info;
-
- // The thread that runs the Mach exception read and reply handler.
- pthread_t m_exception_thread;
-
- // TODO see if we can remove this if we get the exception collection
- // and distribution to happen in a single-threaded fashion.
- std::recursive_mutex m_exception_messages_mutex;
-
- // A collection of exception messages caught when listening to the
- // exception port.
- MachException::Message::collection m_exception_messages;
-
- // When we call MachProcess::Interrupt(), we want to send this
- // signal (if non-zero).
- int m_sent_interrupt_signo;
-
- // If we resume the process and still haven't received our
- // interrupt signal (if this is non-zero).
- int m_auto_resume_signo;
-
- /// Thread-related Member Variables
- NativeThreadListDarwin m_thread_list;
- ResumeActionList m_thread_actions;
-
- /// Process Lifetime Member Variable
-
- // The pipe over which the waitpid thread and the main loop will
- // communicate.
- Pipe m_waitpid_pipe;
-
- // The thread that runs the waitpid handler.
- pthread_t m_waitpid_thread;
-
- // waitpid reader callback handle.
- MainLoop::ReadHandleUP m_waitpid_reader_handle;
-
- // Private Instance Methods
- NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd);
-
- /// Finalize the launch.
- ///
- /// This method associates the NativeProcessDarwin instance with the host
- /// process that was just launched. It peforms actions like attaching a
- /// listener to the inferior exception port, ptracing the process, and the
- /// like.
- ///
- /// \param[in] launch_flavor
- /// The launch flavor that was used to launch the process.
- ///
- /// \param[in] main_loop
- /// The main loop that will run the process monitor. Work
- /// that needs to be done (e.g. reading files) gets registered
- /// here along with callbacks to process the work.
- ///
- /// \return
- /// Any error that occurred during the aforementioned
- /// operations. Failure here will force termination of the
- /// launched process and debugging session.
- Status FinalizeLaunch(LaunchFlavor launch_flavor, MainLoop &main_loop);
-
- Status SaveExceptionPortInfo();
-
- void ExceptionMessageReceived(const MachException::Message &message);
-
- void MaybeRaiseThreadPriority();
-
- Status StartExceptionThread();
-
- Status SendInferiorExitStatusToMainLoop(::pid_t pid, int status);
-
- Status HandleWaitpidResult();
-
- bool ProcessUsingSpringBoard() const;
-
- bool ProcessUsingBackBoard() const;
-
- static void *ExceptionThread(void *arg);
-
- void *DoExceptionThread();
-
- lldb::addr_t GetDYLDAllImageInfosAddress(Status &error) const;
-
- static uint32_t GetCPUTypeForLocalProcess(::pid_t pid);
-
- uint32_t GetCPUType() const;
-
- task_t ExceptionMessageBundleComplete();
-
- void StartSTDIOThread();
-
- Status StartWaitpidThread(MainLoop &main_loop);
-
- static void *WaitpidThread(void *arg);
-
- void *DoWaitpidThread();
-
- task_t TaskPortForProcessID(Status &error, bool force = false) const;
-
- /// Attaches to an existing process. Forms the implementation of
- /// Process::DoAttach.
- void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
-
- ::pid_t Attach(lldb::pid_t pid, Status &error);
-
- Status PrivateResume();
-
- Status ReplyToAllExceptions();
-
- Status ResumeTask();
-
- bool IsTaskValid() const;
-
- bool IsTaskValid(task_t task) const;
-
- mach_port_t GetExceptionPort() const;
-
- bool IsExceptionPortValid() const;
-
- Status GetTaskBasicInfo(task_t task, struct task_basic_info *info) const;
-
- Status SuspendTask();
-
- static Status SetDefaultPtraceOpts(const lldb::pid_t);
-
- static void *MonitorThread(void *baton);
-
- void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
-
- void WaitForNewThread(::pid_t tid);
-
- void MonitorSIGTRAP(const siginfo_t &info, NativeThreadDarwin &thread);
-
- void MonitorTrace(NativeThreadDarwin &thread);
-
- void MonitorBreakpoint(NativeThreadDarwin &thread);
-
- void MonitorWatchpoint(NativeThreadDarwin &thread, uint32_t wp_index);
-
- void MonitorSignal(const siginfo_t &info, NativeThreadDarwin &thread,
- bool exited);
-
- Status SetupSoftwareSingleStepping(NativeThreadDarwin &thread);
-
- bool HasThreadNoLock(lldb::tid_t thread_id);
-
- bool StopTrackingThread(lldb::tid_t thread_id);
-
- NativeThreadDarwinSP AddThread(lldb::tid_t thread_id);
-
- Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
-
- Status FixupBreakpointPCAsNeeded(NativeThreadDarwin &thread);
-
- /// Writes a siginfo_t structure corresponding to the given thread
- /// ID to the memory region pointed to by \p siginfo.
- Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
-
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread ID to the memory pointed to by @p
- /// message.
- Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- void NotifyThreadDeath(lldb::tid_t tid);
-
- Status Detach(lldb::tid_t tid);
-
- // This method is requests a stop on all threads which are still
- // running. It sets up a deferred delegate notification, which will
- // fire once threads report as stopped. The triggerring_tid will be
- // set as the current thread (main stop reason).
- void StopRunningThreads(lldb::tid_t triggering_tid);
-
- // Notify the delegate if all threads have stopped.
- void SignalIfAllThreadsStopped();
-
- // Resume the given thread, optionally passing it the given signal.
- // The type of resume operation (continue, single-step) depends on
- // the state parameter.
- Status ResumeThread(NativeThreadDarwin &thread, lldb::StateType state,
- int signo);
-
- void ThreadWasCreated(NativeThreadDarwin &thread);
-
- void SigchldHandler();
-};
-
-} // namespace process_darwin
-} // namespace lldb_private
-
-#endif /* NativeProcessDarwin_h */
diff --git a/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp b/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
deleted file mode 100644
index bcd6d8c2c4c1..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-//===-- NativeThreadDarwin.cpp -------------------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeThreadDarwin.h"
-
-// C includes
-#include <libproc.h>
-
-// LLDB includes
-#include "lldb/Utility/Stream.h"
-
-#include "NativeProcessDarwin.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_darwin;
-
-uint64_t NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
- ::thread_t mach_port_id) {
- thread_identifier_info_data_t tident;
- mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
-
- auto mach_err = ::thread_info(mach_port_id, THREAD_IDENTIFIER_INFO,
- (thread_info_t)&tident, &tident_count);
- if (mach_err != KERN_SUCCESS) {
- // When we fail to get thread info for the supposed port, assume it is
- // really a globally unique thread id already, or return the best thing we
- // can, which is the thread port.
- return mach_port_id;
- }
- return tident.thread_id;
-}
-
-NativeThreadDarwin::NativeThreadDarwin(NativeProcessDarwin *process,
- bool is_64_bit,
- lldb::tid_t unique_thread_id,
- ::thread_t mach_thread_port)
- : NativeThreadProtocol(process, unique_thread_id),
- m_mach_thread_port(mach_thread_port), m_basic_info(),
- m_proc_threadinfo() {}
-
-bool NativeThreadDarwin::GetIdentifierInfo() {
- // Don't try to get the thread info once and cache it for the life of the
- // thread. It changes over time, for instance if the thread name changes,
- // then the thread_handle also changes... So you have to refetch it every
- // time.
- mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- kern_return_t kret = ::thread_info(m_mach_thread_port, THREAD_IDENTIFIER_INFO,
- (thread_info_t)&m_ident_info, &count);
- return kret == KERN_SUCCESS;
-
- return false;
-}
-
-std::string NativeThreadDarwin::GetName() {
- std::string name;
-
- if (GetIdentifierInfo()) {
- auto process_sp = GetProcess();
- if (!process_sp) {
- name = "<unavailable>";
- return name;
- }
-
- int len = ::proc_pidinfo(process_sp->GetID(), PROC_PIDTHREADINFO,
- m_ident_info.thread_handle, &m_proc_threadinfo,
- sizeof(m_proc_threadinfo));
-
- if (len && m_proc_threadinfo.pth_name[0])
- name = m_proc_threadinfo.pth_name;
- }
- return name;
-}
-
-lldb::StateType NativeThreadDarwin::GetState() {
- // TODO implement
- return eStateInvalid;
-}
-
-bool NativeThreadDarwin::GetStopReason(ThreadStopInfo &stop_info,
- std::string &description) {
- // TODO implement
- return false;
-}
-
-NativeRegisterContextSP NativeThreadDarwin::GetRegisterContext() {
- // TODO implement
- return NativeRegisterContextSP();
-}
-
-Status NativeThreadDarwin::SetWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags, bool hardware) {
- Status error;
- error.SetErrorString("not yet implemented");
- return error;
-}
-
-Status NativeThreadDarwin::RemoveWatchpoint(lldb::addr_t addr) {
- Status error;
- error.SetErrorString("not yet implemented");
- return error;
-}
-
-void NativeThreadDarwin::Dump(Stream &stream) const {
-// This is what we really want once we have the thread class wired up.
-#if 0
- DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
- index,
- m_seq_id,
- m_unique_id,
- GetPC(INVALID_NUB_ADDRESS),
- GetSP(INVALID_NUB_ADDRESS),
- m_basic_info.user_time.seconds, m_basic_info.user_time.microseconds,
- m_basic_info.system_time.seconds, m_basic_info.system_time.microseconds,
- m_basic_info.cpu_usage,
- m_basic_info.policy,
- m_basic_info.run_state,
- thread_run_state,
- m_basic_info.flags,
- m_basic_info.suspend_count, m_suspend_count,
- m_basic_info.sleep_time);
-
-#else
- // Here's all we have right now.
- stream.Printf("tid: 0x%8.8" PRIx64 ", thread port: 0x%4.4x", GetID(),
- m_mach_thread_port);
-#endif
-}
-
-bool NativeThreadDarwin::NotifyException(MachException::Data &exc) {
-// TODO implement this.
-#if 0
- // Allow the arch specific protocol to process (MachException::Data &)exc
- // first before possible reassignment of m_stop_exception with exc. See
- // also MachThread::GetStopException().
- bool handled = m_arch_up->NotifyException(exc);
-
- if (m_stop_exception.IsValid())
- {
- // We may have more than one exception for a thread, but we need to
- // only remember the one that we will say is the reason we stopped. We
- // may have been single stepping and also gotten a signal exception, so
- // just remember the most pertinent one.
- if (m_stop_exception.IsBreakpoint())
- m_stop_exception = exc;
- }
- else
- {
- m_stop_exception = exc;
- }
-
- return handled;
-#else
- // Pretend we handled it.
- return true;
-#endif
-}
-
-bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
-// TODO: implement this
-#if 0
- // See if this thread is at a breakpoint?
- DNBBreakpoint *bp = CurrentBreakpoint();
-
- if (bp)
- {
- // This thread is sitting at a breakpoint, ask the breakpoint if we
- // should be stopping here.
- return true;
- }
- else
- {
- if (m_arch_up->StepNotComplete())
- {
- step_more = true;
- return false;
- }
- // The thread state is used to let us know what the thread was trying
- // to do. MachThread::ThreadWillResume() will set the thread state to
- // various values depending if the thread was the current thread and if
- // it was to be single stepped, or resumed.
- if (GetState() == eStateRunning)
- {
- // If our state is running, then we should continue as we are in
- // the process of stepping over a breakpoint.
- return false;
- }
- else
- {
- // Stop if we have any kind of valid exception for this thread.
- if (GetStopException().IsValid())
- return true;
- }
- }
- return false;
-#else
- return false;
-#endif
-}
-
-void NativeThreadDarwin::ThreadDidStop() {
-// TODO implement this.
-#if 0
- // This thread has existed prior to resuming under debug nub control, and
- // has just been stopped. Do any cleanup that needs to be done after
- // running.
-
- // The thread state and breakpoint will still have the same values as they
- // had prior to resuming the thread, so it makes it easy to check if we
- // were trying to step a thread, or we tried to resume while being at a
- // breakpoint.
-
- // When this method gets called, the process state is still in the state it
- // was in while running so we can act accordingly.
- m_arch_up->ThreadDidStop();
-
-
- // We may have suspended this thread so the primary thread could step
- // without worrying about race conditions, so lets restore our suspend
- // count.
- RestoreSuspendCountAfterStop();
-
- // Update the basic information for a thread
- MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
-
- if (m_basic_info.suspend_count > 0)
- SetState(eStateSuspended);
- else
- SetState(eStateStopped);
-#endif
-}
-
-bool NativeThreadDarwin::MachPortNumberIsValid(::thread_t thread) {
- return thread != (::thread_t)(0);
-}
-
-const struct thread_basic_info *NativeThreadDarwin::GetBasicInfo() const {
- if (GetBasicInfo(m_mach_thread_port, &m_basic_info))
- return &m_basic_info;
- return NULL;
-}
-
-bool NativeThreadDarwin::GetBasicInfo(::thread_t thread,
- struct thread_basic_info *basicInfoPtr) {
- if (MachPortNumberIsValid(thread)) {
- unsigned int info_count = THREAD_BASIC_INFO_COUNT;
- kern_return_t err = ::thread_info(thread, THREAD_BASIC_INFO,
- (thread_info_t)basicInfoPtr, &info_count);
- if (err == KERN_SUCCESS)
- return true;
- }
- ::memset(basicInfoPtr, 0, sizeof(struct thread_basic_info));
- return false;
-}
-
-bool NativeThreadDarwin::IsUserReady() const {
- if (m_basic_info.run_state == 0)
- GetBasicInfo();
-
- switch (m_basic_info.run_state) {
- default:
- case TH_STATE_UNINTERRUPTIBLE:
- break;
-
- case TH_STATE_RUNNING:
- case TH_STATE_STOPPED:
- case TH_STATE_WAITING:
- case TH_STATE_HALTED:
- return true;
- }
- return false;
-}
-
-NativeProcessDarwinSP NativeThreadDarwin::GetNativeProcessDarwinSP() {
- return std::static_pointer_cast<NativeProcessDarwin>(GetProcess());
-}
diff --git a/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.h b/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.h
deleted file mode 100644
index 616a9a7b9bf0..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeThreadDarwin.h
+++ /dev/null
@@ -1,165 +0,0 @@
-//===-- NativeThreadDarwin.h ---------------------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef NativeThreadDarwin_H
-#define NativeThreadDarwin_H
-
-// C includes
-#include <mach/mach_types.h>
-#include <sched.h>
-#include <sys/proc_info.h>
-
-// C++ includes
-#include <map>
-#include <memory>
-#include <string>
-
-// LLDB includes
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/lldb-private-forward.h"
-
-#include "MachException.h"
-
-namespace lldb_private {
-namespace process_darwin {
-
-class NativeProcessDarwin;
-using NativeProcessDarwinSP = std::shared_ptr<NativeProcessDarwin>;
-
-class NativeThreadListDarwin;
-
-class NativeThreadDarwin : public NativeThreadProtocol {
- friend class NativeProcessDarwin;
- friend class NativeThreadListDarwin;
-
-public:
- static uint64_t
- GetGloballyUniqueThreadIDForMachPortID(::thread_t mach_port_id);
-
- NativeThreadDarwin(NativeProcessDarwin *process, bool is_64_bit,
- lldb::tid_t unique_thread_id = 0,
- ::thread_t mach_thread_port = 0);
-
- // NativeThreadProtocol Interface
- std::string GetName() override;
-
- lldb::StateType GetState() override;
-
- bool GetStopReason(ThreadStopInfo &stop_info,
- std::string &description) override;
-
- NativeRegisterContextSP GetRegisterContext() override;
-
- Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
- bool hardware) override;
-
- Status RemoveWatchpoint(lldb::addr_t addr) override;
-
- // New methods that are fine for others to call.
- void Dump(Stream &stream) const;
-
-private:
- // Interface for friend classes
-
- /// Resumes the thread. If \p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status Resume(uint32_t signo);
-
- /// Single steps the thread. If \p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status SingleStep(uint32_t signo);
-
- bool NotifyException(MachException::Data &exc);
-
- bool ShouldStop(bool &step_more) const;
-
- void ThreadDidStop();
-
- void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
-
- /// Return true if the thread is stopped.
- /// If stopped by a signal, indicate the signo in the signo
- /// argument. Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
- bool IsStopped(int *signo);
-
- const struct thread_basic_info *GetBasicInfo() const;
-
- static bool GetBasicInfo(::thread_t thread,
- struct thread_basic_info *basicInfoPtr);
-
- bool IsUserReady() const;
-
- void SetStoppedByExec();
-
- void SetStoppedByBreakpoint();
-
- void SetStoppedByWatchpoint(uint32_t wp_index);
-
- bool IsStoppedAtBreakpoint();
-
- bool IsStoppedAtWatchpoint();
-
- void SetStoppedByTrace();
-
- void SetStoppedWithNoReason();
-
- void SetExited();
-
- Status RequestStop();
-
- /// Return the mach thread port number for this thread.
- ///
- /// \return
- /// The mach port number for this thread. Returns NULL_THREAD
- /// when the thread is invalid.
- thread_t GetMachPortNumber() const { return m_mach_thread_port; }
-
- static bool MachPortNumberIsValid(::thread_t thread);
-
- // Private interface
- bool GetIdentifierInfo();
-
- void MaybeLogStateChange(lldb::StateType new_state);
-
- NativeProcessDarwinSP GetNativeProcessDarwinSP();
-
- void SetStopped();
-
- inline void MaybePrepareSingleStepWorkaround();
-
- inline void MaybeCleanupSingleStepWorkaround();
-
- // Member Variables
-
- // The mach thread port for the thread.
- ::thread_t m_mach_thread_port;
-
- // The most recently-retrieved thread basic info.
- mutable ::thread_basic_info m_basic_info;
-
- struct proc_threadinfo m_proc_threadinfo;
-
- thread_identifier_info_data_t m_ident_info;
-
-#if 0
- lldb::StateType m_state;
- ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
- std::string m_stop_description;
- using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
- WatchpointIndexMap m_watchpoint_index_map;
- // cpu_set_t m_original_cpu_set; // For single-step workaround.
-#endif
-};
-
-typedef std::shared_ptr<NativeThreadDarwin> NativeThreadDarwinSP;
-
-} // namespace process_darwin
-} // namespace lldb_private
-
-#endif // #ifndef NativeThreadDarwin_H
diff --git a/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
deleted file mode 100644
index 1faa5b219cbc..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
+++ /dev/null
@@ -1,702 +0,0 @@
-//===-- NativeThreadListDarwin.cpp ------------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 6/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeThreadListDarwin.h"
-
-// C includes
-#include <inttypes.h>
-#include <mach/vm_map.h>
-#include <sys/sysctl.h>
-
-// LLDB includes
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Stream.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "NativeProcessDarwin.h"
-#include "NativeThreadDarwin.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_darwin;
-
-NativeThreadListDarwin::NativeThreadListDarwin()
- : m_threads(), m_threads_mutex(), m_is_64_bit(false) {}
-
-NativeThreadListDarwin::~NativeThreadListDarwin() {}
-
-// These methods will be accessed directly from NativeThreadDarwin
-#if 0
-nub_state_t
-NativeThreadListDarwin::GetState(nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetState();
- return eStateInvalid;
-}
-
-const char *
-NativeThreadListDarwin::GetName (nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetName();
- return NULL;
-}
-#endif
-
-// TODO: figure out if we need to add this to NativeThreadDarwin yet.
-#if 0
-ThreadInfo::QoS
-NativeThreadListDarwin::GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetRequestedQoS(tsd, dti_qos_class_index);
- return ThreadInfo::QoS();
-}
-
-nub_addr_t
-NativeThreadListDarwin::GetPThreadT (nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetPThreadT();
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t
-NativeThreadListDarwin::GetDispatchQueueT (nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetDispatchQueueT();
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t
-NativeThreadListDarwin::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetTSDAddressForThread(plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
- return INVALID_NUB_ADDRESS;
-}
-#endif
-
-// TODO implement these
-#if 0
-nub_thread_t
-NativeThreadListDarwin::SetCurrentThread(nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- {
- m_current_thread = thread_sp;
- return tid;
- }
- return INVALID_NUB_THREAD;
-}
-
-
-bool
-NativeThreadListDarwin::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetStopException().GetStopInfo(stop_info);
- return false;
-}
-
-bool
-NativeThreadListDarwin::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
-{
- thread_t mach_port_number = GetMachPortNumberByThreadID (tid);
-
- mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
-}
-
-void
-NativeThreadListDarwin::DumpThreadStoppedReason (nub_thread_t tid) const
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- thread_sp->GetStopException().DumpStopReason();
-}
-
-const char *
-NativeThreadListDarwin::GetThreadInfo (nub_thread_t tid) const
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetBasicInfoAsString();
- return NULL;
-}
-
-#endif
-
-NativeThreadDarwinSP
-NativeThreadListDarwin::GetThreadByID(lldb::tid_t tid) const {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- if (thread_sp && (thread_sp->GetID() == tid))
- return thread_sp;
- }
- return NativeThreadDarwinSP();
-}
-
-NativeThreadDarwinSP NativeThreadListDarwin::GetThreadByMachPortNumber(
- ::thread_t mach_port_number) const {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
- return thread_sp;
- }
- return NativeThreadDarwinSP();
-}
-
-lldb::tid_t NativeThreadListDarwin::GetThreadIDByMachPortNumber(
- ::thread_t mach_port_number) const {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
- return thread_sp->GetID();
- }
- return LLDB_INVALID_THREAD_ID;
-}
-
-// TODO implement
-#if 0
-thread_t
-NativeThreadListDarwin::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
-{
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- MachThreadSP thread_sp;
- const size_t num_threads = m_threads.size();
- for (size_t idx = 0; idx < num_threads; ++idx)
- {
- if (m_threads[idx]->ThreadID() == globally_unique_id)
- {
- return m_threads[idx]->MachPortNumber();
- }
- }
- return 0;
-}
-
-bool
-NativeThreadListDarwin::GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value ) const
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetRegisterValue(set, reg, reg_value);
-
- return false;
-}
-
-bool
-NativeThreadListDarwin::SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value ) const
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->SetRegisterValue(set, reg, reg_value);
-
- return false;
-}
-
-nub_size_t
-NativeThreadListDarwin::GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->GetRegisterContext (buf, buf_len);
- return 0;
-}
-
-nub_size_t
-NativeThreadListDarwin::SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->SetRegisterContext (buf, buf_len);
- return 0;
-}
-
-uint32_t
-NativeThreadListDarwin::SaveRegisterState (nub_thread_t tid)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->SaveRegisterState ();
- return 0;
-}
-
-bool
-NativeThreadListDarwin::RestoreRegisterState (nub_thread_t tid, uint32_t save_id)
-{
- MachThreadSP thread_sp (GetThreadByID (tid));
- if (thread_sp)
- return thread_sp->RestoreRegisterState (save_id);
- return 0;
-}
-#endif
-
-size_t NativeThreadListDarwin::GetNumberOfThreads() const {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- return static_cast<size_t>(m_threads.size());
-}
-
-// TODO implement
-#if 0
-nub_thread_t
-NativeThreadListDarwin::ThreadIDAtIndex (nub_size_t idx) const
-{
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- if (idx < m_threads.size())
- return m_threads[idx]->ThreadID();
- return INVALID_NUB_THREAD;
-}
-
-nub_thread_t
-NativeThreadListDarwin::CurrentThreadID ( )
-{
- MachThreadSP thread_sp;
- CurrentThread(thread_sp);
- if (thread_sp.get())
- return thread_sp->ThreadID();
- return INVALID_NUB_THREAD;
-}
-
-#endif
-
-bool NativeThreadListDarwin::NotifyException(MachException::Data &exc) {
- auto thread_sp = GetThreadByMachPortNumber(exc.thread_port);
- if (thread_sp) {
- thread_sp->NotifyException(exc);
- return true;
- }
- return false;
-}
-
-void NativeThreadListDarwin::Clear() {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- m_threads.clear();
-}
-
-uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
- bool update,
- collection *new_threads) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- LLDB_LOGF(log,
- "NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
- "%u) process stop count = %u",
- __FUNCTION__, process.GetID(), update, process.GetStopID());
-
- if (process.GetStopID() == 0) {
- // On our first stop, we'll record details like 32/64 bitness and select
- // the proper architecture implementation.
- //
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process.GetID()};
-
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if ((sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo,
- &bufsize, NULL, 0) == 0) &&
- (bufsize > 0)) {
- if (processInfo.kp_proc.p_flag & P_LP64)
- m_is_64_bit = true;
- }
-
-// TODO implement architecture selection and abstraction.
-#if 0
-#if defined(__i386__) || defined(__x86_64__)
- if (m_is_64_bit)
- DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
- else
- DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
-#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (m_is_64_bit)
- DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
- else
- DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
-#endif
-#endif
- }
-
- if (m_threads.empty() || update) {
- thread_array_t thread_list = nullptr;
- mach_msg_type_number_t thread_list_count = 0;
- task_t task = process.GetTask();
-
- Status error;
- auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
- error.SetError(mach_err, eErrorTypeMachKernel);
- if (error.Fail()) {
- LLDB_LOGF(log,
- "::task_threads(task = 0x%4.4x, thread_list => %p, "
- "thread_list_count => %u) failed: %u (%s)",
- task, thread_list, thread_list_count, error.GetError(),
- error.AsCString());
- return 0;
- }
-
- if (thread_list_count > 0) {
- collection currThreads;
- size_t idx;
- // Iterator through the current thread list and see which threads we
- // already have in our list (keep them), which ones we don't (add them),
- // and which ones are not around anymore (remove them).
- for (idx = 0; idx < thread_list_count; ++idx) {
- // Get the Mach thread port.
- const ::thread_t mach_port_num = thread_list[idx];
-
- // Get the unique thread id for the mach port number.
- uint64_t unique_thread_id =
- NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
- mach_port_num);
-
- // Retrieve the thread if it exists.
- auto thread_sp = GetThreadByID(unique_thread_id);
- if (thread_sp) {
- // We are already tracking it. Keep the existing native thread
- // instance.
- currThreads.push_back(thread_sp);
- } else {
- // We don't have a native thread instance for this thread. Create it
- // now.
- thread_sp.reset(new NativeThreadDarwin(
- &process, m_is_64_bit, unique_thread_id, mach_port_num));
-
- // Add the new thread regardless of its is user ready state. Make
- // sure the thread is ready to be displayed and shown to users before
- // we add this thread to our list...
- if (thread_sp->IsUserReady()) {
- if (new_threads)
- new_threads->push_back(thread_sp);
-
- currThreads.push_back(thread_sp);
- }
- }
- }
-
- m_threads.swap(currThreads);
- m_current_thread.reset();
-
- // Free the vm memory given to us by ::task_threads()
- vm_size_t thread_list_size =
- (vm_size_t)(thread_list_count * sizeof(::thread_t));
- ::vm_deallocate(::mach_task_self(), (vm_address_t)thread_list,
- thread_list_size);
- }
- }
- return static_cast<uint32_t>(m_threads.size());
-}
-
-// TODO implement
-#if 0
-
-void
-NativeThreadListDarwin::CurrentThread (MachThreadSP& thread_sp)
-{
- // locker will keep a mutex locked until it goes out of scope
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- if (m_current_thread.get() == NULL)
- {
- // Figure out which thread is going to be our current thread. This is
- // currently done by finding the first thread in the list that has a
- // valid exception.
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- if (m_threads[idx]->GetStopException().IsValid())
- {
- m_current_thread = m_threads[idx];
- break;
- }
- }
- }
- thread_sp = m_current_thread;
-}
-
-#endif
-
-void NativeThreadListDarwin::Dump(Stream &stream) const {
- bool first = true;
-
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- if (thread_sp) {
- // Handle newlines between thread entries.
- if (first)
- first = false;
- else
- stream.PutChar('\n');
- thread_sp->Dump(stream);
- }
- }
-}
-
-void NativeThreadListDarwin::ProcessWillResume(
- NativeProcessDarwin &process, const ResumeActionList &thread_actions) {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
-
- // Update our thread list, because sometimes libdispatch or the kernel will
- // spawn threads while a task is suspended.
- NativeThreadListDarwin::collection new_threads;
-
-// TODO implement this.
-#if 0
- // First figure out if we were planning on running only one thread, and if
- // so, force that thread to resume.
- bool run_one_thread;
- thread_t solo_thread = THREAD_NULL;
- if ((thread_actions.GetSize() > 0) &&
- (thread_actions.NumActionsWithState(eStateStepping) +
- thread_actions.NumActionsWithState (eStateRunning) == 1))
- {
- run_one_thread = true;
- const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
- size_t num_actions = thread_actions.GetSize();
- for (size_t i = 0; i < num_actions; i++, action_ptr++)
- {
- if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning)
- {
- solo_thread = action_ptr->tid;
- break;
- }
- }
- }
- else
- run_one_thread = false;
-#endif
-
- UpdateThreadList(process, true, &new_threads);
-
-#if 0
- DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS };
- // If we are planning to run only one thread, any new threads should be
- // suspended.
- if (run_one_thread)
- resume_new_threads.state = eStateSuspended;
-
- const size_t num_new_threads = new_threads.size();
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- MachThread *thread = m_threads[idx].get();
- bool handled = false;
- for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx)
- {
- if (thread == new_threads[new_idx].get())
- {
- thread->ThreadWillResume(&resume_new_threads);
- handled = true;
- break;
- }
- }
-
- if (!handled)
- {
- const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true);
- // There must always be a thread action for every thread.
- assert (thread_action);
- bool others_stopped = false;
- if (solo_thread == thread->ThreadID())
- others_stopped = true;
- thread->ThreadWillResume (thread_action, others_stopped);
- }
- }
-
- if (new_threads.size())
- {
- for (uint32_t idx = 0; idx < num_new_threads; ++idx)
- {
- DNBLogThreadedIf (LOG_THREAD, "NativeThreadListDarwin::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
- process->ProcessID(),
- process->StopCount(),
- new_threads[idx]->ThreadID(),
- new_threads[idx]->IsUserReady());
- }
- }
-#endif
-}
-
-uint32_t NativeThreadListDarwin::ProcessDidStop(NativeProcessDarwin &process) {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
-
- // Update our thread list.
- UpdateThreadList(process, true);
-
- for (auto thread_sp : m_threads) {
- if (thread_sp)
- thread_sp->ThreadDidStop();
- }
- return (uint32_t)m_threads.size();
-}
-
-// Check each thread in our thread list to see if we should notify our client
-// of the current halt in execution.
-//
-// Breakpoints can have callback functions associated with them than can return
-// true to stop, or false to continue executing the inferior.
-//
-// RETURNS
-// true if we should stop and notify our clients
-// false if we should resume our child process and skip notification
-bool NativeThreadListDarwin::ShouldStop(bool &step_more) {
- std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- for (auto thread_sp : m_threads) {
- if (thread_sp && thread_sp->ShouldStop(step_more))
- return true;
- }
- return false;
-}
-
-// Implement.
-#if 0
-
-void
-NativeThreadListDarwin::NotifyBreakpointChanged (const DNBBreakpoint *bp)
-{
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- m_threads[idx]->NotifyBreakpointChanged(bp);
- }
-}
-
-
-uint32_t
-NativeThreadListDarwin::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const
-{
- if (bp != NULL)
- {
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->EnableHardwareBreakpoint(bp);
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-bool
-NativeThreadListDarwin::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const
-{
- if (bp != NULL)
- {
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->DisableHardwareBreakpoint(bp);
- }
- return false;
-}
-
-// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
-// MachProcess::EnableWatchpoint() ->
-// NativeThreadListDarwin::EnableHardwareWatchpoint().
-uint32_t
-NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
-{
- uint32_t hw_index = INVALID_NUB_HW_INDEX;
- if (wp != NULL)
- {
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- // On Mac OS X we have to prime the control registers for new threads.
- // We do this using the control register data for the first thread, for
- // lack of a better way of choosing.
- bool also_set_on_task = true;
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX)
- {
- // We know that idx failed for some reason. Let's rollback the
- // transaction for [0, idx).
- for (uint32_t i = 0; i < idx; ++i)
- m_threads[i]->RollbackTransForHWP();
- return INVALID_NUB_HW_INDEX;
- }
- also_set_on_task = false;
- }
- // Notify each thread to commit the pending transaction.
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->FinishTransForHWP();
-
- }
- return hw_index;
-}
-
-bool
-NativeThreadListDarwin::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const
-{
- if (wp != NULL)
- {
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
-
- // On Mac OS X we have to prime the control registers for new threads.
- // We do this using the control register data for the first thread, for
- // lack of a better way of choosing.
- bool also_set_on_task = true;
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task))
- {
- // We know that idx failed for some reason. Let's rollback the
- // transaction for [0, idx).
- for (uint32_t i = 0; i < idx; ++i)
- m_threads[i]->RollbackTransForHWP();
- return false;
- }
- also_set_on_task = false;
- }
- // Notify each thread to commit the pending transaction.
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->FinishTransForHWP();
-
- return true;
- }
- return false;
-}
-
-uint32_t
-NativeThreadListDarwin::NumSupportedHardwareWatchpoints () const
-{
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- // Use an arbitrary thread to retrieve the number of supported hardware
- // watchpoints.
- if (num_threads)
- return m_threads[0]->NumSupportedHardwareWatchpoints();
- return 0;
-}
-
-uint32_t
-NativeThreadListDarwin::GetThreadIndexForThreadStoppedWithSignal (const int signo) const
-{
- PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
- uint32_t should_stop = false;
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx)
- {
- if (m_threads[idx]->GetStopException().SoftSignal () == signo)
- return idx;
- }
- return UINT32_MAX;
-}
-
-#endif
diff --git a/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.h b/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
deleted file mode 100644
index 9ab0a7c8c802..000000000000
--- a/lldb/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
+++ /dev/null
@@ -1,138 +0,0 @@
-//===-- NativeThreadListDarwin.h --------------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 6/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __NativeThreadListDarwin_h__
-#define __NativeThreadListDarwin_h__
-
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include "lldb/lldb-private-forward.h"
-#include "lldb/lldb-types.h"
-
-#include "MachException.h"
-
-// #include "ThreadInfo.h"
-
-namespace lldb_private {
-namespace process_darwin {
-
-class NativeBreakpointDarwin;
-class NativeProcessDarwin;
-
-class NativeThreadDarwin;
-using NativeThreadDarwinSP = std::shared_ptr<NativeThreadDarwin>;
-
-class NativeThreadListDarwin {
-public:
- NativeThreadListDarwin();
- ~NativeThreadListDarwin();
-
- void Clear();
-
- void Dump(Stream &stream) const;
-
-// These methods will be accessed directly from NativeThreadDarwin
-#if 0
- bool GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value) const;
- bool SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value) const;
- nub_size_t GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len);
- nub_size_t SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len);
- uint32_t SaveRegisterState (nub_thread_t tid);
- bool RestoreRegisterState (nub_thread_t tid, uint32_t save_id);
-#endif
-
- const char *GetThreadInfo(lldb::tid_t tid) const;
-
- void ProcessWillResume(NativeProcessDarwin &process,
- const ResumeActionList &thread_actions);
-
- uint32_t ProcessDidStop(NativeProcessDarwin &process);
-
- bool NotifyException(MachException::Data &exc);
-
- bool ShouldStop(bool &step_more);
-
-// These methods will be accessed directly from NativeThreadDarwin
-#if 0
- const char * GetName (nub_thread_t tid);
- nub_state_t GetState (nub_thread_t tid);
- nub_thread_t SetCurrentThread (nub_thread_t tid);
-#endif
-
-// TODO: figure out if we need to add this to NativeThreadDarwin yet.
-#if 0
- ThreadInfo::QoS GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index);
- nub_addr_t GetPThreadT (nub_thread_t tid);
- nub_addr_t GetDispatchQueueT (nub_thread_t tid);
- nub_addr_t GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
-#endif
-
-// These methods will be accessed directly from NativeThreadDarwin
-#if 0
- bool GetThreadStoppedReason (nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
- void DumpThreadStoppedReason (nub_thread_t tid) const;
- bool GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info);
-#endif
-
- size_t GetNumberOfThreads() const;
-
- lldb::tid_t ThreadIDAtIndex(size_t idx) const;
-
- lldb::tid_t GetCurrentThreadID();
-
- NativeThreadDarwinSP GetCurrentThread();
-
- void NotifyBreakpointChanged(const NativeBreakpointDarwin *bp);
-
- uint32_t EnableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
-
- bool DisableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
-
- uint32_t EnableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
-
- bool DisableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
-
- uint32_t GetNumberOfSupportedHardwareWatchpoints() const;
-
- size_t GetThreadIndexForThreadStoppedWithSignal(const int signo) const;
-
- NativeThreadDarwinSP GetThreadByID(lldb::tid_t tid) const;
-
- NativeThreadDarwinSP
- GetThreadByMachPortNumber(::thread_t mach_port_number) const;
-
- lldb::tid_t GetThreadIDByMachPortNumber(::thread_t mach_port_number) const;
-
- thread_t GetMachPortNumberByThreadID(lldb::tid_t globally_unique_id) const;
-
-protected:
- typedef std::vector<NativeThreadDarwinSP> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- // Consider having this return an lldb_private::Status.
- uint32_t UpdateThreadList(NativeProcessDarwin &process, bool update,
- collection *num_threads = nullptr);
-
- collection m_threads;
- mutable std::recursive_mutex m_threads_mutex;
- NativeThreadDarwinSP m_current_thread;
- bool m_is_64_bit;
-};
-
-} // namespace process_darwin
-} // namespace lldb_private
-
-#endif // #ifndef __NativeThreadListDarwin_h__
diff --git a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 0a49f96f54a1..48dbddb86cca 100644
--- a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -1,4 +1,4 @@
-//===-- FreeBSDThread.cpp ---------------------------------------*- C++ -*-===//
+//===-- FreeBSDThread.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -14,9 +14,6 @@
#include <sys/types.h>
#include <sys/user.h>
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/State.h"
-
#include "FreeBSDThread.h"
#include "POSIXStopInfo.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
@@ -26,7 +23,6 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-#include "Plugins/Process/Utility/UnwindLLDB.h"
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
#include "RegisterContextPOSIXProcessMonitor_arm.h"
@@ -44,6 +40,8 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Target/Unwind.h"
#include "lldb/Utility/State.h"
#include "llvm/ADT/SmallString.h"
@@ -166,7 +164,6 @@ lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
- reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
break;
case llvm::Triple::arm:
reg_interface = new RegisterInfoPOSIX_arm(target_arch);
@@ -195,7 +192,8 @@ lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64: {
RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
+ new RegisterContextPOSIXProcessMonitor_arm64(
+ *this, std::make_unique<RegisterInfoPOSIX_arm64>(target_arch));
m_posix_thread = reg_ctx;
m_reg_context_sp.reset(reg_ctx);
break;
@@ -254,8 +252,7 @@ FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
if (concrete_frame_idx == 0)
reg_ctx_sp = GetRegisterContext();
else {
- assert(GetUnwinder());
- reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
+ reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
@@ -275,13 +272,6 @@ bool FreeBSDThread::CalculateStopInfo() {
return true;
}
-Unwind *FreeBSDThread::GetUnwinder() {
- if (!m_unwinder_up)
- m_unwinder_up.reset(new UnwindLLDB(*this));
-
- return m_unwinder_up.get();
-}
-
void FreeBSDThread::DidStop() {
// Don't set the thread state to stopped unless we really stopped.
}
diff --git a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
index 6d3c253a519e..774ffb511bc6 100644
--- a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
@@ -102,8 +102,6 @@ protected:
void ExitNotify(const ProcessMessage &message);
void ExecNotify(const ProcessMessage &message);
- lldb_private::Unwind *GetUnwinder() override;
-
// FreeBSDThread internal API.
// POSIXThread override
diff --git a/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
index 71f012944a9a..4e6f3afda0ab 100644
--- a/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
@@ -1,4 +1,4 @@
-//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===//
+//===-- POSIXStopInfo.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 32e3320150f8..a44080640f6c 100644
--- a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -1,5 +1,4 @@
-//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++
-//-*-===//
+//===-- ProcessFreeBSD.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -57,6 +56,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ProcessFreeBSD)
+
namespace {
UnixSignalsSP &GetFreeBSDSignals() {
static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
@@ -379,7 +380,8 @@ Status ProcessFreeBSD::DoLaunch(Module *module,
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
- const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)};
+ const FileSpec dbg_pts_file_spec{
+ launch_info.GetPTY().GetSecondaryName(NULL, 0)};
file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
stdin_file_spec =
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index ff3fb0a75e2d..6a9209d1214c 100644
--- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===//
+//===-- ProcessMonitor.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -855,7 +855,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
// terminal has already dupped the tty descriptors to stdin/out/err. This
// closes original fd from which they were copied (and avoids leaking
// descriptors to the debugged process.
- terminal.CloseSlaveFileDescriptor();
+ terminal.CloseSecondaryFileDescriptor();
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
@@ -939,7 +939,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
#endif
// Release the master terminal descriptor and pass it off to the
// ProcessMonitor instance. Similarly stash the inferior pid.
- monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
+ monitor->m_terminal_fd = terminal.ReleasePrimaryFileDescriptor();
monitor->m_pid = pid;
// Set the terminal fd to be in non blocking mode (it simplifies the
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
index f0c4526357cc..4216f68faf5c 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm.cpp -----------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_arm.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
index 147f4b56a804..d3eafae1e6de 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm64.cpp -----------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_arm64.cpp ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -22,9 +22,9 @@ using namespace lldb_private;
RegisterContextPOSIXProcessMonitor_arm64::
RegisterContextPOSIXProcessMonitor_arm64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) {}
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
+ : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {}
ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() {
lldb::ProcessSP base = CalculateProcess();
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
index d54d34e89cad..f100d905e28f 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
@@ -17,8 +17,8 @@ class RegisterContextPOSIXProcessMonitor_arm64
public POSIXBreakpointProtocol {
public:
RegisterContextPOSIXProcessMonitor_arm64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info);
protected:
bool ReadGPR();
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
index db9b5a6a038c..23c76f234c8e 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp -----------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index 77694733fa39..f8342775a81b 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp ----------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 3046d97f153c..b1739e1e3bd8 100644
--- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.cpp --------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_x86.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 4313d27e11e9..5109022d80dd 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -1,4 +1,4 @@
-//===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===//
+//===-- NativeProcessNetBSD.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -95,7 +95,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
Info.GetArchitecture().GetArchitectureName());
std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD(
- pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+ pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop));
// Enable event reporting
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index a8afa0b20305..03b505c19890 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -1,4 +1,4 @@
-//===-- NativeRegisterContextNetBSD.cpp -------------------------*- C++ -*-===//
+//===-- NativeRegisterContextNetBSD.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 05a35401da46..ca4706a65657 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- NativeRegisterContextNetBSD_x86_64.cpp ---------------*- C++ -*-===//
+//===-- NativeRegisterContextNetBSD_x86_64.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
#include "NativeRegisterContextNetBSD_x86_64.h"
@@ -16,6 +16,7 @@
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
+#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
// clang-format off
@@ -135,9 +136,84 @@ static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
k_num_dbr_registers_x86_64,
"g_dbr_regnums_x86_64 has wrong number of register infos");
+// x86 32-bit general purpose registers.
+const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit floating point registers.
+const uint32_t g_fpu_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_fpu_regnums_i386 has wrong number of register infos");
+
+// x86 64-bit registers available via XState.
+static const uint32_t g_xstate_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ // Note: we currently do not provide them but this is needed to avoid
+ // unnamed groups in SBFrame::GetRegisterContext().
+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386,
+ lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386 + k_num_mpx_registers_i386,
+ "g_xstate_regnums_i386 has wrong number of register infos");
+
+// x86 debug registers.
+static const uint32_t g_dbr_regnums_i386[] = {
+ lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
+ lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
+ 1 ==
+ k_num_dbr_registers_i386,
+ "g_dbr_regnums_i386 has wrong number of register infos");
+
+
// Number of register sets provided by this context.
enum { k_num_register_sets = 4 };
+// Register sets for x86 32-bit.
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_fpu_regnums_i386},
+ {"Extended State Registers", "xstate",
+ k_num_avx_registers_i386 + k_num_mpx_registers_i386,
+ g_xstate_regnums_i386},
+ {"Debug Registers", "dbr", k_num_dbr_registers_i386,
+ g_dbr_regnums_i386},
+};
+
// Register sets for x86 64-bit.
static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
@@ -164,18 +240,23 @@ NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec &target_arch) {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
- // register context.
- return new RegisterContextNetBSD_x86_64(target_arch);
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextNetBSD_i386 context.
+ return new RegisterContextNetBSD_i386(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
+ // register context.
+ return new RegisterContextNetBSD_x86_64(target_arch);
+ }
}
NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
: NativeRegisterContextNetBSD(native_thread,
CreateRegisterInfoInterface(target_arch)),
- m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {}
+ m_gpr(), m_fpr(), m_dbr() {}
// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
@@ -192,6 +273,8 @@ uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
const RegisterSet *
NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set_index];
case llvm::Triple::x86_64:
return &g_reg_sets_x86_64[set_index];
default:
@@ -202,36 +285,162 @@ NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
return nullptr;
}
+static constexpr int RegNumX86ToX86_64(int regnum) {
+ switch (regnum) {
+ case lldb_eax_i386:
+ return lldb_rax_x86_64;
+ case lldb_ebx_i386:
+ return lldb_rbx_x86_64;
+ case lldb_ecx_i386:
+ return lldb_rcx_x86_64;
+ case lldb_edx_i386:
+ return lldb_rdx_x86_64;
+ case lldb_edi_i386:
+ return lldb_rdi_x86_64;
+ case lldb_esi_i386:
+ return lldb_rsi_x86_64;
+ case lldb_ebp_i386:
+ return lldb_rbp_x86_64;
+ case lldb_esp_i386:
+ return lldb_rsp_x86_64;
+ case lldb_eip_i386:
+ return lldb_rip_x86_64;
+ case lldb_eflags_i386:
+ return lldb_rflags_x86_64;
+ case lldb_cs_i386:
+ return lldb_cs_x86_64;
+ case lldb_fs_i386:
+ return lldb_fs_x86_64;
+ case lldb_gs_i386:
+ return lldb_gs_x86_64;
+ case lldb_ss_i386:
+ return lldb_ss_x86_64;
+ case lldb_ds_i386:
+ return lldb_ds_x86_64;
+ case lldb_es_i386:
+ return lldb_es_x86_64;
+ case lldb_fctrl_i386:
+ return lldb_fctrl_x86_64;
+ case lldb_fstat_i386:
+ return lldb_fstat_x86_64;
+ case lldb_ftag_i386:
+ return lldb_fstat_x86_64;
+ case lldb_fop_i386:
+ return lldb_fop_x86_64;
+ case lldb_fiseg_i386:
+ return lldb_fiseg_x86_64;
+ case lldb_fioff_i386:
+ return lldb_fioff_x86_64;
+ case lldb_foseg_i386:
+ return lldb_foseg_x86_64;
+ case lldb_fooff_i386:
+ return lldb_fooff_x86_64;
+ case lldb_mxcsr_i386:
+ return lldb_mxcsr_x86_64;
+ case lldb_mxcsrmask_i386:
+ return lldb_mxcsrmask_x86_64;
+ case lldb_st0_i386:
+ case lldb_st1_i386:
+ case lldb_st2_i386:
+ case lldb_st3_i386:
+ case lldb_st4_i386:
+ case lldb_st5_i386:
+ case lldb_st6_i386:
+ case lldb_st7_i386:
+ return lldb_st0_x86_64 + regnum - lldb_st0_i386;
+ case lldb_mm0_i386:
+ case lldb_mm1_i386:
+ case lldb_mm2_i386:
+ case lldb_mm3_i386:
+ case lldb_mm4_i386:
+ case lldb_mm5_i386:
+ case lldb_mm6_i386:
+ case lldb_mm7_i386:
+ return lldb_mm0_x86_64 + regnum - lldb_mm0_i386;
+ case lldb_xmm0_i386:
+ case lldb_xmm1_i386:
+ case lldb_xmm2_i386:
+ case lldb_xmm3_i386:
+ case lldb_xmm4_i386:
+ case lldb_xmm5_i386:
+ case lldb_xmm6_i386:
+ case lldb_xmm7_i386:
+ return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386;
+ case lldb_ymm0_i386:
+ case lldb_ymm1_i386:
+ case lldb_ymm2_i386:
+ case lldb_ymm3_i386:
+ case lldb_ymm4_i386:
+ case lldb_ymm5_i386:
+ case lldb_ymm6_i386:
+ case lldb_ymm7_i386:
+ return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386;
+ case lldb_dr0_i386:
+ case lldb_dr1_i386:
+ case lldb_dr2_i386:
+ case lldb_dr3_i386:
+ case lldb_dr4_i386:
+ case lldb_dr5_i386:
+ case lldb_dr6_i386:
+ case lldb_dr7_i386:
+ return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
+ default:
+ assert(false && "Unhandled i386 register.");
+ return 0;
+ }
+}
+
int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
int reg_num) const {
- if (reg_num <= k_last_gpr_x86_64)
- return GPRegSet;
- else if (reg_num <= k_last_fpr_x86_64)
- return FPRegSet;
- else if (reg_num <= k_last_avx_x86_64)
- return XStateRegSet; // AVX
- else if (reg_num <= k_last_mpxr_x86_64)
- return -1; // MPXR
- else if (reg_num <= k_last_mpxc_x86_64)
- return -1; // MPXC
- else if (reg_num <= lldb_dr7_x86_64)
- return DBRegSet; // DBR
- else
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ if (reg_num <= k_last_gpr_i386)
+ return GPRegSet;
+ else if (reg_num <= k_last_fpr_i386)
+ return FPRegSet;
+ else if (reg_num <= k_last_avx_i386)
+ return XStateRegSet; // AVX
+ else if (reg_num <= lldb_dr7_i386)
+ return DBRegSet; // DBR
+ else
+ return -1;
+ case llvm::Triple::x86_64:
+ if (reg_num <= k_last_gpr_x86_64)
+ return GPRegSet;
+ else if (reg_num <= k_last_fpr_x86_64)
+ return FPRegSet;
+ else if (reg_num <= k_last_avx_x86_64)
+ return XStateRegSet; // AVX
+ else if (reg_num <= k_last_mpxr_x86_64)
+ return -1; // MPXR
+ else if (reg_num <= k_last_mpxc_x86_64)
+ return -1; // MPXC
+ else if (reg_num <= lldb_dr7_x86_64)
+ return DBRegSet; // DBR
+ else
+ return -1;
+ default:
+ assert(false && "Unhandled target architecture.");
return -1;
+ }
}
Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_GETREGS, &m_gpr_x86_64);
+ return DoRegisterSet(PT_GETREGS, &m_gpr);
case FPRegSet:
- return DoRegisterSet(PT_GETFPREGS, &m_fpr_x86_64);
+#if defined(__x86_64__)
+ return DoRegisterSet(PT_GETFPREGS, &m_fpr);
+#else
+ return DoRegisterSet(PT_GETXMMREGS, &m_fpr);
+#endif
case DBRegSet:
- return DoRegisterSet(PT_GETDBREGS, &m_dbr_x86_64);
+ return DoRegisterSet(PT_GETDBREGS, &m_dbr);
case XStateRegSet:
#ifdef HAVE_XSTATE
{
- struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)};
+ struct iovec iov = {&m_xstate, sizeof(m_xstate)};
return DoRegisterSet(PT_GETXSTATE, &iov);
}
#else
@@ -244,15 +453,19 @@ Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_SETREGS, &m_gpr_x86_64);
+ return DoRegisterSet(PT_SETREGS, &m_gpr);
case FPRegSet:
- return DoRegisterSet(PT_SETFPREGS, &m_fpr_x86_64);
+#if defined(__x86_64__)
+ return DoRegisterSet(PT_SETFPREGS, &m_fpr);
+#else
+ return DoRegisterSet(PT_SETXMMREGS, &m_fpr);
+#endif
case DBRegSet:
- return DoRegisterSet(PT_SETDBREGS, &m_dbr_x86_64);
+ return DoRegisterSet(PT_SETDBREGS, &m_dbr);
case XStateRegSet:
#ifdef HAVE_XSTATE
{
- struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)};
+ struct iovec iov = {&m_xstate, sizeof(m_xstate)};
return DoRegisterSet(PT_SETXSTATE, &iov);
}
#else
@@ -272,7 +485,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
if (reg == LLDB_INVALID_REGNUM) {
// This is likely an internal register for lldb use only and should not be
// directly queried.
@@ -291,112 +504,175 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86_64:
+ break;
+ case llvm::Triple::x86:
+ reg = RegNumX86ToX86_64(reg);
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ error.SetErrorString("Unhandled target architecture.");
+ return error;
+ }
+
error = ReadRegisterSet(set);
if (error.Fail())
return error;
switch (reg) {
+#if defined(__x86_64__)
case lldb_rax_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RAX];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RAX];
break;
case lldb_rbx_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBX];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RBX];
break;
case lldb_rcx_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RCX];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RCX];
break;
case lldb_rdx_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDX];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RDX];
break;
case lldb_rdi_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDI];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RDI];
break;
case lldb_rsi_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSI];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RSI];
break;
case lldb_rbp_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBP];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RBP];
break;
case lldb_rsp_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSP];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RSP];
break;
case lldb_r8_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R8];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R8];
break;
case lldb_r9_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R9];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R9];
break;
case lldb_r10_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R10];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R10];
break;
case lldb_r11_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R11];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R11];
break;
case lldb_r12_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R12];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R12];
break;
case lldb_r13_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R13];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R13];
break;
case lldb_r14_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R14];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R14];
break;
case lldb_r15_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R15];
+ reg_value = (uint64_t)m_gpr.regs[_REG_R15];
break;
case lldb_rip_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RIP];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RIP];
break;
case lldb_rflags_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RFLAGS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS];
break;
case lldb_cs_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_CS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_CS];
break;
case lldb_fs_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_FS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_FS];
break;
case lldb_gs_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_GS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_GS];
break;
case lldb_ss_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_SS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_SS];
break;
case lldb_ds_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_DS];
+ reg_value = (uint64_t)m_gpr.regs[_REG_DS];
break;
case lldb_es_x86_64:
- reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES];
+ reg_value = (uint64_t)m_gpr.regs[_REG_ES];
+ break;
+#else
+ case lldb_rax_x86_64:
+ reg_value = (uint32_t)m_gpr.r_eax;
break;
+ case lldb_rbx_x86_64:
+ reg_value = (uint32_t)m_gpr.r_ebx;
+ break;
+ case lldb_rcx_x86_64:
+ reg_value = (uint32_t)m_gpr.r_ecx;
+ break;
+ case lldb_rdx_x86_64:
+ reg_value = (uint32_t)m_gpr.r_edx;
+ break;
+ case lldb_rdi_x86_64:
+ reg_value = (uint32_t)m_gpr.r_edi;
+ break;
+ case lldb_rsi_x86_64:
+ reg_value = (uint32_t)m_gpr.r_esi;
+ break;
+ case lldb_rsp_x86_64:
+ reg_value = (uint32_t)m_gpr.r_esp;
+ break;
+ case lldb_rbp_x86_64:
+ reg_value = (uint32_t)m_gpr.r_ebp;
+ break;
+ case lldb_rip_x86_64:
+ reg_value = (uint32_t)m_gpr.r_eip;
+ break;
+ case lldb_rflags_x86_64:
+ reg_value = (uint32_t)m_gpr.r_eflags;
+ break;
+ case lldb_cs_x86_64:
+ reg_value = (uint32_t)m_gpr.r_cs;
+ break;
+ case lldb_fs_x86_64:
+ reg_value = (uint32_t)m_gpr.r_fs;
+ break;
+ case lldb_gs_x86_64:
+ reg_value = (uint32_t)m_gpr.r_gs;
+ break;
+ case lldb_ss_x86_64:
+ reg_value = (uint32_t)m_gpr.r_ss;
+ break;
+ case lldb_ds_x86_64:
+ reg_value = (uint32_t)m_gpr.r_ds;
+ break;
+ case lldb_es_x86_64:
+ reg_value = (uint32_t)m_gpr.r_es;
+ break;
+#endif
case lldb_fctrl_x86_64:
- reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_cw;
+ reg_value = (uint16_t)m_fpr.fxstate.fx_cw;
break;
case lldb_fstat_x86_64:
- reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_sw;
+ reg_value = (uint16_t)m_fpr.fxstate.fx_sw;
break;
case lldb_ftag_x86_64:
- reg_value = (uint8_t)m_fpr_x86_64.fxstate.fx_tw;
+ reg_value = (uint8_t)m_fpr.fxstate.fx_tw;
break;
case lldb_fop_x86_64:
- reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_opcode;
+ reg_value = (uint64_t)m_fpr.fxstate.fx_opcode;
break;
case lldb_fiseg_x86_64:
- reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_ip.fa_64;
+ reg_value = (uint64_t)m_fpr.fxstate.fx_ip.fa_64;
break;
case lldb_fioff_x86_64:
- reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off;
+ reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off;
break;
case lldb_foseg_x86_64:
- reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_dp.fa_64;
+ reg_value = (uint64_t)m_fpr.fxstate.fx_dp.fa_64;
break;
case lldb_fooff_x86_64:
- reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off;
+ reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off;
break;
case lldb_mxcsr_x86_64:
- reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr;
+ reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr;
break;
case lldb_mxcsrmask_x86_64:
- reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr_mask;
+ reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask;
break;
case lldb_st0_x86_64:
case lldb_st1_x86_64:
@@ -406,7 +682,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
case lldb_st5_x86_64:
case lldb_st6_x86_64:
case lldb_st7_x86_64:
- reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
+ reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
reg_info->byte_size, endian::InlHostByteOrder());
break;
case lldb_mm0_x86_64:
@@ -417,7 +693,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
case lldb_mm5_x86_64:
case lldb_mm6_x86_64:
case lldb_mm7_x86_64:
- reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
+ reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
reg_info->byte_size, endian::InlHostByteOrder());
break;
case lldb_xmm0_x86_64:
@@ -436,7 +712,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
case lldb_xmm13_x86_64:
case lldb_xmm14_x86_64:
case lldb_xmm15_x86_64:
- reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
+ reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
reg_info->byte_size, endian::InlHostByteOrder());
break;
case lldb_ymm0_x86_64:
@@ -456,15 +732,15 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
case lldb_ymm14_x86_64:
case lldb_ymm15_x86_64:
#ifdef HAVE_XSTATE
- if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) ||
- !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) {
+ if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
+ !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
reg_info->name);
} else {
uint32_t reg_index = reg - lldb_ymm0_x86_64;
YMMReg ymm = XStateToYMM(
- m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
- m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
+ m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+ m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
endian::InlHostByteOrder());
}
@@ -480,7 +756,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
case lldb_dr5_x86_64:
case lldb_dr6_x86_64:
case lldb_dr7_x86_64:
- reg_value = (uint64_t)m_dbr_x86_64.dr[reg - lldb_dr0_x86_64];
+ reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
break;
}
@@ -497,7 +773,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
return error;
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
if (reg == LLDB_INVALID_REGNUM) {
// This is likely an internal register for lldb use only and should not be
// directly queried.
@@ -516,112 +792,175 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
return error;
}
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86_64:
+ break;
+ case llvm::Triple::x86:
+ reg = RegNumX86ToX86_64(reg);
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ error.SetErrorString("Unhandled target architecture.");
+ return error;
+ }
+
error = ReadRegisterSet(set);
if (error.Fail())
return error;
switch (reg) {
+#if defined(__x86_64__)
case lldb_rax_x86_64:
- m_gpr_x86_64.regs[_REG_RAX] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
break;
case lldb_rbx_x86_64:
- m_gpr_x86_64.regs[_REG_RBX] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
break;
case lldb_rcx_x86_64:
- m_gpr_x86_64.regs[_REG_RCX] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
break;
case lldb_rdx_x86_64:
- m_gpr_x86_64.regs[_REG_RDX] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
break;
case lldb_rdi_x86_64:
- m_gpr_x86_64.regs[_REG_RDI] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
break;
case lldb_rsi_x86_64:
- m_gpr_x86_64.regs[_REG_RSI] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
break;
case lldb_rbp_x86_64:
- m_gpr_x86_64.regs[_REG_RBP] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
break;
case lldb_rsp_x86_64:
- m_gpr_x86_64.regs[_REG_RSP] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
break;
case lldb_r8_x86_64:
- m_gpr_x86_64.regs[_REG_R8] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
break;
case lldb_r9_x86_64:
- m_gpr_x86_64.regs[_REG_R9] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
break;
case lldb_r10_x86_64:
- m_gpr_x86_64.regs[_REG_R10] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
break;
case lldb_r11_x86_64:
- m_gpr_x86_64.regs[_REG_R11] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
break;
case lldb_r12_x86_64:
- m_gpr_x86_64.regs[_REG_R12] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
break;
case lldb_r13_x86_64:
- m_gpr_x86_64.regs[_REG_R13] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
break;
case lldb_r14_x86_64:
- m_gpr_x86_64.regs[_REG_R14] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
break;
case lldb_r15_x86_64:
- m_gpr_x86_64.regs[_REG_R15] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
break;
case lldb_rip_x86_64:
- m_gpr_x86_64.regs[_REG_RIP] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
break;
case lldb_rflags_x86_64:
- m_gpr_x86_64.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
break;
case lldb_cs_x86_64:
- m_gpr_x86_64.regs[_REG_CS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
break;
case lldb_fs_x86_64:
- m_gpr_x86_64.regs[_REG_FS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64();
break;
case lldb_gs_x86_64:
- m_gpr_x86_64.regs[_REG_GS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64();
break;
case lldb_ss_x86_64:
- m_gpr_x86_64.regs[_REG_SS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
break;
case lldb_ds_x86_64:
- m_gpr_x86_64.regs[_REG_DS] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64();
break;
case lldb_es_x86_64:
- m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64();
+ m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64();
break;
+#else
+ case lldb_rax_x86_64:
+ m_gpr.r_eax = reg_value.GetAsUInt32();
+ break;
+ case lldb_rbx_x86_64:
+ m_gpr.r_ebx = reg_value.GetAsUInt32();
+ break;
+ case lldb_rcx_x86_64:
+ m_gpr.r_ecx = reg_value.GetAsUInt32();
+ break;
+ case lldb_rdx_x86_64:
+ m_gpr.r_edx = reg_value.GetAsUInt32();
+ break;
+ case lldb_rdi_x86_64:
+ m_gpr.r_edi = reg_value.GetAsUInt32();
+ break;
+ case lldb_rsi_x86_64:
+ m_gpr.r_esi = reg_value.GetAsUInt32();
+ break;
+ case lldb_rsp_x86_64:
+ m_gpr.r_esp = reg_value.GetAsUInt32();
+ break;
+ case lldb_rbp_x86_64:
+ m_gpr.r_ebp = reg_value.GetAsUInt32();
+ break;
+ case lldb_rip_x86_64:
+ m_gpr.r_eip = reg_value.GetAsUInt32();
+ break;
+ case lldb_rflags_x86_64:
+ m_gpr.r_eflags = reg_value.GetAsUInt32();
+ break;
+ case lldb_cs_x86_64:
+ m_gpr.r_cs = reg_value.GetAsUInt32();
+ break;
+ case lldb_fs_x86_64:
+ m_gpr.r_fs = reg_value.GetAsUInt32();
+ break;
+ case lldb_gs_x86_64:
+ m_gpr.r_gs = reg_value.GetAsUInt32();
+ break;
+ case lldb_ss_x86_64:
+ m_gpr.r_ss = reg_value.GetAsUInt32();
+ break;
+ case lldb_ds_x86_64:
+ m_gpr.r_ds = reg_value.GetAsUInt32();
+ break;
+ case lldb_es_x86_64:
+ m_gpr.r_es = reg_value.GetAsUInt32();
+ break;
+#endif
case lldb_fctrl_x86_64:
- m_fpr_x86_64.fxstate.fx_cw = reg_value.GetAsUInt16();
+ m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16();
break;
case lldb_fstat_x86_64:
- m_fpr_x86_64.fxstate.fx_sw = reg_value.GetAsUInt16();
+ m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16();
break;
case lldb_ftag_x86_64:
- m_fpr_x86_64.fxstate.fx_tw = reg_value.GetAsUInt8();
+ m_fpr.fxstate.fx_tw = reg_value.GetAsUInt8();
break;
case lldb_fop_x86_64:
- m_fpr_x86_64.fxstate.fx_opcode = reg_value.GetAsUInt16();
+ m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16();
break;
case lldb_fiseg_x86_64:
- m_fpr_x86_64.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64();
+ m_fpr.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64();
break;
case lldb_fioff_x86_64:
- m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
+ m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
break;
case lldb_foseg_x86_64:
- m_fpr_x86_64.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64();
+ m_fpr.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64();
break;
case lldb_fooff_x86_64:
- m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
+ m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
break;
case lldb_mxcsr_x86_64:
- m_fpr_x86_64.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
+ m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
break;
case lldb_mxcsrmask_x86_64:
- m_fpr_x86_64.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
+ m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
break;
case lldb_st0_x86_64:
case lldb_st1_x86_64:
@@ -631,7 +970,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_st5_x86_64:
case lldb_st6_x86_64:
case lldb_st7_x86_64:
- ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
+ ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
reg_value.GetBytes(), reg_value.GetByteSize());
break;
case lldb_mm0_x86_64:
@@ -642,7 +981,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_mm5_x86_64:
case lldb_mm6_x86_64:
case lldb_mm7_x86_64:
- ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
+ ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
reg_value.GetBytes(), reg_value.GetByteSize());
break;
case lldb_xmm0_x86_64:
@@ -661,7 +1000,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_xmm13_x86_64:
case lldb_xmm14_x86_64:
case lldb_xmm15_x86_64:
- ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
+ ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
reg_value.GetBytes(), reg_value.GetByteSize());
break;
case lldb_ymm0_x86_64:
@@ -681,8 +1020,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_ymm14_x86_64:
case lldb_ymm15_x86_64:
#ifdef HAVE_XSTATE
- if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) ||
- !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) {
+ if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
+ !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
reg_info->name);
} else {
@@ -690,8 +1029,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
YMMReg ymm;
::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
YMMToXState(ymm,
- m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
- m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
+ m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
+ m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
}
#else
error.SetErrorString("XState not supported by the kernel");
@@ -705,7 +1044,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
case lldb_dr5_x86_64:
case lldb_dr6_x86_64:
case lldb_dr7_x86_64:
- m_dbr_x86_64.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
+ m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
break;
}
@@ -722,7 +1061,7 @@ Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
return error;
uint8_t *dst = data_sp->GetBytes();
- ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
+ ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize();
return error;
@@ -742,7 +1081,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
error.SetErrorStringWithFormat(
"NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
+ "data size, expected %zu, actual %" PRIu64,
__FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
return error;
}
@@ -755,7 +1094,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
__FUNCTION__);
return error;
}
- ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
+ ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
error = WriteRegisterSet(GPRegSet);
if (error.Fail())
@@ -765,13 +1104,25 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
return error;
}
+int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
+ assert(num >= 0 && num <= 7);
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return lldb_dr0_i386 + num;
+ case llvm::Triple::x86_64:
+ return lldb_dr0_x86_64 + num;
+ default:
+ return -1;
+ }
+}
+
Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index,
bool &is_hit) {
if (wp_index >= NumSupportedHardwareWatchpoints())
return Status("Watchpoint index out of range");
RegisterValue reg_value;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6));
Status error = ReadRegister(reg_info, reg_value);
if (error.Fail()) {
is_hit = false;
@@ -808,7 +1159,7 @@ Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
return Status("Watchpoint index out of range");
RegisterValue reg_value;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7));
Status error = ReadRegister(reg_info, reg_value);
if (error.Fail()) {
is_vacant = false;
@@ -848,8 +1199,7 @@ Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
if (!is_vacant)
return Status("Watchpoint index not vacant");
- const RegisterInfo *const reg_info_dr7 =
- GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
RegisterValue dr7_value;
error = ReadRegister(reg_info_dr7, dr7_value);
if (error.Fail())
@@ -874,7 +1224,7 @@ Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
control_bits |= enable_bit | rw_bits | size_bits;
const RegisterInfo *const reg_info_drN =
- GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ GetRegisterInfoAtIndex(GetDR(wp_index));
RegisterValue drN_value;
error = ReadRegister(reg_info_drN, drN_value);
if (error.Fail())
@@ -906,8 +1256,7 @@ bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
// for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5
// or 6-7 of the debug control register (DR7)
- const RegisterInfo *const reg_info_dr7 =
- GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
RegisterValue reg_value;
Status error = ReadRegister(reg_info_dr7, reg_value);
if (error.Fail())
@@ -924,8 +1273,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index)
// for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of
// the debug status register (DR6)
- const RegisterInfo *const reg_info_dr6 =
- GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
RegisterValue reg_value;
Status error = ReadRegister(reg_info_dr6, reg_value);
if (error.Fail())
@@ -940,8 +1288,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
RegisterValue reg_value;
// clear bits {0-4} of the debug status register (DR6)
- const RegisterInfo *const reg_info_dr6 =
- GetRegisterInfoAtIndex(lldb_dr6_x86_64);
+ const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
Status error = ReadRegister(reg_info_dr6, reg_value);
if (error.Fail())
return error;
@@ -952,8 +1299,7 @@ Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
return error;
// clear bits {0-7,16-31} of the debug control register (DR7)
- const RegisterInfo *const reg_info_dr7 =
- GetRegisterInfoAtIndex(lldb_dr7_x86_64);
+ const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
error = ReadRegister(reg_info_dr7, reg_value);
if (error.Fail())
return error;
@@ -988,7 +1334,7 @@ NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
return LLDB_INVALID_ADDRESS;
RegisterValue reg_value;
const RegisterInfo *const reg_info_drN =
- GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
+ GetRegisterInfoAtIndex(GetDR(wp_index));
if (ReadRegister(reg_info_drN, reg_value).Fail())
return LLDB_INVALID_ADDRESS;
return reg_value.GetAsUInt64();
@@ -1005,10 +1351,10 @@ Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
Status res = r_source.ReadRegisterSet(DBRegSet);
if (!res.Fail()) {
// copy dbregs only if any watchpoints were set
- if ((r_source.m_dbr_x86_64.dr[7] & 0xFF) == 0)
+ if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
return res;
- m_dbr_x86_64 = r_source.m_dbr_x86_64;
+ m_dbr = r_source.m_dbr;
res = WriteRegisterSet(DBRegSet);
}
return res;
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 54b8a806267f..6c0632f3bce8 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
#ifndef lldb_NativeRegisterContextNetBSD_x86_64_h
#define lldb_NativeRegisterContextNetBSD_x86_64_h
@@ -81,14 +81,19 @@ private:
enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet };
// Private member variables.
- struct reg m_gpr_x86_64;
- struct fpreg m_fpr_x86_64;
- struct dbreg m_dbr_x86_64;
+ struct reg m_gpr;
+#if defined(__x86_64__)
+ struct fpreg m_fpr;
+#else
+ struct xmmregs m_fpr;
+#endif
+ struct dbreg m_dbr;
#ifdef HAVE_XSTATE
- struct xstate m_xstate_x86_64;
+ struct xstate m_xstate;
#endif
int GetSetForNativeRegNum(int reg_num) const;
+ int GetDR(int num) const;
Status ReadRegisterSet(uint32_t set);
Status WriteRegisterSet(uint32_t set);
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index dd2745d9330e..fe76fb40e0b3 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -1,4 +1,4 @@
-//===-- NativeThreadNetBSD.cpp -------------------------------- -*- C++ -*-===//
+//===-- NativeThreadNetBSD.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
index b872269fdfe1..579077b45bf9 100644
--- a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -1,4 +1,4 @@
-//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
+//===-- CrashReason.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
index 058dc5ae2338..117d12101a0b 100644
--- a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
+++ b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
@@ -1,4 +1,4 @@
-//===-- NativeProcessELF.cpp ---------------------------------- -*- C++ -*-===//
+//===-- NativeProcessELF.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -107,6 +107,11 @@ lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() {
return LLDB_INVALID_ADDRESS;
}
+template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress<
+ llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>();
+template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress<
+ llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, llvm::ELF::Elf64_Dyn>();
+
template <typename T>
llvm::Expected<SVR4LibraryInfo>
NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) {
diff --git a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
index 4fb513baebf0..dcfa9290ff50 100644
--- a/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
+++ b/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -48,6 +48,14 @@ protected:
llvm::Optional<lldb::addr_t> m_shared_library_info_addr;
};
+// Explicitly declare the two 32/64 bit templates that NativeProcessELF.cpp will
+// define. This allows us to keep the template definition here and usable
+// elsewhere.
+extern template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress<
+ llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr, llvm::ELF::Elf32_Dyn>();
+extern template lldb::addr_t NativeProcessELF::GetELFImageInfoAddress<
+ llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr, llvm::ELF::Elf64_Dyn>();
+
} // namespace lldb_private
-#endif \ No newline at end of file
+#endif
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 66286dd3d9e3..4e8c6f1ba2d2 100644
--- a/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
+//===-- ProcessMessage.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
index a17558bfe7c6..f4d0803b264a 100644
--- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -1,5 +1,4 @@
-//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++
-//-*-===//
+//===-- ProcessPOSIXLog.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h
index 1f7eb54d10e7..fd3965fade19 100644
--- a/lldb/source/Plugins/Process/Utility/ARMDefines.h
+++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ARMDefines_h_
-#define lldb_ARMDefines_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
#include "llvm/Support/ErrorHandling.h"
@@ -188,4 +188,4 @@ static inline bool ARMConditionPassed(const uint32_t condition,
} // namespace lldb_private
-#endif // lldb_ARMDefines_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h
index d860348818d3..bbe4c9a35fa6 100644
--- a/lldb/source/Plugins/Process/Utility/ARMUtils.h
+++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ARMUtils_h_
-#define lldb_ARMUtils_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H
#include "ARMDefines.h"
#include "InstructionUtils.h"
@@ -371,4 +371,4 @@ static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
} // namespace lldb_private
-#endif // lldb_ARMUtils_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
index 25a1d0b5af06..685d9d0824f6 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
@@ -1,4 +1,4 @@
-//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
+//===-- AuxVector.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h
index c16be68aedb1..c8c8b1249413 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_AuxVector_H_
-#define liblldb_AuxVector_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_AUXVECTOR_H
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index a86880af2260..443638aa39f6 100644
--- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -1,4 +1,4 @@
-//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
+//===-- DynamicRegisterInfo.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -742,6 +742,8 @@ const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
for (auto &reg_info : m_regs) {
// We can use pointer comparison since we used a ConstString to set the
// "name" member in AddRegister()
+ assert(ConstString(reg_info.name).GetCString() == reg_info.name &&
+ "reg_info.name not from a ConstString?");
if (reg_info.name == reg_name.GetCString()) {
return &reg_info;
}
diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index aacf547e187d..48939375a504 100644
--- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_DynamicRegisterInfo_h_
-#define lldb_DynamicRegisterInfo_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
#include <map>
#include <vector>
@@ -90,4 +90,4 @@ protected:
// all registers
bool m_finalized = false;
};
-#endif // lldb_DynamicRegisterInfo_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
diff --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
index 9f63a594e054..0a4bdc72b364 100644
--- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -1,4 +1,4 @@
-//===-- FreeBSDSignals.cpp --------------------------------------*- C++ -*-===//
+//===-- FreeBSDSignals.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h
index 75462f3c76ff..c4c810e54985 100644
--- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h
+++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_FreeBSDSignals_H_
-#define liblldb_FreeBSDSignals_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H
#include "lldb/Target/UnixSignals.h"
@@ -24,4 +24,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_FreeBSDSignals_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_FREEBSDSIGNALS_H
diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
index ed35273ce3fe..427225c14d3b 100644
--- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===//
+//===-- GDBRemoteSignals.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h
index a02dd0604e67..d37757ab60a5 100644
--- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h
+++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteSignals_H_
-#define liblldb_GDBRemoteSignals_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H
#include "lldb/Target/UnixSignals.h"
@@ -26,4 +26,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_GDBRemoteSignals_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_GDBREMOTESIGNALS_H
diff --git a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp
index 295c17e474fb..d73b132539f1 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/lldb/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -1,4 +1,4 @@
-//===-- HistoryThread.cpp ---------------------------------------*- C++ -*-===//
+//===-- HistoryThread.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,12 +25,14 @@ using namespace lldb_private;
// Constructor
HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
- std::vector<lldb::addr_t> pcs)
+ std::vector<lldb::addr_t> pcs,
+ bool pcs_are_call_addresses)
: Thread(process, tid, true), m_framelist_mutex(), m_framelist(),
m_pcs(pcs), m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(),
m_thread_name(), m_originating_unique_thread_id(tid),
m_queue_id(LLDB_INVALID_QUEUE_ID) {
- m_unwinder_up.reset(new HistoryUnwind(*this, pcs));
+ m_unwinder_up =
+ std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
diff --git a/lldb/source/Plugins/Process/Utility/HistoryThread.h b/lldb/source/Plugins/Process/Utility/HistoryThread.h
index 1e2658640172..a66e0f2d4207 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryThread.h
+++ b/lldb/source/Plugins/Process/Utility/HistoryThread.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_HistoryThread_h_
-#define liblldb_HistoryThread_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H
#include <mutex>
@@ -33,7 +33,8 @@ namespace lldb_private {
class HistoryThread : public lldb_private::Thread {
public:
HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
- std::vector<lldb::addr_t> pcs);
+ std::vector<lldb::addr_t> pcs,
+ bool pcs_are_call_addresses = false);
~HistoryThread() override;
@@ -88,4 +89,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_HistoryThread_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYTHREAD_H
diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 83fdb011f5a1..9b9522955de9 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -1,4 +1,4 @@
-//===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===//
+//===-- HistoryUnwind.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -23,8 +23,10 @@ using namespace lldb_private;
// Constructor
-HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs)
- : Unwind(thread), m_pcs(pcs) {}
+HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool pcs_are_call_addresses)
+ : Unwind(thread), m_pcs(pcs),
+ m_pcs_are_call_addresses(pcs_are_call_addresses) {}
// Destructor
@@ -59,7 +61,10 @@ bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
if (frame_idx < m_pcs.size()) {
cfa = frame_idx;
pc = m_pcs[frame_idx];
- behaves_like_zeroth_frame = (frame_idx == 0);
+ if (m_pcs_are_call_addresses)
+ behaves_like_zeroth_frame = true;
+ else
+ behaves_like_zeroth_frame = (frame_idx == 0);
return true;
}
return false;
diff --git a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
index 4d16608bd8c2..cb72b5d0a176 100644
--- a/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/lldb/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_HistoryUnwind_h_
-#define liblldb_HistoryUnwind_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H
#include <vector>
@@ -18,7 +18,8 @@ namespace lldb_private {
class HistoryUnwind : public lldb_private::Unwind {
public:
- HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs);
+ HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool pcs_are_call_addresses = false);
~HistoryUnwind() override;
@@ -35,8 +36,11 @@ protected:
private:
std::vector<lldb::addr_t> m_pcs;
+ /// This boolean indicates that the PCs in the non-0 frames are call
+ /// addresses and not return addresses.
+ bool m_pcs_are_call_addresses;
};
} // namespace lldb_private
-#endif // liblldb_HistoryUnwind_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_HISTORYUNWIND_H
diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index ee939b01d350..0f331933f2ea 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -1,4 +1,4 @@
-//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===//
+//===-- InferiorCallPOSIX.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index 2008c5fe0b91..3623e10194f9 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_InferiorCallPOSIX_h_
-#define lldb_InferiorCallPOSIX_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H
// Inferior execution of POSIX functions.
@@ -32,4 +32,4 @@ bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
} // namespace lldb_private
-#endif // lldb_InferiorCallPOSIX_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INFERIORCALLPOSIX_H
diff --git a/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/lldb/source/Plugins/Process/Utility/InstructionUtils.h
index f74933e691ee..55b89440700b 100644
--- a/lldb/source/Plugins/Process/Utility/InstructionUtils.h
+++ b/lldb/source/Plugins/Process/Utility/InstructionUtils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_InstructionUtils_h_
-#define lldb_InstructionUtils_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
#include <cassert>
#include <cstdint>
@@ -113,4 +113,4 @@ static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit,
} // namespace lldb_private
-#endif // lldb_InstructionUtils_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
diff --git a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
index 1ba432aa542b..0c7d9ddc5ac6 100644
--- a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
+++ b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
@@ -1,4 +1,4 @@
-//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===//
+//===-- LinuxProcMaps.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
index e1f0e48ac5c9..363f248fd416 100644
--- a/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
+++ b/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LinuxProcMaps_H_
-#define liblldb_LinuxProcMaps_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
@@ -24,4 +24,4 @@ void ParseLinuxMapRegions(llvm::StringRef linux_map,
} // namespace lldb_private
-#endif // liblldb_LinuxProcMaps_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPROCMAPS_H
diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
index bef47cd26307..4dd619e3bade 100644
--- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -1,4 +1,4 @@
-//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===//
+//===-- LinuxSignals.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.h b/lldb/source/Plugins/Process/Utility/LinuxSignals.h
index 7ad8cfcbef68..32c4744a96d0 100644
--- a/lldb/source/Plugins/Process/Utility/LinuxSignals.h
+++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_LinuxSignals_H_
-#define liblldb_LinuxSignals_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H
#include "lldb/Target/UnixSignals.h"
@@ -24,4 +24,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_LinuxSignals_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXSIGNALS_H
diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index d8e5426ab5a5..8f75844277c0 100644
--- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -1,5 +1,4 @@
-//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++
-//-*-===//
+//===-- MipsLinuxSignals.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h
index b5e3ed86f568..6b78fc72a91c 100644
--- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h
+++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_MipsLinuxSignals_H_
-#define liblldb_MipsLinuxSignals_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H
#include "lldb/Target/UnixSignals.h"
@@ -25,4 +25,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_MipsLinuxSignals_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
index be61cfdd7374..3a875f7bb39b 100644
--- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
@@ -1,4 +1,4 @@
-//===-- NativeRegisterContextRegisterInfo.cpp -------------------*- C++ -*-===//
+//===-- NativeRegisterContextRegisterInfo.cpp -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
index b285c477cd96..0e96841fd909 100644
--- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO
-#define LLDB_PLUGINS_PROCESS_UTIILTY_NATIVE_REGISTER_CONTEXT_REGISTER_INFO
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NATIVEREGISTERCONTEXTREGISTERINFO_H
#include <memory>
@@ -33,7 +33,7 @@ public:
const RegisterInfoInterface &GetRegisterInfoInterface() const;
-private:
+protected:
std::unique_ptr<RegisterInfoInterface> m_register_info_interface_up;
};
}
diff --git a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
index 29967deb7e9b..ffdfd19b4efe 100644
--- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp
@@ -1,4 +1,4 @@
-//===-- NetBSDSignals.cpp --------------------------------------*- C++ -*-===//
+//===-- NetBSDSignals.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
index bf7399a89060..e6740a304a02 100644
--- a/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
+++ b/lldb/source/Plugins/Process/Utility/NetBSDSignals.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_NetBSDSignals_H_
-#define liblldb_NetBSDSignals_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H
#include "lldb/Target/UnixSignals.h"
@@ -24,4 +24,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_NetBSDSignals_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_NETBSDSIGNALS_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h
index ef40162984f1..21582df91fb0 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwinConstants.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_REGISTERCONTEXTDARWINCONSTANTS_H
-#define LLDB_REGISTERCONTEXTDARWINCONSTANTS_H
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H
namespace lldb_private {
@@ -22,4 +22,4 @@ namespace lldb_private {
} // namespace lldb_private
-#endif // LLDB_REGISTERCONTEXTDARWINCONSTANTS_H
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWINCONSTANTS_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 173e66904151..eef4541e7edd 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_arm.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
index d7c1809a3222..1bd60f756487 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextDarwin_arm_h_
-#define liblldb_RegisterContextDarwin_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
@@ -261,4 +261,4 @@ protected:
static const lldb_private::RegisterInfo *GetRegisterInfos();
};
-#endif // liblldb_RegisterContextDarwin_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index fa5197cd6bf4..9fc275276699 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -1,5 +1,4 @@
-//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++
-//-*-===//
+//===-- RegisterContextDarwin_arm64.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index abb87e3c2348..010e566be32c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextDarwin_arm64_h_
-#define liblldb_RegisterContextDarwin_arm64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
@@ -228,4 +228,4 @@ protected:
static const lldb_private::RegisterInfo *GetRegisterInfos();
};
-#endif // liblldb_RegisterContextDarwin_arm64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM64_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 959b04700b17..c5ebddc56b6c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_i386.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
index e52f0fe63250..9c759c31caed 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextDarwin_i386_h_
-#define liblldb_RegisterContextDarwin_i386_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
@@ -205,4 +205,4 @@ protected:
static const lldb_private::RegisterInfo *GetRegisterInfos();
};
-#endif // liblldb_RegisterContextDarwin_i386_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 22088a7d6448..38cd00aea9cc 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextDarwin_x86_64.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_x86_64.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
index 1a65a4f28b33..d9ba8d0b2319 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextDarwin_x86_64_h_
-#define liblldb_RegisterContextDarwin_x86_64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
@@ -210,4 +210,4 @@ protected:
static const lldb_private::RegisterInfo *GetRegisterInfos();
};
-#endif // liblldb_RegisterContextDarwin_x86_64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp
index 6832b6095931..4c2e291c62d6 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp
@@ -1,5 +1,4 @@
-//===-- RegisterContextDummy.cpp ---------------------------------*- C++
-//-*-===//
+//===-- RegisterContextDummy.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h
index bdaa2217d207..de98767693fe 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_RegisterContextDummy_h_
-#define lldb_RegisterContextDummy_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H
#include <vector>
@@ -56,9 +56,10 @@ private:
lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
lldb_private::RegisterInfo m_pc_reg_info;
- DISALLOW_COPY_AND_ASSIGN(RegisterContextDummy);
+ RegisterContextDummy(const RegisterContextDummy &) = delete;
+ const RegisterContextDummy &operator=(const RegisterContextDummy &) = delete;
};
} // namespace lldb_private
-#endif // lldb_RegisterContextDummy_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDUMMY_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index b90b38108267..10d346a3cb7e 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_i386.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_i386.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
index 7aadf3a0a4c9..5a3e5b0551d6 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextFreeBSD_i386_H_
-#define liblldb_RegisterContextFreeBSD_i386_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_I386_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
index 4331ef5ad14e..0c5d34f345db 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_mips64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_mips64.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
index 96f02b4440c5..39968eacf475 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextFreeBSD_mips64_H_
-#define liblldb_RegisterContextFreeBSD_mips64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_MIPS64_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 4f869eb3b177..9fe6255d698e 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_powerpc.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
index ba2751194d16..7e4c43ba908a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextFreeBSD_powerpc_h_
-#define liblldb_RegisterContextFreeBSD_powerpc_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H
#include "RegisterInfoInterface.h"
@@ -49,4 +49,4 @@ public:
uint32_t GetRegisterCount() const override;
};
-#endif // liblldb_RegisterContextFreeBSD_powerpc_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_POWERPC_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index bcf3951ee077..c1f390ade9b9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_x86_64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_x86_64.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
index c379e1a5cd75..d0f69fde1817 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextFreeBSD_x86_64_H_
-#define liblldb_RegisterContextFreeBSD_x86_64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTFREEBSD_X86_64_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp
index c19a2bfae668..577958738900 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp
@@ -1,5 +1,4 @@
-//===-- RegisterContextHistory.cpp ---------------------------------*- C++
-//-*-===//
+//===-- RegisterContextHistory.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h
index 952e4263d955..407640d2bdb9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_RegisterContextHistory_h_
-#define lldb_RegisterContextHistory_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H
#include <vector>
@@ -58,8 +58,10 @@ private:
lldb::addr_t m_pc_value;
- DISALLOW_COPY_AND_ASSIGN(RegisterContextHistory);
+ RegisterContextHistory(const RegisterContextHistory &) = delete;
+ const RegisterContextHistory &
+ operator=(const RegisterContextHistory &) = delete;
};
} // namespace lldb_private
-#endif // lldb_RegisterContextHistory_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTHISTORY_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
deleted file mode 100644
index 49a589f14989..000000000000
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ /dev/null
@@ -1,2198 +0,0 @@
-//===-- RegisterContextLLDB.cpp --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/Address.h"
-#include "lldb/Core/AddressRange.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Symbol/ArmUnwindInfo.h"
-#include "lldb/Symbol/CallFrameInfo.h"
-#include "lldb/Symbol/DWARFCallFrameInfo.h"
-#include "lldb/Symbol/FuncUnwinders.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/lldb-private.h"
-
-#include "RegisterContextLLDB.h"
-
-#include <memory>
-
-using namespace lldb;
-using namespace lldb_private;
-
-static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
- if (sym_ctx.symbol)
- return sym_ctx.symbol->GetName();
- else if (sym_ctx.function)
- return sym_ctx.function->GetName();
- return ConstString();
-}
-
-RegisterContextLLDB::RegisterContextLLDB(Thread &thread,
- const SharedPtr &next_frame,
- SymbolContext &sym_ctx,
- uint32_t frame_number,
- UnwindLLDB &unwind_lldb)
- : RegisterContext(thread, frame_number), m_thread(thread),
- m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(),
- m_fallback_unwind_plan_sp(), m_all_registers_available(false),
- m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS),
- m_afa(LLDB_INVALID_ADDRESS), m_start_pc(),
- m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0),
- m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number),
- m_registers(), m_parent_unwind(unwind_lldb) {
- m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
-
- if (IsFrameZero()) {
- InitializeZerothFrame();
- } else {
- InitializeNonZerothFrame();
- }
-
- // This same code exists over in the GetFullUnwindPlanForFrame() but it may
- // not have been executed yet
- if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame ||
- next_frame->m_frame_type == eDebuggerFrame) {
- m_all_registers_available = true;
- }
-}
-
-bool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(
- lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) {
- if (!unwind_plan_sp)
- return false;
-
- // check if m_current_pc is valid
- if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- // yes - current offset can be used as is
- valid_pc_offset = m_current_offset;
- return true;
- }
-
- // if m_current_offset <= 0, we've got nothing else to try
- if (m_current_offset <= 0)
- return false;
-
- // check pc - 1 to see if it's valid
- Address pc_minus_one(m_current_pc);
- pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
- if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
- // *valid_pc_offset = m_current_offset - 1;
- valid_pc_offset = m_current_pc.GetOffset() - 1;
- return true;
- }
-
- return false;
-}
-
-// Initialize a RegisterContextLLDB which is the first frame of a stack -- the
-// zeroth frame or currently executing frame.
-
-void RegisterContextLLDB::InitializeZerothFrame() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
-
- if (reg_ctx_sp.get() == nullptr) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("frame does not have a register context");
- return;
- }
-
- addr_t current_pc = reg_ctx_sp->GetPC();
-
- if (current_pc == LLDB_INVALID_ADDRESS) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("frame does not have a pc");
- return;
- }
-
- Process *process = exe_ctx.GetProcessPtr();
-
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- // (which would be a no-op in frame 0 where we get it from the register set,
- // but still a good idea to make the call here for other ABIs that may
- // exist.)
- ABI *abi = process->GetABI().get();
- if (abi)
- current_pc = abi->FixCodeAddress(current_pc);
-
- // Initialize m_current_pc, an Address object, based on current_pc, an
- // addr_t.
- m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());
-
- // If we don't have a Module for some reason, we're not going to find
- // symbol/function information - just stick in some reasonable defaults and
- // hope we can unwind past this frame.
- ModuleSP pc_module_sp(m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp) {
- UnwindLogMsg("using architectural default unwind method");
- }
-
- AddressRange addr_range;
- m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
-
- if (m_sym_ctx.symbol) {
- UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- } else if (m_sym_ctx.function) {
- UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- } else {
- UnwindLogMsg("with pc value of 0x%" PRIx64
- ", no symbol/function name is known.",
- current_pc);
- }
-
- if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
- m_frame_type = eTrapHandlerFrame;
- } else {
- // FIXME: Detect eDebuggerFrame here.
- m_frame_type = eNormalFrame;
- }
-
- // If we were able to find a symbol/function, set addr_range to the bounds of
- // that symbol/function. else treat the current pc value as the start_pc and
- // record no offset.
- if (addr_range.GetBaseAddress().IsValid()) {
- m_start_pc = addr_range.GetBaseAddress();
- if (m_current_pc.GetSection() == m_start_pc.GetSection()) {
- m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
- } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
- // This means that whatever symbol we kicked up isn't really correct ---
- // we should not cross section boundaries ... We really should NULL out
- // the function/symbol in this case unless there is a bad assumption here
- // due to inlined functions?
- m_current_offset =
- m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
- }
- m_current_offset_backed_up_one = m_current_offset;
- } else {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- }
-
- // We've set m_frame_type and m_sym_ctx before these calls.
-
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
-
- UnwindPlan::RowSP active_row;
- lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
- if (m_full_unwind_plan_sp &&
- m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- active_row =
- m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
- if (active_row.get() && log) {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
- m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg("%s", active_row_strm.GetData());
- }
- }
-
- if (!active_row.get()) {
- UnwindLogMsg("could not find an unwindplan row for this frame's pc");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
- // Try the fall back unwind plan since the
- // full unwind plan failed.
- FuncUnwindersSP func_unwinders_sp;
- UnwindPlanSP call_site_unwind_plan;
- bool cfa_status = false;
-
- if (m_sym_ctx_valid) {
- func_unwinders_sp =
- pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
- m_current_pc, m_sym_ctx);
- }
-
- if (func_unwinders_sp.get() != nullptr)
- call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_thread);
-
- if (call_site_unwind_plan.get() != nullptr) {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- if (TryFallbackUnwindPlan())
- cfa_status = true;
- }
- if (!cfa_status) {
- UnwindLogMsg("could not read CFA value for first frame.");
- m_frame_type = eNotAValidFrame;
- return;
- }
- } else
- ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
-
- UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
- " afa is 0x%" PRIx64 " using %s UnwindPlan",
- (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
- (uint64_t)m_cfa,
- (uint64_t)m_afa,
- m_full_unwind_plan_sp->GetSourceName().GetCString());
-}
-
-// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the
-// RegisterContextLLDB "below" it to provide things like its current pc value.
-
-void RegisterContextLLDB::InitializeNonZerothFrame() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (IsFrameZero()) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that "
- "shouldn't happen.");
- return;
- }
-
- if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("Could not get next frame, marking this frame as invalid.");
- return;
- }
- if (!m_thread.GetRegisterContext()) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("Could not get register context for this thread, marking this "
- "frame as invalid.");
- return;
- }
-
- addr_t pc;
- if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
- UnwindLogMsg("could not get pc value");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- ABI *abi = process->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
-
- if (log) {
- UnwindLogMsg("pc = 0x%" PRIx64, pc);
- addr_t reg_val;
- if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
- UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
- if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
- UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
- }
-
- // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
- // handler function
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
- GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
-
- if (pc == 0 || pc == 0x1) {
- if (!above_trap_handler) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("this frame has a pc of 0x0");
- return;
- }
- }
-
- const bool allow_section_end = true;
- m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end);
-
- // If we don't have a Module for some reason, we're not going to find
- // symbol/function information - just stick in some reasonable defaults and
- // hope we can unwind past this frame.
- ModuleSP pc_module_sp(m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp) {
- UnwindLogMsg("using architectural default unwind method");
-
- // Test the pc value to see if we know it's in an unmapped/non-executable
- // region of memory.
- uint32_t permissions;
- if (process->GetLoadAddressPermissions(pc, permissions) &&
- (permissions & ePermissionsExecutable) == 0) {
- // If this is the second frame off the stack, we may have unwound the
- // first frame incorrectly. But using the architecture default unwind
- // plan may get us back on track -- albeit possibly skipping a real
- // frame. Give this frame a clearly-invalid pc and see if we can get any
- // further.
- if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
- GetNextFrame()->IsFrameZero()) {
- UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable "
- "memory but on frame 1 -- "
- "allowing it once.",
- (uint64_t)pc);
- m_frame_type = eSkipFrame;
- } else {
- // anywhere other than the second frame, a non-executable pc means
- // we're off in the weeds -- stop now.
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("pc is in a non-executable section of memory and this "
- "isn't the 2nd frame in the stack walk.");
- return;
- }
- }
-
- if (abi) {
- m_fast_unwind_plan_sp.reset();
- m_full_unwind_plan_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
- }
- m_all_registers_available = false;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
- UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
- if (row.get()) {
- if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) {
- UnwindLogMsg("failed to get cfa value");
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNotAValidFrame;
- }
- return;
- }
-
- ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa);
-
- // A couple of sanity checks..
- if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) {
- UnwindLogMsg("could not find a valid cfa address");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- // m_cfa should point into the stack memory; if we can query memory
- // region permissions, see if the memory is allocated & readable.
- if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
- (permissions & ePermissionsReadable) == 0) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg(
- "the CFA points to a region of memory that is not readable");
- return;
- }
- } else {
- UnwindLogMsg("could not find a row for function offset zero");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- if (CheckIfLoopingStack()) {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack()) {
- UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
- "looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
- }
-
- UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
- (uint64_t)m_cfa, (uint64_t)m_afa);
- return;
- }
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("could not find any symbol for this pc, or a default unwind "
- "plan, to continue unwind.");
- return;
- }
-
- AddressRange addr_range;
- m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
-
- if (m_sym_ctx.symbol) {
- UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
- GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- } else if (m_sym_ctx.function) {
- UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc,
- GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- } else {
- UnwindLogMsg("with pc value of 0x%" PRIx64
- ", no symbol/function name is known.",
- pc);
- }
-
- bool decr_pc_and_recompute_addr_range;
-
- if (!m_sym_ctx_valid) {
- // Always decrement and recompute if the symbol lookup failed
- decr_pc_and_recompute_addr_range = true;
- } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
- GetNextFrame()->m_frame_type == eDebuggerFrame) {
- // Don't decrement if we're "above" an asynchronous event like
- // sigtramp.
- decr_pc_and_recompute_addr_range = false;
- } else if (!addr_range.GetBaseAddress().IsValid() ||
- addr_range.GetBaseAddress().GetSection() != m_current_pc.GetSection() ||
- addr_range.GetBaseAddress().GetOffset() != m_current_pc.GetOffset()) {
- // If our "current" pc isn't the start of a function, no need
- // to decrement and recompute.
- decr_pc_and_recompute_addr_range = false;
- } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
- // Signal dispatch may set the return address of the handler it calls to
- // point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
- // so do not decrement and recompute if the symbol we already found is a trap
- // handler.
- decr_pc_and_recompute_addr_range = false;
- } else {
- // Decrement to find the function containing the call.
- decr_pc_and_recompute_addr_range = true;
- }
-
- // We need to back up the pc by 1 byte and re-search for the Symbol to handle
- // the case where the "saved pc" value is pointing to the next function, e.g.
- // if a function ends with a CALL instruction.
- // FIXME this may need to be an architectural-dependent behavior; if so we'll
- // need to add a member function
- // to the ABI plugin and consult that.
- if (decr_pc_and_recompute_addr_range) {
- UnwindLogMsg("Backing up the pc value of 0x%" PRIx64
- " by 1 and re-doing symbol lookup; old symbol was %s",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- Address temporary_pc;
- temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
- m_sym_ctx.Clear(false);
- m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
-
- UnwindLogMsg("Symbol is now %s",
- GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
-
- // If we were able to find a symbol/function, set addr_range_ptr to the
- // bounds of that symbol/function. else treat the current pc value as the
- // start_pc and record no offset.
- if (addr_range.GetBaseAddress().IsValid()) {
- m_start_pc = addr_range.GetBaseAddress();
- m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
- m_current_offset_backed_up_one = m_current_offset;
- if (decr_pc_and_recompute_addr_range &&
- m_current_offset_backed_up_one > 0) {
- m_current_offset_backed_up_one--;
- if (m_sym_ctx_valid) {
- m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
- }
- }
- } else {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- }
-
- if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
- m_frame_type = eTrapHandlerFrame;
- } else {
- // FIXME: Detect eDebuggerFrame here.
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
- }
- }
-
- // We've set m_frame_type and m_sym_ctx before this call.
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
-
- UnwindPlan::RowSP active_row;
- RegisterKind row_register_kind = eRegisterKindGeneric;
-
- // Try to get by with just the fast UnwindPlan if possible - the full
- // UnwindPlan may be expensive to get (e.g. if we have to parse the entire
- // eh_frame section of an ObjectFile for the first time.)
-
- if (m_fast_unwind_plan_sp &&
- m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- active_row =
- m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
- PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
- if (active_row.get() && log) {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
- m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg("active row: %s", active_row_strm.GetData());
- }
- } else {
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
- PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
- if (active_row.get() && log) {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
- &m_thread,
- m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg("active row: %s", active_row_strm.GetData());
- }
- }
- }
-
- if (!active_row.get()) {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg("could not find unwind row for this pc");
- return;
- }
-
- if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
- UnwindLogMsg("failed to get cfa");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
-
- UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa);
-
- if (CheckIfLoopingStack()) {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack()) {
- UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
- "looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
- }
-
- UnwindLogMsg("initialized frame current pc is 0x%" PRIx64
- " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
- (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
- (uint64_t)m_cfa,
- (uint64_t)m_afa);
-}
-
-bool RegisterContextLLDB::CheckIfLoopingStack() {
- // If we have a bad stack setup, we can get the same CFA value multiple times
- // -- or even more devious, we can actually oscillate between two CFA values.
- // Detect that here and break out to avoid a possible infinite loop in lldb
- // trying to unwind the stack. To detect when we have the same CFA value
- // multiple times, we compare the
- // CFA of the current
- // frame with the 2nd next frame because in some specail case (e.g. signal
- // hanlders, hand written assembly without ABI compiance) we can have 2
- // frames with the same
- // CFA (in theory we
- // can have arbitrary number of frames with the same CFA, but more then 2 is
- // very very unlikely)
-
- RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
- if (next_frame) {
- RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
- addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
- if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
- if (next_next_frame_cfa == m_cfa) {
- // We have a loop in the stack unwind
- return true;
- }
- }
- }
- return false;
-}
-
-bool RegisterContextLLDB::IsFrameZero() const { return m_frame_number == 0; }
-
-// Find a fast unwind plan for this frame, if possible.
-//
-// On entry to this method,
-//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
-// if either of those are correct,
-// 2. m_sym_ctx should already be filled in, and
-// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into
-// the function, maybe backed up by 1, -1 if unknown
-
-UnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame() {
- UnwindPlanSP unwind_plan_sp;
- ModuleSP pc_module_sp(m_current_pc.GetModule());
-
- if (!m_current_pc.IsValid() || !pc_module_sp ||
- pc_module_sp->GetObjectFile() == nullptr)
- return unwind_plan_sp;
-
- if (IsFrameZero())
- return unwind_plan_sp;
-
- FuncUnwindersSP func_unwinders_sp(
- pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
- m_current_pc, m_sym_ctx));
- if (!func_unwinders_sp)
- return unwind_plan_sp;
-
- // If we're in _sigtramp(), unwinding past this frame requires special
- // knowledge.
- if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
- return unwind_plan_sp;
-
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
- *m_thread.CalculateTarget(), m_thread);
- if (unwind_plan_sp) {
- if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose()) {
- if (m_fast_unwind_plan_sp)
- UnwindLogMsgVerbose("frame, and has a fast UnwindPlan");
- else
- UnwindLogMsgVerbose("frame");
- }
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- } else {
- unwind_plan_sp.reset();
- }
- }
- return unwind_plan_sp;
-}
-
-// On entry to this method,
-//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
-// if either of those are correct,
-// 2. m_sym_ctx should already be filled in, and
-// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into
-// the function, maybe backed up by 1, -1 if unknown
-
-UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
- UnwindPlanSP unwind_plan_sp;
- UnwindPlanSP arch_default_unwind_plan_sp;
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- ABI *abi = process ? process->GetABI().get() : nullptr;
- if (abi) {
- arch_default_unwind_plan_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
- } else {
- UnwindLogMsg(
- "unable to get architectural default UnwindPlan from ABI plugin");
- }
-
- bool behaves_like_zeroth_frame = false;
- if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
- GetNextFrame()->m_frame_type == eDebuggerFrame) {
- behaves_like_zeroth_frame = true;
- // If this frame behaves like a 0th frame (currently executing or
- // interrupted asynchronously), all registers can be retrieved.
- m_all_registers_available = true;
- }
-
- // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
- // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first
- // instruction" arch default UnwindPlan Also, if this Process can report on
- // memory region attributes, any non-executable region means we jumped
- // through a bad function pointer - handle the same way as 0x0. Note, if we
- // have a symbol context & a symbol, we don't want to follow this code path.
- // This is for jumping to memory regions without any information available.
-
- if ((!m_sym_ctx_valid ||
- (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) &&
- behaves_like_zeroth_frame && m_current_pc.IsValid()) {
- uint32_t permissions;
- addr_t current_pc_addr =
- m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr());
- if (current_pc_addr == 0 ||
- (process &&
- process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
- (permissions & ePermissionsExecutable) == 0)) {
- if (abi) {
- unwind_plan_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- }
- }
- }
-
- // No Module for the current pc, try using the architecture default unwind.
- ModuleSP pc_module_sp(m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp ||
- pc_module_sp->GetObjectFile() == nullptr) {
- m_frame_type = eNormalFrame;
- return arch_default_unwind_plan_sp;
- }
-
- FuncUnwindersSP func_unwinders_sp;
- if (m_sym_ctx_valid) {
- func_unwinders_sp =
- pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
- m_current_pc, m_sym_ctx);
- }
-
- // No FuncUnwinders available for this pc (stripped function symbols, lldb
- // could not augment its function table with another source, like
- // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the
- // .ARM.exidx tables have unwind information for this address, else fall back
- // to the architectural default unwind.
- if (!func_unwinders_sp) {
- m_frame_type = eNormalFrame;
-
- if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
- !m_current_pc.IsValid())
- return arch_default_unwind_plan_sp;
-
- // Even with -fomit-frame-pointer, we can try eh_frame to get back on
- // track.
- DWARFCallFrameInfo *eh_frame =
- pc_module_sp->GetUnwindTable().GetEHFrameInfo();
- if (eh_frame) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- ArmUnwindInfo *arm_exidx =
- pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
- if (arm_exidx) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
- *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- CallFrameInfo *object_file_unwind =
- pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
- if (object_file_unwind) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- return arch_default_unwind_plan_sp;
- }
-
- // If we're in _sigtramp(), unwinding past this frame requires special
- // knowledge. On Mac OS X this knowledge is properly encoded in the eh_frame
- // section, so prefer that if available. On other platforms we may need to
- // provide a platform-specific UnwindPlan which encodes the details of how to
- // unwind out of sigtramp.
- if (m_frame_type == eTrapHandlerFrame && process) {
- m_fast_unwind_plan_sp.reset();
- unwind_plan_sp =
- func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
- if (!unwind_plan_sp)
- unwind_plan_sp =
- func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
- unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
- return unwind_plan_sp;
- }
- }
-
- // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
- // even when it's frame zero This comes up if we have hand-written functions
- // in a Module and hand-written eh_frame. The assembly instruction
- // inspection may fail and the eh_frame CFI were probably written with some
- // care to do the right thing. It'd be nice if there was a way to ask the
- // eh_frame directly if it is asynchronous (can be trusted at every
- // instruction point) or synchronous (the normal case - only at call sites).
- // But there is not.
- if (process && process->GetDynamicLoader() &&
- process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
- // We must specifically call the GetEHFrameUnwindPlan() method here --
- // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
- // return an unwind plan sourced from either eh_frame (that's what we
- // intend) or compact unwind (this won't work)
- unwind_plan_sp =
- func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
- if (!unwind_plan_sp)
- unwind_plan_sp =
- func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
- "DynamicLoader suggested we prefer it",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
- }
-
- // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
- // the assembly language instructions
- if (behaves_like_zeroth_frame && process) {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
- process->GetTarget(), m_thread);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
- if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
- // We probably have an UnwindPlan created by inspecting assembly
- // instructions. The assembly profilers work really well with compiler-
- // generated functions but hand- written assembly can be problematic.
- // We set the eh_frame based unwind plan as our fallback unwind plan if
- // instruction emulation doesn't work out even for non call sites if it
- // is available and use the architecture default unwind plan if it is
- // not available. The eh_frame unwind plan is more reliable even on non
- // call sites then the architecture default plan and for hand written
- // assembly code it is often written in a way that it valid at all
- // location what helps in the most common cases when the instruction
- // emulation fails.
- UnwindPlanSP call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
- m_thread);
- if (call_site_unwind_plan &&
- call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() !=
- unwind_plan_sp->GetSourceName()) {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- } else {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
- }
- }
- UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this "
- "is the non-call site unwind plan and this is a "
- "zeroth frame",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
-
- // If we're on the first instruction of a function, and we have an
- // architectural default UnwindPlan for the initial instruction of a
- // function, use that.
- if (m_current_offset == 0) {
- unwind_plan_sp =
- func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
- m_thread);
- if (unwind_plan_sp) {
- UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we are at "
- "the first instruction of a function",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
- }
- }
-
- // Typically this is unwind info from an eh_frame section intended for
- // exception handling; only valid at call sites
- if (process) {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_thread);
- }
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
- UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because this "
- "is the call-site unwind plan",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
-
- // We'd prefer to use an UnwindPlan intended for call sites when we're at a
- // call site but if we've struck out on that, fall back to using the non-
- // call-site assembly inspection UnwindPlan if possible.
- if (process) {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
- process->GetTarget(), m_thread);
- }
- if (unwind_plan_sp &&
- unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
- // We probably have an UnwindPlan created by inspecting assembly
- // instructions. The assembly profilers work really well with compiler-
- // generated functions but hand- written assembly can be problematic. We
- // set the eh_frame based unwind plan as our fallback unwind plan if
- // instruction emulation doesn't work out even for non call sites if it is
- // available and use the architecture default unwind plan if it is not
- // available. The eh_frame unwind plan is more reliable even on non call
- // sites then the architecture default plan and for hand written assembly
- // code it is often written in a way that it valid at all location what
- // helps in the most common cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
- m_thread);
- if (call_site_unwind_plan &&
- call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() !=
- unwind_plan_sp->GetSourceName()) {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- } else {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
- }
- }
-
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
- UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because we "
- "failed to find a call-site unwind plan that would work",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
-
- // If nothing else, use the architectural default UnwindPlan and hope that
- // does the job.
- if (arch_default_unwind_plan_sp)
- UnwindLogMsgVerbose(
- "frame uses %s for full UnwindPlan because we are falling back "
- "to the arch default plan",
- arch_default_unwind_plan_sp->GetSourceName().GetCString());
- else
- UnwindLogMsg(
- "Unable to find any UnwindPlan for full unwind of this frame.");
-
- return arch_default_unwind_plan_sp;
-}
-
-void RegisterContextLLDB::InvalidateAllRegisters() {
- m_frame_type = eNotAValidFrame;
-}
-
-size_t RegisterContextLLDB::GetRegisterCount() {
- return m_thread.GetRegisterContext()->GetRegisterCount();
-}
-
-const RegisterInfo *RegisterContextLLDB::GetRegisterInfoAtIndex(size_t reg) {
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
-}
-
-size_t RegisterContextLLDB::GetRegisterSetCount() {
- return m_thread.GetRegisterContext()->GetRegisterSetCount();
-}
-
-const RegisterSet *RegisterContextLLDB::GetRegisterSet(size_t reg_set) {
- return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
-}
-
-uint32_t RegisterContextLLDB::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
- kind, num);
-}
-
-bool RegisterContextLLDB::ReadRegisterValueFromRegisterLocation(
- lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!IsValid())
- return false;
- bool success = false;
-
- switch (regloc.type) {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
- const RegisterInfo *other_reg_info =
- GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- success =
- m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
- } break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
- const RegisterInfo *other_reg_info =
- GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- if (IsFrameZero()) {
- success =
- m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
- } else {
- success = GetNextFrame()->ReadRegister(other_reg_info, value);
- }
- } break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- success =
- value.SetUInt(regloc.location.inferred_value, reg_info->byte_size);
- break;
-
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- llvm_unreachable("FIXME debugger inferior function call unwind");
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
- Status error(ReadRegisterValueFromMemory(
- reg_info, regloc.location.target_memory_location, reg_info->byte_size,
- value));
- success = error.Success();
- } break;
- default:
- llvm_unreachable("Unknown RegisterLocation type.");
- }
- return success;
-}
-
-bool RegisterContextLLDB::WriteRegisterValueToRegisterLocation(
- lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info, const RegisterValue &value) {
- if (!IsValid())
- return false;
-
- bool success = false;
-
- switch (regloc.type) {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
- const RegisterInfo *other_reg_info =
- GetRegisterInfoAtIndex(regloc.location.register_number);
- success =
- m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
- } break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
- const RegisterInfo *other_reg_info =
- GetRegisterInfoAtIndex(regloc.location.register_number);
- if (IsFrameZero()) {
- success =
- m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
- } else {
- success = GetNextFrame()->WriteRegister(other_reg_info, value);
- }
- } break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- llvm_unreachable("FIXME debugger inferior function call unwind");
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
- Status error(WriteRegisterValueToMemory(
- reg_info, regloc.location.target_memory_location, reg_info->byte_size,
- value));
- success = error.Success();
- } break;
- default:
- llvm_unreachable("Unknown RegisterLocation type.");
- }
- return success;
-}
-
-bool RegisterContextLLDB::IsValid() const {
- return m_frame_type != eNotAValidFrame;
-}
-
-// After the final stack frame in a stack walk we'll get one invalid
-// (eNotAValidFrame) stack frame -- one past the end of the stack walk. But
-// higher-level code will need to tell the differnece between "the unwind plan
-// below this frame failed" versus "we successfully completed the stack walk"
-// so this method helps to disambiguate that.
-
-bool RegisterContextLLDB::IsTrapHandlerFrame() const {
- return m_frame_type == eTrapHandlerFrame;
-}
-
-// A skip frame is a bogus frame on the stack -- but one where we're likely to
-// find a real frame farther
-// up the stack if we keep looking. It's always the second frame in an unwind
-// (i.e. the first frame after frame zero) where unwinding can be the
-// trickiest. Ideally we'll mark up this frame in some way so the user knows
-// we're displaying bad data and we may have skipped one frame of their real
-// program in the process of getting back on track.
-
-bool RegisterContextLLDB::IsSkipFrame() const {
- return m_frame_type == eSkipFrame;
-}
-
-bool RegisterContextLLDB::IsTrapHandlerSymbol(
- lldb_private::Process *process,
- const lldb_private::SymbolContext &m_sym_ctx) const {
- PlatformSP platform_sp(process->GetTarget().GetPlatform());
- if (platform_sp) {
- const std::vector<ConstString> trap_handler_names(
- platform_sp->GetTrapHandlerSymbolNames());
- for (ConstString name : trap_handler_names) {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
- return true;
- }
- }
- }
- const std::vector<ConstString> user_specified_trap_handler_names(
- m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
- for (ConstString name : user_specified_trap_handler_names) {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
- return true;
- }
- }
-
- return false;
-}
-
-// Answer the question: Where did THIS frame save the CALLER frame ("previous"
-// frame)'s register value?
-
-enum UnwindLLDB::RegisterSearchResult
-RegisterContextLLDB::SavedLocationForRegister(
- uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc) {
- RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
-
- // Have we already found this register location?
- if (!m_registers.empty()) {
- std::map<uint32_t,
- lldb_private::UnwindLLDB::RegisterLocation>::const_iterator
- iterator;
- iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB));
- if (iterator != m_registers.end()) {
- regloc = iterator->second;
- UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
- // Look through the available UnwindPlans for the register location.
-
- UnwindPlan::Row::RegisterLocation unwindplan_regloc;
- bool have_unwindplan_regloc = false;
- RegisterKind unwindplan_registerkind = kNumRegisterKinds;
-
- if (m_fast_unwind_plan_sp) {
- UnwindPlan::RowSP active_row =
- m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind();
- if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
- UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind "
- "reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
- (int)unwindplan_registerkind);
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
- unwindplan_regloc)) {
- UnwindLogMsg(
- "supplying caller's saved %s (%d)'s location using FastUnwindPlan",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- have_unwindplan_regloc = true;
- }
- }
-
- if (!have_unwindplan_regloc) {
- // m_full_unwind_plan_sp being NULL means that we haven't tried to find a
- // full UnwindPlan yet
- if (!m_full_unwind_plan_sp)
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
-
- if (m_full_unwind_plan_sp) {
- RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC);
-
- UnwindPlan::RowSP active_row =
- m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
-
- RegisterNumber return_address_reg;
-
- // If we're fetching the saved pc and this UnwindPlan defines a
- // ReturnAddress register (e.g. lr on arm), look for the return address
- // register number in the UnwindPlan's row.
- if (pc_regnum.IsValid() && pc_regnum == regnum &&
- m_full_unwind_plan_sp->GetReturnAddressRegister() !=
- LLDB_INVALID_REGNUM) {
-
- return_address_reg.init(
- m_thread, m_full_unwind_plan_sp->GetRegisterKind(),
- m_full_unwind_plan_sp->GetReturnAddressRegister());
- regnum = return_address_reg;
- UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a "
- "RA reg; getting %s (%d) instead",
- return_address_reg.GetName(),
- return_address_reg.GetAsKind(eRegisterKindLLDB));
- } else {
- if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
- if (unwindplan_registerkind == eRegisterKindGeneric) {
- UnwindLogMsg("could not convert lldb regnum %s (%d) into "
- "eRegisterKindGeneric reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- } else {
- UnwindLogMsg("could not convert lldb regnum %s (%d) into %d "
- "RegisterKind reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
- (int)unwindplan_registerkind);
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- }
-
- if (regnum.IsValid() &&
- active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
- unwindplan_regloc)) {
- have_unwindplan_regloc = true;
- UnwindLogMsg(
- "supplying caller's saved %s (%d)'s location using %s UnwindPlan",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
- m_full_unwind_plan_sp->GetSourceName().GetCString());
- }
-
- // This is frame 0 and we're retrieving the PC and it's saved in a Return
- // Address register and it hasn't been saved anywhere yet -- that is,
- // it's still live in the actual register. Handle this specially.
-
- if (!have_unwindplan_regloc && return_address_reg.IsValid() &&
- IsFrameZero()) {
- if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
- LLDB_INVALID_REGNUM) {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type =
- UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number =
- return_address_reg.GetAsKind(eRegisterKindLLDB);
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg("supplying caller's register %s (%d) from the live "
- "RegisterContext at frame 0, saved in %d",
- return_address_reg.GetName(),
- return_address_reg.GetAsKind(eRegisterKindLLDB),
- return_address_reg.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
- // If this architecture stores the return address in a register (it
- // defines a Return Address register) and we're on a non-zero stack frame
- // and the Full UnwindPlan says that the pc is stored in the
- // RA registers (e.g. lr on arm), then we know that the full unwindplan is
- // not trustworthy -- this
- // is an impossible situation and the instruction emulation code has
- // likely been misled. If this stack frame meets those criteria, we need
- // to throw away the Full UnwindPlan that the instruction emulation came
- // up with and fall back to the architecture's Default UnwindPlan so the
- // stack walk can get past this point.
-
- // Special note: If the Full UnwindPlan was generated from the compiler,
- // don't second-guess it when we're at a call site location.
-
- // arch_default_ra_regnum is the return address register # in the Full
- // UnwindPlan register numbering
- RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_RA);
-
- if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) !=
- LLDB_INVALID_REGNUM &&
- pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() &&
- unwindplan_regloc.GetRegisterNumber() ==
- arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) &&
- m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes &&
- !m_all_registers_available) {
- UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link "
- "register but this is a non-zero frame",
- m_full_unwind_plan_sp->GetSourceName().GetCString());
-
- // Throw away the full unwindplan; install the arch default unwindplan
- if (ForceSwitchToFallbackUnwindPlan()) {
- // Update for the possibly new unwind plan
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
- UnwindPlan::RowSP active_row =
- m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
-
- // Sanity check: Verify that we can fetch a pc value and CFA value
- // with this unwind plan
-
- RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC);
- bool can_fetch_pc_value = false;
- bool can_fetch_cfa = false;
- addr_t cfa_value;
- if (active_row) {
- if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) !=
- LLDB_INVALID_REGNUM &&
- active_row->GetRegisterInfo(
- arch_default_pc_reg.GetAsKind(unwindplan_registerkind),
- unwindplan_regloc)) {
- can_fetch_pc_value = true;
- }
- if (ReadFrameAddress(unwindplan_registerkind,
- active_row->GetCFAValue(), cfa_value)) {
- can_fetch_cfa = true;
- }
- }
-
- have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa;
- } else {
- // We were unable to fall back to another unwind plan
- have_unwindplan_regloc = false;
- }
- }
- }
- }
-
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- if (!have_unwindplan_regloc) {
- // If the UnwindPlan failed to give us an unwind location for this
- // register, we may be able to fall back to some ABI-defined default. For
- // example, some ABIs allow to determine the caller's SP via the CFA. Also,
- // the ABI may set volatile registers to the undefined state.
- ABI *abi = process ? process->GetABI().get() : nullptr;
- if (abi) {
- const RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB));
- if (reg_info &&
- abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) {
- UnwindLogMsg(
- "supplying caller's saved %s (%d)'s location using ABI default",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- have_unwindplan_regloc = true;
- }
- }
- }
-
- if (!have_unwindplan_regloc) {
- if (IsFrameZero()) {
- // This is frame 0 - we should return the actual live register context
- // value
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type =
- UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg("supplying caller's register %s (%d) from the live "
- "RegisterContext at frame 0",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- } else {
- std::string unwindplan_name("");
- if (m_full_unwind_plan_sp) {
- unwindplan_name += "via '";
- unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
- unwindplan_name += "'";
- }
- UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(),
- regnum.GetAsKind(eRegisterKindLLDB),
- unwindplan_name.c_str());
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- // unwindplan_regloc has valid contents about where to retrieve the register
- if (unwindplan_regloc.IsUnspecified()) {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
- UnwindLogMsg("save location for %s (%d) is unspecified, continue searching",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- if (unwindplan_regloc.IsUndefined()) {
- UnwindLogMsg(
- "did not supply reg location for %s (%d) because it is volatile",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
- }
-
- if (unwindplan_regloc.IsSame()) {
- if (!IsFrameZero() &&
- (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC ||
- regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) {
- UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or "
- "return address reg on a non-zero frame -- treat as if we "
- "have no information",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- } else {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg(
- "supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
- if (unwindplan_regloc.IsCFAPlusOffset()) {
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = m_cfa + offset;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus "
- "offset %d [value is 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
- regloc.location.inferred_value);
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsAtCFAPlusOffset()) {
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = m_cfa + offset;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
- "CFA plus offset %d [saved at 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
- regloc.location.target_memory_location);
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsAFAPlusOffset()) {
- if (m_afa == LLDB_INVALID_ADDRESS)
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
-
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = m_afa + offset;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus "
- "offset %d [value is 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
- regloc.location.inferred_value);
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsAtAFAPlusOffset()) {
- if (m_afa == LLDB_INVALID_ADDRESS)
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
-
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = m_afa + offset;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
- "AFA plus offset %d [saved at 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
- regloc.location.target_memory_location);
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsInOtherRegister()) {
- uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
- RegisterNumber row_regnum(m_thread, unwindplan_registerkind,
- unwindplan_regnum);
- if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) {
- UnwindLogMsg("could not supply caller's %s (%d) location - was saved in "
- "another reg but couldn't convert that regnum",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB);
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg(
- "supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
- row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsDWARFExpression() ||
- unwindplan_regloc.IsAtDWARFExpression()) {
- DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(),
- unwindplan_regloc.GetDWARFExpressionLength(),
- process->GetByteOrder(),
- process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.SetRegisterKind(unwindplan_registerkind);
- Value cfa_val = Scalar(m_cfa);
- cfa_val.SetValueType(Value::eValueTypeLoadAddress);
- Value result;
- Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
- &error)) {
- addr_t val;
- val = result.GetScalar().ULongLong();
- if (unwindplan_regloc.IsDWARFExpression()) {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = val;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
- "(IsDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- } else {
- regloc.type =
- UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = val;
- m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
- UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
- "(IsAtDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
- UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s "
- "(%d) but failed",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- UnwindLogMsg("no save location for %s (%d) in this stack frame",
- regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
-
- // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are
- // unsupported.
-
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
-}
-
-// TryFallbackUnwindPlan() -- this method is a little tricky.
-//
-// When this is called, the frame above -- the caller frame, the "previous"
-// frame -- is invalid or bad.
-//
-// Instead of stopping the stack walk here, we'll try a different UnwindPlan
-// and see if we can get a valid frame above us.
-//
-// This most often happens when an unwind plan based on assembly instruction
-// inspection is not correct -- mostly with hand-written assembly functions or
-// functions where the stack frame is set up "out of band", e.g. the kernel
-// saved the register context and then called an asynchronous trap handler like
-// _sigtramp.
-//
-// Often in these cases, if we just do a dumb stack walk we'll get past this
-// tricky frame and our usual techniques can continue to be used.
-
-bool RegisterContextLLDB::TryFallbackUnwindPlan() {
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
- m_full_unwind_plan_sp->GetSourceName() ==
- m_fallback_unwind_plan_sp->GetSourceName()) {
- return false;
- }
-
- // If a compiler generated unwind plan failed, trying the arch default
- // unwindplan isn't going to do any better.
- if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
- return false;
-
- // Get the caller's pc value and our own CFA value. Swap in the fallback
- // unwind plan, re-fetch the caller's pc value and CFA value. If they're the
- // same, then the fallback unwind plan provides no benefit.
-
- RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC);
-
- addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
- addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
- UnwindLLDB::RegisterLocation regloc;
- if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
- regloc) ==
- UnwindLLDB::RegisterSearchResult::eRegisterFound) {
- const RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
- if (reg_info) {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
- old_caller_pc_value = reg_value.GetAsUInt64();
- }
- }
- }
-
- // This is a tricky wrinkle! If SavedLocationForRegister() detects a really
- // impossible register location for the full unwind plan, it may call
- // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full
- // unwindplan with the fallback... in short, we're done, we're using the
- // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr
- // at the top -- the only way it became nullptr since then is via
- // SavedLocationForRegister().
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return true;
-
- // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide
- // this isn't working, we need to restore. We'll also need to save & restore
- // the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
- UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
- addr_t old_cfa = m_cfa;
- addr_t old_afa = m_afa;
-
- m_registers.clear();
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
-
- UnwindPlan::RowSP active_row =
- m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
-
- if (active_row &&
- active_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::FAValue::unspecified) {
- addr_t new_cfa;
- if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetCFAValue(), new_cfa) ||
- new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
- UnwindLogMsg("failed to get cfa with fallback unwindplan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- return false;
- }
- m_cfa = new_cfa;
-
- ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetAFAValue(), m_afa);
-
- if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
- regloc) ==
- UnwindLLDB::RegisterSearchResult::eRegisterFound) {
- const RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
- if (reg_info) {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
- reg_value)) {
- new_caller_pc_value = reg_value.GetAsUInt64();
- }
- }
- }
-
- if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
- UnwindLogMsg("failed to get a pc value for the caller frame with the "
- "fallback unwind plan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- m_afa = old_afa;
- return false;
- }
-
- if (old_caller_pc_value == new_caller_pc_value &&
- m_cfa == old_cfa &&
- m_afa == old_afa) {
- UnwindLogMsg("fallback unwind plan got the same values for this frame "
- "CFA and caller frame pc, not using");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- return false;
- }
-
- UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
- "because UnwindPlan '%s' failed.",
- m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
- original_full_unwind_plan_sp->GetSourceName().GetCString());
-
- // We've copied the fallback unwind plan into the full - now clear the
- // fallback.
- m_fallback_unwind_plan_sp.reset();
- PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
- }
-
- return true;
-}
-
-bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
- m_full_unwind_plan_sp->GetSourceName() ==
- m_fallback_unwind_plan_sp->GetSourceName()) {
- return false;
- }
-
- UnwindPlan::RowSP active_row =
- m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
-
- if (active_row &&
- active_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::FAValue::unspecified) {
- addr_t new_cfa;
- if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetCFAValue(), new_cfa) ||
- new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
- UnwindLogMsg("failed to get cfa with fallback unwindplan");
- m_fallback_unwind_plan_sp.reset();
- return false;
- }
-
- ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetAFAValue(), m_afa);
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
- m_fallback_unwind_plan_sp.reset();
-
- m_registers.clear();
-
- m_cfa = new_cfa;
-
- PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
-
- UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
- m_full_unwind_plan_sp->GetSourceName().GetCString());
- return true;
- }
- return false;
-}
-
-void RegisterContextLLDB::PropagateTrapHandlerFlagFromUnwindPlan(
- lldb::UnwindPlanSP unwind_plan) {
- if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
- // Unwind plan does not indicate trap handler. Do nothing. We may
- // already be flagged as trap handler flag due to the symbol being
- // in the trap handler symbol list, and that should take precedence.
- return;
- } else if (m_frame_type != eNormalFrame) {
- // If this is already a trap handler frame, nothing to do.
- // If this is a skip or debug or invalid frame, don't override that.
- return;
- }
-
- m_frame_type = eTrapHandlerFrame;
-
- if (m_current_offset_backed_up_one != m_current_offset) {
- // We backed up the pc by 1 to compute the symbol context, but
- // now need to undo that because the pc of the trap handler
- // frame may in fact be the first instruction of a signal return
- // trampoline, rather than the instruction after a call. This
- // happens on systems where the signal handler dispatch code, rather
- // than calling the handler and being returned to, jumps to the
- // handler after pushing the address of a return trampoline on the
- // stack -- on these systems, when the handler returns, control will
- // be transferred to the return trampoline, so that's the best
- // symbol we can present in the callstack.
- UnwindLogMsg("Resetting current offset and re-doing symbol lookup; "
- "old symbol was %s",
- GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- m_current_offset_backed_up_one = m_current_offset;
-
- AddressRange addr_range;
- m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
-
- UnwindLogMsg("Symbol is now %s",
- GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
-
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- Target *target = &process->GetTarget();
-
- m_start_pc = addr_range.GetBaseAddress();
- m_current_offset =
- m_current_pc.GetLoadAddress(target) - m_start_pc.GetLoadAddress(target);
- }
-}
-
-bool RegisterContextLLDB::ReadFrameAddress(
- lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
- addr_t &address) {
- RegisterValue reg_value;
-
- address = LLDB_INVALID_ADDRESS;
- addr_t cfa_reg_contents;
-
- switch (fa.GetValueType()) {
- case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
- RegisterNumber cfa_reg(m_thread, row_register_kind,
- fa.GetRegisterNumber());
- if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
- const RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
- RegisterValue reg_value;
- if (reg_info) {
- Status error = ReadRegisterValueFromMemory(
- reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
- if (error.Success()) {
- address = reg_value.GetAsUInt64();
- UnwindLogMsg(
- "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
- ", CFA value is 0x%" PRIx64,
- cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents, address);
- return true;
- } else {
- UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64
- "] but memory read failed.",
- cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents);
- }
- }
- }
- break;
- }
- case UnwindPlan::Row::FAValue::isRegisterPlusOffset: {
- RegisterNumber cfa_reg(m_thread, row_register_kind,
- fa.GetRegisterNumber());
- if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
- if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
- cfa_reg_contents == 1) {
- UnwindLogMsg(
- "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
- cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents);
- cfa_reg_contents = LLDB_INVALID_ADDRESS;
- return false;
- }
- address = cfa_reg_contents + fa.GetOffset();
- UnwindLogMsg(
- "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64
- ", offset is %d",
- address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents, fa.GetOffset());
- return true;
- }
- break;
- }
- case UnwindPlan::Row::FAValue::isDWARFExpression: {
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(),
- fa.GetDWARFExpressionLength(),
- process->GetByteOrder(),
- process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
- dwarfexpr.SetRegisterKind(row_register_kind);
- Value result;
- Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
- &error)) {
- address = result.GetScalar().ULongLong();
-
- UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
- address);
- return true;
- }
- UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
- error.AsCString());
- break;
- }
- case UnwindPlan::Row::FAValue::isRaSearch: {
- Process &process = *m_thread.GetProcess();
- lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset());
- if (return_address_hint == LLDB_INVALID_ADDRESS)
- return false;
- const unsigned max_iterations = 256;
- for (unsigned i = 0; i < max_iterations; ++i) {
- Status st;
- lldb::addr_t candidate_addr =
- return_address_hint + i * process.GetAddressByteSize();
- lldb::addr_t candidate =
- process.ReadPointerFromMemory(candidate_addr, st);
- if (st.Fail()) {
- UnwindLogMsg("Cannot read memory at 0x%" PRIx64 ": %s", candidate_addr,
- st.AsCString());
- return false;
- }
- Address addr;
- uint32_t permissions;
- if (process.GetLoadAddressPermissions(candidate, permissions) &&
- permissions & lldb::ePermissionsExecutable) {
- address = candidate_addr;
- UnwindLogMsg("Heuristically found CFA: 0x%" PRIx64, address);
- return true;
- }
- }
- UnwindLogMsg("No suitable CFA found");
- break;
- }
- default:
- return false;
- }
- return false;
-}
-
-lldb::addr_t RegisterContextLLDB::GetReturnAddressHint(int32_t plan_offset) {
- addr_t hint;
- if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint))
- return LLDB_INVALID_ADDRESS;
- if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
- return LLDB_INVALID_ADDRESS;
-
- hint += plan_offset;
-
- if (auto next = GetNextFrame()) {
- if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
- return LLDB_INVALID_ADDRESS;
- if (auto expected_size =
- next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
- *next->m_sym_ctx.symbol))
- hint += *expected_size;
- else {
- UnwindLogMsgVerbose("Could not retrieve parameter size: %s",
- llvm::toString(expected_size.takeError()).c_str());
- return LLDB_INVALID_ADDRESS;
- }
- }
- return hint;
-}
-
-// Retrieve a general purpose register value for THIS frame, as saved by the
-// NEXT frame, i.e. the frame that
-// this frame called. e.g.
-//
-// foo () { }
-// bar () { foo (); }
-// main () { bar (); }
-//
-// stopped in foo() so
-// frame 0 - foo
-// frame 1 - bar
-// frame 2 - main
-// and this RegisterContext is for frame 1 (bar) - if we want to get the pc
-// value for frame 1, we need to ask
-// where frame 0 (the "next" frame) saved that and retrieve the value.
-
-bool RegisterContextLLDB::ReadGPRValue(lldb::RegisterKind register_kind,
- uint32_t regnum, addr_t &value) {
- if (!IsValid())
- return false;
-
- uint32_t lldb_regnum;
- if (register_kind == eRegisterKindLLDB) {
- lldb_regnum = regnum;
- } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
- register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) {
- return false;
- }
-
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
- RegisterValue reg_value;
- // if this is frame 0 (currently executing frame), get the requested reg
- // contents from the actual thread registers
- if (IsFrameZero()) {
- if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
- value = reg_value.GetAsUInt64();
- return true;
- }
- return false;
- }
-
- bool pc_register = false;
- uint32_t generic_regnum;
- if (register_kind == eRegisterKindGeneric &&
- (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
- pc_register = true;
- } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
- register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
- (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
- generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
- pc_register = true;
- }
-
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- if (!m_parent_unwind.SearchForSavedLocationForRegister(
- lldb_regnum, regloc, m_frame_number - 1, pc_register)) {
- return false;
- }
- if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
- value = reg_value.GetAsUInt64();
- return true;
- }
- return false;
-}
-
-bool RegisterContextLLDB::ReadGPRValue(const RegisterNumber &regnum,
- addr_t &value) {
- return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(),
- value);
-}
-
-// Find the value of a register in THIS frame
-
-bool RegisterContextLLDB::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &value) {
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose("looking for register saved location for reg %d",
- lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero()) {
- UnwindLogMsgVerbose("passing along to the live register context for reg %d",
- lldb_regnum);
- return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
- }
-
- bool is_pc_regnum = false;
- if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC ||
- reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) {
- is_pc_regnum = true;
- }
-
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister(
- lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
- return false;
-
- return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
-}
-
-bool RegisterContextLLDB::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &value) {
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose("looking for register saved location for reg %d",
- lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero()) {
- UnwindLogMsgVerbose("passing along to the live register context for reg %d",
- lldb_regnum);
- return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
- }
-
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister(
- lldb_regnum, regloc, m_frame_number - 1, false))
- return false;
-
- return WriteRegisterValueToRegisterLocation(regloc, reg_info, value);
-}
-
-// Don't need to implement this one
-bool RegisterContextLLDB::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
- return false;
-}
-
-// Don't need to implement this one
-bool RegisterContextLLDB::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- return false;
-}
-
-// Retrieve the pc value for THIS from
-
-bool RegisterContextLLDB::GetCFA(addr_t &cfa) {
- if (!IsValid()) {
- return false;
- }
- if (m_cfa == LLDB_INVALID_ADDRESS) {
- return false;
- }
- cfa = m_cfa;
- return true;
-}
-
-RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetNextFrame() const {
- RegisterContextLLDB::SharedPtr regctx;
- if (m_frame_number == 0)
- return regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1);
-}
-
-RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetPrevFrame() const {
- RegisterContextLLDB::SharedPtr regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1);
-}
-
-// Retrieve the address of the start of the function of THIS frame
-
-bool RegisterContextLLDB::GetStartPC(addr_t &start_pc) {
- if (!IsValid())
- return false;
-
- if (!m_start_pc.IsValid()) {
- bool read_successfully = ReadPC (start_pc);
- if (read_successfully)
- {
- ProcessSP process_sp (m_thread.GetProcess());
- if (process_sp)
- {
- ABI *abi = process_sp->GetABI().get();
- if (abi)
- start_pc = abi->FixCodeAddress(start_pc);
- }
- }
- return read_successfully;
- }
- start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get());
- return true;
-}
-
-// Retrieve the current pc value for THIS frame, as saved by the NEXT frame.
-
-bool RegisterContextLLDB::ReadPC(addr_t &pc) {
- if (!IsValid())
- return false;
-
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
- GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
-
- if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
- // A pc value of 0 or 1 is impossible in the middle of the stack -- it
- // indicates the end of a stack walk.
- // On the currently executing frame (or such a frame interrupted
- // asynchronously by sigtramp et al) this may occur if code has jumped
- // through a NULL pointer -- we want to be able to unwind past that frame
- // to help find the bug.
-
- ProcessSP process_sp (m_thread.GetProcess());
- if (process_sp)
- {
- ABI *abi = process_sp->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
- }
-
- return !(m_all_registers_available == false &&
- above_trap_handler == false && (pc == 0 || pc == 1));
- } else {
- return false;
- }
-}
-
-void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log) {
- va_list args;
- va_start(args, fmt);
-
- char *logmsg;
- if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) {
- if (logmsg)
- free(logmsg);
- va_end(args);
- return;
- }
- va_end(args);
-
- LLDB_LOGF(log, "%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "",
- m_thread.GetIndexID(), m_frame_number, logmsg);
- free(logmsg);
- }
-}
-
-void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose()) {
- va_list args;
- va_start(args, fmt);
-
- char *logmsg;
- if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == nullptr) {
- if (logmsg)
- free(logmsg);
- va_end(args);
- return;
- }
- va_end(args);
-
- LLDB_LOGF(log, "%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "",
- m_thread.GetIndexID(), m_frame_number, logmsg);
- free(logmsg);
- }
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
deleted file mode 100644
index 114ac35591e7..000000000000
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ /dev/null
@@ -1,259 +0,0 @@
-//===-- RegisterContextLLDB.h --------------------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_RegisterContextLLDB_h_
-#define lldb_RegisterContextLLDB_h_
-
-#include <vector>
-
-#include "UnwindLLDB.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/RegisterNumber.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class UnwindLLDB;
-
-class RegisterContextLLDB : public lldb_private::RegisterContext {
-public:
- typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
-
- RegisterContextLLDB(lldb_private::Thread &thread, const SharedPtr &next_frame,
- lldb_private::SymbolContext &sym_ctx,
- uint32_t frame_number,
- lldb_private::UnwindLLDB &unwind_lldb);
-
- ~RegisterContextLLDB() override = default;
-
- void InvalidateAllRegisters() override;
-
- size_t GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
- bool IsValid() const;
-
- bool IsTrapHandlerFrame() const;
-
- bool GetCFA(lldb::addr_t &cfa);
-
- bool GetStartPC(lldb::addr_t &start_pc);
-
- bool ReadPC(lldb::addr_t &start_pc);
-
-private:
- enum FrameType {
- eNormalFrame,
- eTrapHandlerFrame,
- eDebuggerFrame, // a debugger inferior function call frame; we get caller's
- // registers from debugger
- eSkipFrame, // The unwind resulted in a bogus frame but may get back on
- // track so we don't want to give up yet
- eNotAValidFrame // this frame is invalid for some reason - most likely it is
- // past the top (end) of the stack
- };
-
- // UnwindLLDB needs to pass around references to RegisterLocations
- friend class UnwindLLDB;
-
- // Returns true if we have an unwind loop -- the same stack frame unwinding
- // multiple times.
- bool CheckIfLoopingStack();
-
- // Indicates whether this frame is frame zero -- the currently
- // executing frame -- or not.
- bool IsFrameZero() const;
-
- void InitializeZerothFrame();
-
- void InitializeNonZerothFrame();
-
- SharedPtr GetNextFrame() const;
-
- SharedPtr GetPrevFrame() const;
-
- // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've
- // got one bogus frame at frame #1.
- // There is a good chance we'll get back on track if we follow the frame
- // pointer chain (or whatever is appropriate
- // on this ABI) so we allow one invalid frame to be in the stack. Ideally
- // we'll mark this frame specially at some
- // point and indicate to the user that the unwinder had a hiccup. Often when
- // this happens we will miss a frame of
- // the program's actual stack in the unwind and we want to flag that for the
- // user somehow.
- bool IsSkipFrame() const;
-
- /// Determines if a SymbolContext is a trap handler or not
- ///
- /// Given a SymbolContext, determines if this is a trap handler function
- /// aka asynchronous signal handler.
- ///
- /// \return
- /// Returns true if the SymbolContext is a trap handler.
- bool IsTrapHandlerSymbol(lldb_private::Process *process,
- const lldb_private::SymbolContext &m_sym_ctx) const;
-
- /// Check if the given unwind plan indicates a signal trap handler, and
- /// update frame type and symbol context if so.
- void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
-
- // Provide a location for where THIS function saved the CALLER's register
- // value
- // Or a frame "below" this one saved it, i.e. a function called by this one,
- // preserved a register that this
- // function didn't modify/use.
- //
- // The RegisterLocation type may be set to eRegisterNotAvailable -- this will
- // happen for a volatile register
- // being queried mid-stack. Instead of floating frame 0's contents of that
- // register up the stack (which may
- // or may not be the value of that reg when the function was executing), we
- // won't return any value.
- //
- // If a non-volatile register (a "preserved" register) is requested mid-stack
- // and no frames "below" the requested
- // stack have saved the register anywhere, it is safe to assume that frame 0's
- // register values are still the same
- // as the requesting frame's.
- lldb_private::UnwindLLDB::RegisterSearchResult
- SavedLocationForRegister(uint32_t lldb_regnum,
- lldb_private::UnwindLLDB::RegisterLocation &regloc);
-
- bool ReadRegisterValueFromRegisterLocation(
- lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegisterValueToRegisterLocation(
- lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- /// If the unwind has to the caller frame has failed, try something else
- ///
- /// If lldb is using an assembly language based UnwindPlan for a frame and
- /// the unwind to the caller frame fails, try falling back to a generic
- /// UnwindPlan (architecture default unwindplan) to see if that might work
- /// better. This is mostly helping to work around problems where the
- /// assembly language inspection fails on hand-written assembly code.
- ///
- /// \return
- /// Returns true if a fallback unwindplan was found & was installed.
- bool TryFallbackUnwindPlan();
-
- /// Switch to the fallback unwind plan unconditionally without any safety
- /// checks that it is providing better results than the normal unwind plan.
- ///
- /// The only time it is valid to call this method is if the full unwindplan is
- /// found to be fundamentally incorrect/impossible.
- ///
- /// Returns true if it was able to install the fallback unwind plan.
- bool ForceSwitchToFallbackUnwindPlan();
-
- // Get the contents of a general purpose (address-size) register for this
- // frame
- // (usually retrieved from the next frame)
- bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum,
- lldb::addr_t &value);
-
- bool ReadGPRValue(const RegisterNumber &reg_num, lldb::addr_t &value);
-
- // Get the Frame Address register for a given frame.
- bool ReadFrameAddress(lldb::RegisterKind register_kind,
- UnwindPlan::Row::FAValue &fa, lldb::addr_t &address);
-
- lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
-
- lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
-
- void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
-
- void UnwindLogMsgVerbose(const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
-
- bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
- int &valid_pc_offset);
-
- lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
-
- lldb_private::Thread &m_thread;
-
- ///
- // The following tell us how to retrieve the CALLER's register values (ie the
- // "previous" frame, aka the frame above)
- // i.e. where THIS frame saved them
- ///
-
- lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
- lldb::UnwindPlanSP m_full_unwind_plan_sp;
- lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
-
- bool m_all_registers_available; // Can we retrieve all regs or just
- // nonvolatile regs?
- int m_frame_type; // enum FrameType
-
- lldb::addr_t m_cfa;
- lldb::addr_t m_afa;
- lldb_private::Address m_start_pc;
- lldb_private::Address m_current_pc;
-
- int m_current_offset; // how far into the function we've executed; -1 if
- // unknown
- // 0 if no instructions have been executed yet.
-
- int m_current_offset_backed_up_one; // how far into the function we've
- // executed; -1 if unknown
- // 0 if no instructions have been executed yet.
- // On architectures where the return address on the stack points
- // to the instruction after the CALL, this value will have 1
- // subtracted from it. Else a function that ends in a CALL will
- // have an offset pointing into the next function's address range.
- // m_current_pc has the actual address of the "current" pc.
-
- lldb_private::SymbolContext &m_sym_ctx;
- bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to
- // use m_sym_ctx
-
- uint32_t m_frame_number; // What stack frame this RegisterContext is
-
- std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>
- m_registers; // where to find reg values for this frame
-
- lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating
- // this RegisterContextLLDB
-
- // For RegisterContextLLDB only
-
- DISALLOW_COPY_AND_ASSIGN(RegisterContextLLDB);
-};
-
-} // namespace lldb_private
-
-#endif // lldb_RegisterContextLLDB_h_
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index 79979639dc7e..518dc273faf4 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_i386.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_i386.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index 5567a1ac42e5..ef731a5a7994 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_i386_H_
-#define liblldb_RegisterContextLinux_i386_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
index fc60fea79176..837549e2a495 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_mips.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_mips.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
index e637dfc15e4d..9b59ab421ff4 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_mips_H_
-#define liblldb_RegisterContextLinux_mips_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
#include "RegisterInfoInterface.h"
#include "lldb/lldb-private.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
index 3927883c47a4..432a78129fde 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_mips64.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
index ca0f0140a22d..899f0a40e4ae 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_mips64_H_
-#define liblldb_RegisterContextLinux_mips64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
#include "RegisterInfoInterface.h"
#include "lldb/lldb-private.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
index d6401d788ab2..7a8989cd1225 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_s390x.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_s390x.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
index 10810c97af80..f381f38ecbf9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_s390x_h_
-#define liblldb_RegisterContextLinux_s390x_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_S390X_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 640d5bc02256..f9d4e23fcde2 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_x86_64.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_x86_64.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index 02f273cb02c9..ea21b913d5c5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_x86_64_H_
-#define liblldb_RegisterContextLinux_x86_64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
deleted file mode 100644
index bc78c1d6160c..000000000000
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextMacOSXFrameBackchain.h"
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/StringExtractorGDBRemote.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// RegisterContextMacOSXFrameBackchain constructor
-RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
- Thread &thread, uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor)
- : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
- m_cursor_is_valid(true) {}
-
-// Destructor
-RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
-
-void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
- m_cursor_is_valid = false;
-}
-
-size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
- return m_thread.GetRegisterContext()->GetRegisterCount();
-}
-
-const RegisterInfo *
-RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
-}
-
-size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
- return m_thread.GetRegisterContext()->GetRegisterSetCount();
-}
-
-const RegisterSet *
-RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
- return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
-}
-
-bool RegisterContextMacOSXFrameBackchain::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!m_cursor_is_valid)
- return false;
-
- uint64_t reg_value = LLDB_INVALID_ADDRESS;
-
- switch (reg_info->kinds[eRegisterKindGeneric]) {
- case LLDB_REGNUM_GENERIC_PC:
- if (m_cursor.pc == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.pc;
- break;
-
- case LLDB_REGNUM_GENERIC_FP:
- if (m_cursor.fp == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.fp;
- break;
-
- default:
- return false;
- }
-
- switch (reg_info->encoding) {
- case eEncodingInvalid:
- case eEncodingVector:
- break;
-
- case eEncodingUint:
- case eEncodingSint:
- value.SetUInt(reg_value, reg_info->byte_size);
- return true;
-
- case eEncodingIEEE754:
- switch (reg_info->byte_size) {
- case sizeof(float):
- if (sizeof(float) == sizeof(uint32_t)) {
- value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
- return true;
- } else if (sizeof(float) == sizeof(uint64_t)) {
- value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
- return true;
- }
- break;
-
- case sizeof(double):
- if (sizeof(double) == sizeof(uint32_t)) {
- value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
- return true;
- } else if (sizeof(double) == sizeof(uint64_t)) {
- value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
- return true;
- }
- break;
-
-// TOOD: need a better way to detect when "long double" types are
-// the same bytes size as "double"
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
- !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
- !defined(__ANDROID__)
- case sizeof(long double):
- if (sizeof(long double) == sizeof(uint32_t)) {
- value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- } else if (sizeof(long double) == sizeof(uint64_t)) {
- value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- }
- break;
-#endif
- }
- break;
- }
- return false;
-}
-
-bool RegisterContextMacOSXFrameBackchain::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &value) {
- // Not supported yet. We could easily add support for this by remembering the
- // address of each entry (it would need to be part of the cursor)
- return false;
-}
-
-bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- // libunwind frames can't handle this it doesn't always have all register
- // values. This call should only be called on frame zero anyway so there
- // shouldn't be any problem
- return false;
-}
-
-bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
- // have been the one that saved all the register values. So we just let the
- // thread's register context (the register context for frame zero) do the
- // writing.
- return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
-}
-
-uint32_t
-RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
- kind, num);
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
deleted file mode 100644
index 36e5538daa8a..000000000000
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- RegisterContextMacOSXFrameBackchain.h -------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_RegisterContextMacOSXFrameBackchain_h_
-#define lldb_RegisterContextMacOSXFrameBackchain_h_
-
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/lldb-private.h"
-
-#include "UnwindMacOSXFrameBackchain.h"
-
-class RegisterContextMacOSXFrameBackchain
- : public lldb_private::RegisterContext {
-public:
- RegisterContextMacOSXFrameBackchain(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor);
-
- ~RegisterContextMacOSXFrameBackchain() override;
-
- void InvalidateAllRegisters() override;
-
- size_t GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
-private:
- UnwindMacOSXFrameBackchain::Cursor m_cursor;
- bool m_cursor_is_valid;
-
- DISALLOW_COPY_AND_ASSIGN(RegisterContextMacOSXFrameBackchain);
-};
-
-#endif // lldb_RegisterContextMacOSXFrameBackchain_h_
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index c7042ab5137a..1394cb7f00a1 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMach_arm.cpp -----------------------------*- C++ -*-===//
+//===-- RegisterContextMach_arm.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index 8b2425a193be..e7c180dbdd27 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMach_arm_h_
-#define liblldb_RegisterContextMach_arm_h_
-
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H
#include "RegisterContextDarwin_arm.h"
@@ -37,4 +36,4 @@ protected:
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
};
-#endif // liblldb_RegisterContextMach_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index e631ab9bb26c..b97166b6eebe 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMach_i386.cpp ----------------------------*- C++ -*-===//
+//===-- RegisterContextMach_i386.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index b8835561e98c..09966be60c92 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMach_i386_h_
-#define liblldb_RegisterContextMach_i386_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H
#include "RegisterContextDarwin_i386.h"
@@ -32,4 +32,4 @@ protected:
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_i386_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index db17d7d88778..8933f136789f 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMach_x86_64.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextMach_x86_64.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index 688009aef8af..2a8a2cca2f8a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMach_x86_64_h_
-#define liblldb_RegisterContextMach_x86_64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H
#include "RegisterContextDarwin_x86_64.h"
@@ -33,4 +33,4 @@ protected:
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_x86_64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index 946d4fa9f8e5..f2d230b54053 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===//
+//===-- RegisterContextMemory.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h
index 68223eaeffd7..764ee9b97211 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_RegisterContextMemory_h_
-#define lldb_RegisterContextMemory_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H
#include <vector>
@@ -67,7 +67,9 @@ protected:
// context that is stored in memmory
private:
- DISALLOW_COPY_AND_ASSIGN(RegisterContextMemory);
+ RegisterContextMemory(const RegisterContextMemory &) = delete;
+ const RegisterContextMemory &
+ operator=(const RegisterContextMemory &) = delete;
};
-#endif // lldb_RegisterContextMemory_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMEMORY_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp
new file mode 100644
index 000000000000..bd7830e42b42
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp
@@ -0,0 +1,96 @@
+//===-- RegisterContextNetBSD_i386.cpp -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#include "RegisterContextNetBSD_i386.h"
+#include "RegisterContextPOSIX_x86.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// this needs to match 'struct reg'
+struct GPR {
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+};
+
+struct FPR_i386 {
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint16_t ftag; // FPU Tag Word (ftw)
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union {
+ struct {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
+ // cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
+ uint32_t padding[56];
+};
+
+struct UserArea {
+ GPR gpr;
+ FPR_i386 i387;
+ uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+ uint32_t tlsbase;
+};
+
+#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
+
+// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
+#define DECLARE_REGISTER_INFOS_I386_STRUCT
+#include "RegisterInfos_i386.h"
+#undef DECLARE_REGISTER_INFOS_I386_STRUCT
+
+RegisterContextNetBSD_i386::RegisterContextNetBSD_i386(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
+
+size_t RegisterContextNetBSD_i386::GetGPRSize() const { return sizeof(GPR); }
+
+const RegisterInfo *RegisterContextNetBSD_i386::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+}
+
+uint32_t RegisterContextNetBSD_i386::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0]));
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h
new file mode 100644
index 000000000000..742bb18b8306
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h
@@ -0,0 +1,25 @@
+//===-- RegisterContextNetBSD_i386.h ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_I386_H
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextNetBSD_i386 : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterContextNetBSD_i386(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+};
+
+#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
index e620ff66c922..21aad92ecda8 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextNetBSD_x86_64.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextNetBSD_x86_64.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "RegisterContextNetBSD_x86_64.h"
+#include "RegisterContextNetBSD_i386.h"
#include "RegisterContextPOSIX_x86.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
@@ -83,9 +84,40 @@ struct UserArea {
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
+static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {
+ static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ return g_register_infos;
+}
+
+static const RegisterInfo *
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+ std::vector<lldb_private::RegisterInfo> &g_register_infos =
+ GetPrivateRegisterInfoVector();
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextNetBSD_i386> reg_interface(
+ new RegisterContextNetBSD_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
+
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+// with x86_64 offsets.
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
+}
+
static const RegisterInfo *
PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386(target_arch);
case llvm::Triple::x86_64:
return g_register_infos_x86_64;
default:
@@ -97,6 +129,11 @@ PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
static uint32_t
PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86: {
+ assert(!GetPrivateRegisterInfoVector().empty() &&
+ "i386 register info not yet filled.");
+ return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());
+ }
case llvm::Triple::x86_64:
return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
sizeof(g_register_infos_x86_64[0]));
@@ -106,11 +143,25 @@ PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
}
}
+static uint32_t
+PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t>(k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(
const ArchSpec &target_arch)
: lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
- m_register_count(PrivateGetRegisterCount(target_arch)) {}
+ m_register_count(PrivateGetRegisterCount(target_arch)),
+ m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {}
size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
@@ -121,3 +172,7 @@ const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const {
uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const {
return m_register_count;
}
+
+uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const {
+ return m_user_register_count;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
index 4820ef8d17ba..b7b8d33b7c37 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextNetBSD_x86_64_H_
-#define liblldb_RegisterContextNetBSD_x86_64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTNETBSD_X86_64_H
#include "RegisterInfoInterface.h"
@@ -22,9 +22,12 @@ public:
uint32_t GetRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
const uint32_t m_register_count;
+ const uint32_t m_user_register_count;
};
#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp
index 06eac6f7f991..7183ffcfd0f6 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextOpenBSD_i386.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextOpenBSD_i386.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h
index 992ce0959fdf..e6e24525b7fd 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextOpenBSD_i386_H_
-#define liblldb_RegisterContextOpenBSD_i386_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_I386_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp
index e210196d921d..05c1f83efded 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextOpenBSD_x86_64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextOpenBSD_x86_64.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h
index 9c76e7211132..b399c721546a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextOpenBSD_x86_64_H_
-#define liblldb_RegisterContextOpenBSD_x86_64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTOPENBSD_X86_64_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 821e2aa73b5b..617893b6b3b0 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_arm.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_arm.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -178,35 +178,6 @@ const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder RegisterContextPOSIX_arm::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
return set_index < k_num_register_sets;
}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const lldb_private::RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index 603ba76430e6..d6967f05ed48 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_arm_h_
-#define liblldb_RegisterContextPOSIX_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H
#include "RegisterInfoInterface.h"
#include "lldb-arm-register-enums.h"
@@ -44,9 +44,6 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
protected:
struct RegInfo {
uint32_t num_registers;
@@ -95,12 +92,10 @@ protected:
bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
-
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index db1aa1b8b093..8ef587f13e3a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_arm64.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_arm64.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,105 +25,25 @@
using namespace lldb;
using namespace lldb_private;
-// ARM64 general purpose registers.
-const uint32_t g_gpr_regnums_arm64[] = {
- gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
- gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
- gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
- gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
- gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
- gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
- gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
- gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
- gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
- gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
- gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
- gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
- gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
- gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
- gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
- gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
- 1) == k_num_gpr_registers_arm64,
- "g_gpr_regnums_arm64 has wrong number of register infos");
-
-// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] = {
- fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
- fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
- fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
- fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
- fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
- fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
- fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
- fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
- fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
- fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
- fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
- fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
- fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
- fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
- fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
- fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
-
- fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
- fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
- fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
- fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
- fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
- fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
- fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
- fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
- fpu_fpsr_arm64, fpu_fpcr_arm64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
- 1) == k_num_fpr_registers_arm64,
- "g_fpu_regnums_arm64 has wrong number of register infos");
-
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 2 };
-
-// Register sets for ARM64.
-static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
- g_gpr_regnums_arm64},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
- g_fpu_regnums_arm64}};
-
bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) {
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm64::GPRegSet)
+ return true;
+ return false;
}
bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm64::FPRegSet)
+ return true;
+ return false;
}
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx) {
- m_register_info_up.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
+ : lldb_private::RegisterContext(thread, 0),
+ m_register_info_up(std::move(register_info)) {
::memset(&m_fpr, 0, sizeof m_fpr);
}
@@ -135,19 +55,15 @@ void RegisterContextPOSIX_arm64::Invalidate() {}
void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {}
unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_offset;
}
unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_size;
}
size_t RegisterContextPOSIX_arm64::GetRegisterCount() {
- size_t num_registers =
- m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+ return m_register_info_up->GetRegisterCount();
}
size_t RegisterContextPOSIX_arm64::GetGPRSize() {
@@ -164,71 +80,23 @@ RegisterContextPOSIX_arm64::GetRegisterInfo() {
const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) {
- if (reg < m_reg_info.num_registers)
+ if (reg < GetRegisterCount())
return &GetRegisterInfo()[reg];
else
return nullptr;
}
size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() {
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set) {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+ return m_register_info_up->GetRegisterSetCount();
}
const lldb_private::RegisterSet *
RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) {
- if (IsRegisterSetAvailable(set)) {
- switch (m_register_info_up->m_target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- return &g_reg_sets_arm64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
- }
- return nullptr;
+ return m_register_info_up->GetRegisterSet(set);
}
const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
-}
-
-lldb::ByteOrder RegisterContextPOSIX_arm64::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
-bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) {
- return set_index < k_num_register_sets;
-}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const lldb_private::RegisterInfo *reg_info =
- GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
+ if (reg < GetRegisterCount())
+ return GetRegisterInfo()[reg].name;
+ return nullptr;
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index 49a49b69da6b..c2d5aee7f73c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -6,10 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_arm64_h_
-#define liblldb_RegisterContextPOSIX_arm64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H
#include "RegisterInfoInterface.h"
+#include "RegisterInfoPOSIX_arm64.h"
#include "lldb-arm64-register-enums.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
@@ -19,8 +20,8 @@ class ProcessMonitor;
class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_arm64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info);
~RegisterContextPOSIX_arm64() override;
@@ -44,50 +45,15 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
protected:
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit
// general
// purpose
// registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm64::FPU
- m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface>
- m_register_info_up; // Register Info Interface (FreeBSD or Linux)
- // Determines if an extended register set is supported on the processor
- // running the inferior process.
- virtual bool IsRegisterSetAvailable(size_t set_index);
+ struct RegisterInfoPOSIX_arm64::FPU
+ m_fpr; // floating-point registers including extended register sets.
+ std::unique_ptr<RegisterInfoPOSIX_arm64> m_register_info_up;
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
@@ -95,7 +61,7 @@ protected:
bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
+ size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
@@ -103,4 +69,4 @@ protected:
virtual bool WriteFPR() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_arm64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM64_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index f1fa3035b2ef..c41c4bd7a7ea 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_mips64.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_mips64.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -149,17 +149,6 @@ const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) {
return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
size_t num_sets = GetRegisterSetCount();
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index c507e14bd5b6..1843a2a6aff3 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_mips64_h_
-#define liblldb_RegisterContextPOSIX_mips64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H
#include "RegisterContext_mips.h"
#include "RegisterInfoInterface.h"
@@ -73,12 +73,10 @@ protected:
bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
-
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_mips64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_MIPS64_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index a78e9ed37947..cd65b96d373e 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -1,5 +1,4 @@
-//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++
-//-*-===//
+//===-- RegisterContextPOSIX_powerpc.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -158,36 +157,8 @@ const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) {
return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder RegisterContextPOSIX_powerpc::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) {
size_t num_sets = k_num_register_sets;
return (set_index < num_sets);
}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 1a21a717b22b..e2c33461c8f1 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_powerpc_h_
-#define liblldb_RegisterContextPOSIX_powerpc_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H
#include "RegisterContext_powerpc.h"
#include "RegisterInfoInterface.h"
@@ -165,9 +165,6 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
protected:
uint64_t
m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
@@ -189,8 +186,6 @@ protected:
bool IsVMX(unsigned reg);
- lldb::ByteOrder GetByteOrder();
-
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool ReadVMX() = 0;
@@ -199,4 +194,4 @@ protected:
virtual bool WriteVMX() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_powerpc_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_POWERPC_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
index 02546c0ed16f..f670be2ef3c4 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===//
+//===-- RegisterContextPOSIX_ppc64le.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -176,36 +176,8 @@ const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) {
return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) {
size_t num_sets = k_num_register_sets;
return (set_index < num_sets);
}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_ppc64le::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
index 37079775a3c7..66794ec9e9ca 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_ppc64le_h_
-#define liblldb_RegisterContextPOSIX_ppc64le_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H
#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
#include "RegisterInfoInterface.h"
@@ -39,9 +39,6 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
protected:
// 64-bit general purpose registers.
uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le];
@@ -71,7 +68,6 @@ protected:
bool IsVSX(unsigned reg);
- lldb::ByteOrder GetByteOrder();
};
-#endif // liblldb_RegisterContextPOSIX_ppc64le_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_PPC64LE_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index e040e5075721..e746ec642b38 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_s390x.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -161,31 +161,3 @@ const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) {
}
return nullptr;
}
-
-lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index 54993ce6c3ec..7df732d13ffa 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_s390x_h_
-#define liblldb_RegisterContextPOSIX_s390x_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H
#include "RegisterContext_s390x.h"
#include "RegisterInfoInterface.h"
@@ -43,9 +43,6 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
protected:
struct RegInfo {
uint32_t num_registers;
@@ -68,12 +65,10 @@ protected:
bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
-
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_s390x_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_S390X_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 4d5991f08f1d..ac271a90d6a1 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_x86.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -456,17 +456,6 @@ const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {
return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
// Parse ymm registers and into xmm.bytes and ymmh.bytes.
bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
lldb::ByteOrder byte_order) {
@@ -509,20 +498,3 @@ bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
++num_sets;
return (set_index < num_sets);
}
-
-// Used when parsing DWARF and EH frame information and any other object file
-// sections that contain register numbers in them.
-uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index 932f97bb567f..c4886ae618a2 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextPOSIX_x86_h_
-#define liblldb_RegisterContextPOSIX_x86_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H
#include "RegisterContext_x86.h"
#include "RegisterInfoInterface.h"
@@ -47,9 +47,6 @@ public:
const char *GetRegisterName(unsigned reg);
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
// Note: prefer kernel definitions over user-land
enum FPRType {
eNotValid = 0,
@@ -160,8 +157,6 @@ protected:
bool IsAVX(unsigned reg);
- lldb::ByteOrder GetByteOrder();
-
bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
bool IsFPR(unsigned reg, FPRType fpr_type);
@@ -173,4 +168,4 @@ protected:
virtual bool WriteFPR() = 0;
};
-#endif // liblldb_RegisterContextPOSIX_x86_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
index bcf60cc7a338..31e2944084ed 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextThreadMemory.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
index 09a679ab2c9f..40688a502a66 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_RegisterContextThreadMemory_h_
-#define lldb_RegisterContextThreadMemory_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H
#include <vector>
@@ -92,9 +92,11 @@ protected:
uint32_t m_stop_id;
private:
- DISALLOW_COPY_AND_ASSIGN(RegisterContextThreadMemory);
+ RegisterContextThreadMemory(const RegisterContextThreadMemory &) = delete;
+ const RegisterContextThreadMemory &
+ operator=(const RegisterContextThreadMemory &) = delete;
};
} // namespace lldb_private
-#endif // lldb_RegisterContextThreadMemory_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTTHREADMEMORY_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
index 916d3233cde5..11556e802e33 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextWindows_i386.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextWindows_i386.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
index 7779cc357526..6a5d3524300d 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextWindows_i386_H_
-#define liblldb_RegisterContextWindows_i386_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_I386_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
index e90584de1a44..4ffc4d25781c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextWindows_x86_64.cpp -----------------------*- C++ -*-===//
+//===-- RegisterContextWindows_x86_64.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
index 18198b5b25b3..c29acf284841 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextWindows_x86_64_H_
-#define liblldb_RegisterContextWindows_x86_64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTWINDOWS_X86_64_H
#include "RegisterInfoInterface.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h b/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h
index 7780be51baad..15081f974c66 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContext_mips.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContext_mips64_H_
-#define liblldb_RegisterContext_mips64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H
#include <cstddef>
#include <cstdint>
@@ -371,4 +371,4 @@ struct UserArea {
MSA_linux_mips msa; // MSA registers.
};
-#endif // liblldb_RegisterContext_mips64_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_MIPS_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h
index 1ffcbeb5ec48..7407e2f402e0 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContext_powerpc_H_
-#define liblldb_RegisterContext_powerpc_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H
// eh_frame and DWARF Register numbers (eRegisterKindEHFrame &
// eRegisterKindDWARF)
@@ -120,4 +120,4 @@ enum {
dwarf_v31_powerpc,
};
-#endif // liblldb_RegisterContext_powerpc_H_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_POWERPC_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h
index 2cf39e9eb8e2..248b3bd0beac 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContext_s390x_h_
-#define liblldb_RegisterContext_s390x_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_S390X_H
// SystemZ ehframe, dwarf regnums
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
index 2b79f778aa56..27a1bad4d53f 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContext_x86_H_
-#define liblldb_RegisterContext_x86_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H
#include <cstddef>
#include <cstdint>
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h
new file mode 100644
index 000000000000..7e569dc9ba78
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoAndSetInterface.h
@@ -0,0 +1,36 @@
+//===-- RegisterInfoAndSetInterface.h ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOANDSETINTERFACE_H
+
+#include "RegisterInfoInterface.h"
+
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/lldb-private-types.h"
+#include <vector>
+
+namespace lldb_private {
+
+class RegisterInfoAndSetInterface : public RegisterInfoInterface {
+public:
+ RegisterInfoAndSetInterface(const lldb_private::ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
+
+ virtual size_t GetFPRSize() const = 0;
+
+ virtual const lldb_private::RegisterSet *
+ GetRegisterSet(size_t reg_set) const = 0;
+
+ virtual size_t GetRegisterSetCount() const = 0;
+
+ virtual size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const = 0;
+};
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 4b58e749adce..88c2ae7c5010 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_RegisterInfoInterface_h
-#define lldb_RegisterInfoInterface_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOINTERFACE_H
#include "lldb/Utility/ArchSpec.h"
#include "lldb/lldb-private-types.h"
@@ -61,7 +61,6 @@ public:
return nullptr;
}
-public:
// FIXME make private.
lldb_private::ArchSpec m_target_arch;
};
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
index d392d3be1c41..8fc4d5282b06 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterInfoPOSIX_arm.cpp ------------------------------*- C++ -*-===//
+//===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
index 39c2047600aa..1cf896e3decf 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterInfoPOSIX_arm_h_
-#define liblldb_RegisterInfoPOSIX_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
#include "RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
@@ -58,4 +58,4 @@ private:
uint32_t m_register_info_count;
};
-#endif // liblldb_RegisterInfoPOSIX_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 8b367bdc6448..4537cee42ad9 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterInfoPOSIX_arm64.cpp ----------------------------*- C++ -*-===//
+//===-- RegisterInfoPOSIX_arm64.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -65,6 +65,82 @@ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
}
}
+// Number of register sets provided by this context.
+enum {
+ k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
+ k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
+ k_num_register_sets = 2
+};
+
+// ARM64 general purpose registers.
+static const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0, gpr_x1, gpr_x2, gpr_x3,
+ gpr_x4, gpr_x5, gpr_x6, gpr_x7,
+ gpr_x8, gpr_x9, gpr_x10, gpr_x11,
+ gpr_x12, gpr_x13, gpr_x14, gpr_x15,
+ gpr_x16, gpr_x17, gpr_x18, gpr_x19,
+ gpr_x20, gpr_x21, gpr_x22, gpr_x23,
+ gpr_x24, gpr_x25, gpr_x26, gpr_x27,
+ gpr_x28, gpr_fp, gpr_lr, gpr_sp,
+ gpr_pc, gpr_cpsr, gpr_w0, gpr_w1,
+ gpr_w2, gpr_w3, gpr_w4, gpr_w5,
+ gpr_w6, gpr_w7, gpr_w8, gpr_w9,
+ gpr_w10, gpr_w11, gpr_w12, gpr_w13,
+ gpr_w14, gpr_w15, gpr_w16, gpr_w17,
+ gpr_w18, gpr_w19, gpr_w20, gpr_w21,
+ gpr_w22, gpr_w23, gpr_w24, gpr_w25,
+ gpr_w26, gpr_w27, gpr_w28, LLDB_INVALID_REGNUM};
+
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers,
+ "g_gpr_regnums_arm64 has wrong number of register infos");
+
+// ARM64 floating point registers.
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0, fpu_v1, fpu_v2,
+ fpu_v3, fpu_v4, fpu_v5,
+ fpu_v6, fpu_v7, fpu_v8,
+ fpu_v9, fpu_v10, fpu_v11,
+ fpu_v12, fpu_v13, fpu_v14,
+ fpu_v15, fpu_v16, fpu_v17,
+ fpu_v18, fpu_v19, fpu_v20,
+ fpu_v21, fpu_v22, fpu_v23,
+ fpu_v24, fpu_v25, fpu_v26,
+ fpu_v27, fpu_v28, fpu_v29,
+ fpu_v30, fpu_v31, fpu_s0,
+ fpu_s1, fpu_s2, fpu_s3,
+ fpu_s4, fpu_s5, fpu_s6,
+ fpu_s7, fpu_s8, fpu_s9,
+ fpu_s10, fpu_s11, fpu_s12,
+ fpu_s13, fpu_s14, fpu_s15,
+ fpu_s16, fpu_s17, fpu_s18,
+ fpu_s19, fpu_s20, fpu_s21,
+ fpu_s22, fpu_s23, fpu_s24,
+ fpu_s25, fpu_s26, fpu_s27,
+ fpu_s28, fpu_s29, fpu_s30,
+ fpu_s31, fpu_d0, fpu_d1,
+ fpu_d2, fpu_d3, fpu_d4,
+ fpu_d5, fpu_d6, fpu_d7,
+ fpu_d8, fpu_d9, fpu_d10,
+ fpu_d11, fpu_d12, fpu_d13,
+ fpu_d14, fpu_d15, fpu_d16,
+ fpu_d17, fpu_d18, fpu_d19,
+ fpu_d20, fpu_d21, fpu_d22,
+ fpu_d23, fpu_d24, fpu_d25,
+ fpu_d26, fpu_d27, fpu_d28,
+ fpu_d29, fpu_d30, fpu_d31,
+ fpu_fpsr, fpu_fpcr, LLDB_INVALID_REGNUM};
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers,
+ "g_fpu_regnums_arm64 has wrong number of register infos");
+// clang-format on
+// Register sets for ARM64.
+static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers,
+ g_fpu_regnums_arm64}};
+
static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
@@ -80,19 +156,60 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
const lldb_private::ArchSpec &target_arch)
- : lldb_private::RegisterInfoInterface(target_arch),
+ : lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {
+
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ num_registers = k_num_gpr_registers + k_num_fpr_registers;
+ num_gpr_registers = k_num_gpr_registers;
+ num_fpr_registers = k_num_fpr_registers;
+ last_gpr = gpr_w28;
+ first_fpr = fpu_v0;
+ last_fpr = fpu_fpcr;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
+ return num_gpr_registers + num_fpr_registers;
+}
size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
return sizeof(struct RegisterInfoPOSIX_arm64::GPR);
}
+size_t RegisterInfoPOSIX_arm64::GetFPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_arm64::FPU);
+}
+
const lldb_private::RegisterInfo *
RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
return m_register_info_p;
}
-uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
- return m_register_info_count;
+size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
+ uint32_t reg_index) const {
+ if (reg_index <= last_gpr)
+ return GPRegSet;
+ else if (reg_index <= last_fpr)
+ return FPRegSet;
+ return LLDB_INVALID_REGNUM;
+}
+
+const lldb_private::RegisterSet *
+RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm64[set_index];
+
+ return nullptr;
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index ace179a81814..2da6a531a6b6 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -6,15 +6,18 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_arm64_H_
-#define liblldb_RegisterContextLinux_arm64_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H
-#include "RegisterInfoInterface.h"
+#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
-class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface {
+class RegisterInfoPOSIX_arm64
+ : public lldb_private::RegisterInfoAndSetInterface {
public:
+ enum { GPRegSet = 0, FPRegSet };
+
// based on RegisterContextDarwin_arm64.h
struct GPR {
uint64_t x[29]; // x0-x28
@@ -57,11 +60,28 @@ public:
size_t GetGPRSize() const override;
+ size_t GetFPRSize() const override;
+
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
uint32_t GetRegisterCount() const override;
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t reg_set) const override;
+
+ size_t GetRegisterSetCount() const override;
+
+ size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+
private:
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
};
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
index 35051a3ce095..3461d38a3901 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===//
+//===-- RegisterInfoPOSIX_ppc64le.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
index c4d4d3b546e2..98549ac0dda4 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextLinux_ppc64le_H_
-#define liblldb_RegisterContextLinux_ppc64le_H_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_PPC64LE_H
#include "RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index 68c12aa6e529..4aee55e7afba 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -456,37 +456,26 @@ static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM};
static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM};
static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
-// Generates register kinds array for 64-bit general purpose registers
-#define GPR64_KIND(reg, generic_kind) \
+// Generates register kinds array with DWARF, EH frame and generic kind
+#define MISC_KIND(reg, type, generic_kind) \
{ \
arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \
- gpr_##reg \
+ type##_##reg \
}
-// Generates register kinds array for registers with lldb kind
-#define MISC_KIND(lldb_kind) \
+// Generates register kinds array for registers with only lldb kind
+#define LLDB_KIND(lldb_kind) \
{ \
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
LLDB_INVALID_REGNUM, lldb_kind \
}
// Generates register kinds array for vector registers
-#define VREG_KIND(reg) \
- { \
- LLDB_INVALID_REGNUM, arm64_dwarf::reg, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, fpu_##reg \
- }
-
-// Generates register kinds array for cpsr
-#define CPSR_KIND(lldb_kind) \
- { \
- arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, \
- LLDB_INVALID_REGNUM, lldb_kind \
- }
-
-#define MISC_GPR_KIND(lldb_kind) CPSR_KIND(lldb_kind)
-#define MISC_FPU_KIND(lldb_kind) MISC_KIND(lldb_kind)
-#define MISC_EXC_KIND(lldb_kind) MISC_KIND(lldb_kind)
+#define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind)
+#define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM)
+#define MISC_GPR_KIND(lldb_kind) MISC_KIND(cpsr, gpr, LLDB_REGNUM_GENERIC_FLAGS)
+#define MISC_FPU_KIND(lldb_kind) LLDB_KIND(lldb_kind)
+#define MISC_EXC_KIND(lldb_kind) LLDB_KIND(lldb_kind)
// Defines a 64-bit general purpose register
#define DEFINE_GPR64(reg, generic_kind) \
@@ -509,7 +498,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
{ \
#wreg, nullptr, 4, \
GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \
- lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \
+ lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \
g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \
}
@@ -521,11 +510,11 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
0 \
}
-// Defines S and D pseudo registers mapping over correspondig vector register
+// Defines S and D pseudo registers mapping over corresponding vector register
#define DEFINE_FPU_PSEUDO(reg, size, offset, vreg) \
{ \
#reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \
- lldb::eEncodingIEEE754, lldb::eFormatFloat, MISC_KIND(fpu_##reg), \
+ lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \
g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
index 72ff904520ad..343579cd2657 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -145,7 +145,7 @@
DR_OFFSET(i), eEncodingUint, eFormatHex, \
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM }, \
+ lldb_##reg##i##_i386 }, \
nullptr, nullptr, nullptr, 0 \
}
diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 6d03bd534f37..2d8e8ef21612 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -1,4 +1,4 @@
-//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===//
+//===-- StopInfoMachException.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,6 +8,7 @@
#include "StopInfoMachException.h"
+#include "lldb/lldb-forward.h"
#if defined(__APPLE__)
// Needed for the EXC_RESOURCE interpretation macros
@@ -289,10 +290,48 @@ const char *StopInfoMachException::GetDescription() {
if (m_exc_data_count > 0)
strm.PutChar(')');
- m_description = strm.GetString();
+ m_description = std::string(strm.GetString());
return m_description.c_str();
}
+static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
+ uint32_t exc_data_count,
+ uint64_t exc_sub_code,
+ uint64_t exc_sub_sub_code) {
+ // Try hardware watchpoint.
+ if (target) {
+ // The exc_sub_code indicates the data break address.
+ lldb::WatchpointSP wp_sp =
+ target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired watchpoint
+ // in the exception data. Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
+ }
+ }
+
+ // Try hardware breakpoint.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ // The exc_sub_code indicates the data break address.
+ lldb::BreakpointSiteSP bp_sp =
+ process_sp->GetBreakpointSiteList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (bp_sp && bp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired breakpoint
+ // in the exception data. Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ bp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithBreakpointSiteID(thread,
+ bp_sp->GetID());
+ }
+ }
+
+ return nullptr;
+}
+
StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
@@ -350,22 +389,10 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
} else {
-
- // It's a watchpoint, then.
- // The exc_sub_code indicates the data break address.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress(
- (lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled()) {
- // Debugserver may piggyback the hardware index of the fired
- // watchpoint in the exception data. Set the hardware index if
- // that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread,
- wp_sp->GetID());
- }
+ if (StopInfoSP stop_info =
+ GetStopInfoForHardwareBP(thread, target, exc_data_count,
+ exc_sub_code, exc_sub_sub_code))
+ return stop_info;
}
} else if (exc_code == 2 || // EXC_I386_BPT
exc_code == 3) // EXC_I386_BPTFLT
diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h
index 74c05812ab00..d9c1886d7096 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StopInfoMachException_h_
-#define liblldb_StopInfoMachException_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H
#include <string>
@@ -48,4 +48,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_StopInfoMachException_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_STOPINFOMACHEXCEPTION_H
diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
index 80b04bb14f77..7469e7633e71 100644
--- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -1,5 +1,4 @@
-//===-- ThreadMemory.cpp ----------------------------------------------*- C++
-//-*-===//
+//===-- ThreadMemory.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -30,7 +29,8 @@ ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid,
llvm::StringRef name, llvm::StringRef queue,
lldb::addr_t register_data_addr)
: Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
- m_name(name), m_queue(queue), m_register_data_addr(register_data_addr) {}
+ m_name(std::string(name)), m_queue(std::string(queue)),
+ m_register_data_addr(register_data_addr) {}
ThreadMemory::~ThreadMemory() { DestroyThread(); }
@@ -54,20 +54,14 @@ RegisterContextSP ThreadMemory::GetRegisterContext() {
RegisterContextSP
ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
- RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
if (frame)
concrete_frame_idx = frame->GetConcreteFrameIndex();
- if (concrete_frame_idx == 0) {
- reg_ctx_sp = GetRegisterContext();
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
- }
- return reg_ctx_sp;
+ if (concrete_frame_idx == 0)
+ return GetRegisterContext();
+ return GetUnwinder().CreateRegisterContextForFrame(frame);
}
bool ThreadMemory::CalculateStopInfo() {
diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h
index 85bc1451e4a0..d124f5780ea9 100644
--- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ThreadMemory_h_
-#define liblldb_ThreadMemory_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
#include <string>
@@ -100,7 +100,8 @@ protected:
lldb::addr_t m_register_data_addr;
private:
- DISALLOW_COPY_AND_ASSIGN(ThreadMemory);
+ ThreadMemory(const ThreadMemory &) = delete;
+ const ThreadMemory &operator=(const ThreadMemory &) = delete;
};
-#endif // liblldb_ThreadMemory_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
deleted file mode 100644
index 74fc90e88547..000000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-//===-- UnwindLLDB.cpp -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/Module.h"
-#include "lldb/Symbol/FuncUnwinders.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/ABI.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/Log.h"
-
-#include "RegisterContextLLDB.h"
-#include "UnwindLLDB.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-UnwindLLDB::UnwindLLDB(Thread &thread)
- : Unwind(thread), m_frames(), m_unwind_complete(false),
- m_user_supplied_trap_handler_functions() {
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp) {
- Args args;
- process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
- size_t count = args.GetArgumentCount();
- for (size_t i = 0; i < count; i++) {
- const char *func_name = args.GetArgumentAtIndex(i);
- m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
- }
- }
-}
-
-uint32_t UnwindLLDB::DoGetFrameCount() {
- if (!m_unwind_complete) {
-//#define DEBUG_FRAME_SPEED 1
-#if DEBUG_FRAME_SPEED
-#define FRAME_COUNT 10000
- using namespace std::chrono;
- auto time_value = steady_clock::now();
-#endif
- if (!AddFirstFrame())
- return 0;
-
- ProcessSP process_sp(m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
-
- while (AddOneMoreFrame(abi)) {
-#if DEBUG_FRAME_SPEED
- if ((m_frames.size() % FRAME_COUNT) == 0) {
- const auto now = steady_clock::now();
- const auto delta_t = now - time_value;
- printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
- duration<double, std::milli>(delta_t).count(),
- (float)FRAME_COUNT / duration<double>(delta_t).count());
- time_value = now;
- }
-#endif
- }
- }
- return m_frames.size();
-}
-
-bool UnwindLLDB::AddFirstFrame() {
- if (m_frames.size() > 0)
- return true;
-
- ProcessSP process_sp(m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
-
- // First, set up the 0th (initial) frame
- CursorSP first_cursor_sp(new Cursor());
- RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
- m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
- if (reg_ctx_sp.get() == nullptr)
- goto unwind_done;
-
- if (!reg_ctx_sp->IsValid())
- goto unwind_done;
-
- if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
- goto unwind_done;
-
- if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
- goto unwind_done;
-
- // Everything checks out, so release the auto pointer value and let the
- // cursor own it in its shared pointer
- first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- m_frames.push_back(first_cursor_sp);
-
- // Update the Full Unwind Plan for this frame if not valid
- UpdateUnwindPlanForFirstFrameIfInvalid(abi);
-
- return true;
-
-unwind_done:
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log) {
- LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
- }
- m_unwind_complete = true;
- return false;
-}
-
-UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
- assert(m_frames.size() != 0 &&
- "Get one more frame called with empty frame list");
-
- // If we've already gotten to the end of the stack, don't bother to try
- // again...
- if (m_unwind_complete)
- return nullptr;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
-
- CursorSP prev_frame = m_frames.back();
- uint32_t cur_idx = m_frames.size();
-
- CursorSP cursor_sp(new Cursor());
- RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
- m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
-
- uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth();
-
- // We want to detect an unwind that cycles erroneously and stop backtracing.
- // Don't want this maximum unwind limit to be too low -- if you have a
- // backtrace with an "infinitely recursing" bug, it will crash when the stack
- // blows out and the first 35,000 frames are uninteresting - it's the top
- // most 5 frames that you actually care about. So you can't just cap the
- // unwind at 10,000 or something. Realistically anything over around 200,000
- // is going to blow out the stack space. If we're still unwinding at that
- // point, we're probably never going to finish.
- if (cur_idx >= max_stack_depth) {
- LLDB_LOGF(log,
- "%*sFrame %d unwound too many frames, assuming unwind has "
- "gone astray, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
-
- if (reg_ctx_sp.get() == nullptr) {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
- // return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
- // still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
-
- if (!reg_ctx_sp->IsValid()) {
- // We failed to get a valid RegisterContext. See if the regctx below this
- // on the stack has a fallback unwind plan it can use. Subsequent calls to
- // TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
- // still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log,
- "%*sFrame %d invalid RegisterContext for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
- // return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
- // still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log,
- "%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
- // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
- // have its (constructed) CFA aligned correctly -- don't do the abi
- // alignment check for these.
- if (!reg_ctx_sp->IsTrapHandlerFrame()) {
- // See if we can find a fallback unwind plan for THIS frame. It may be
- // that the UnwindPlan we're using for THIS frame was bad and gave us a
- // bad CFA. If that's not it, then see if we can change the UnwindPlan
- // for the frame below us ("NEXT") -- see if using that other UnwindPlan
- // gets us a better unwind state.
- if (!reg_ctx_sp->TryFallbackUnwindPlan() ||
- !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||
- !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of
- // prev_frame still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log,
- "%*sFrame %d did not get a valid CFA for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- } else {
- LLDB_LOGF(log,
- "%*sFrame %d had a bad CFA value but we switched the "
- "UnwindPlan being used and got one that looks more "
- "realistic.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- }
- }
- if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
- // return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
- // still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log,
- "%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
- // that and return true. Subsequent calls to TryFallbackUnwindPlan() will
- // return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated
- // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame
- // still needs to be updated. Hence updating it.
- if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame(abi);
- }
-
- LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- // Infinite loop where the current cursor is the same as the previous one...
- if (prev_frame->start_pc == cursor_sp->start_pc &&
- prev_frame->cfa == cursor_sp->cfa) {
- LLDB_LOGF(log,
- "th%d pc of this frame is the same as the previous frame and "
- "CFAs for both frames are identical -- stopping unwind",
- m_thread.GetIndexID());
- return nullptr;
- }
-
- cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- return cursor_sp;
-}
-
-void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
- // This function is called for First Frame only.
- assert(m_frames.size() == 1 && "No. of cursor frames are not 1");
-
- bool old_m_unwind_complete = m_unwind_complete;
- CursorSP old_m_candidate_frame = m_candidate_frame;
-
- // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
- // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update
- // the cfa of Frame 0 (if required).
- AddOneMoreFrame(abi);
-
- // Remove all the frames added by above function as the purpose of using
- // above function was just to check whether Unwinder of Frame 0 works or not.
- for (uint32_t i = 1; i < m_frames.size(); i++)
- m_frames.pop_back();
-
- // Restore status after calling AddOneMoreFrame
- m_unwind_complete = old_m_unwind_complete;
- m_candidate_frame = old_m_candidate_frame;
- return;
-}
-
-bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
-
- // Frame zero is a little different
- if (m_frames.empty())
- return false;
-
- // If we've already gotten to the end of the stack, don't bother to try
- // again...
- if (m_unwind_complete)
- return false;
-
- CursorSP new_frame = m_candidate_frame;
- if (new_frame == nullptr)
- new_frame = GetOneMoreFrame(abi);
-
- if (new_frame == nullptr) {
- LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
- m_unwind_complete = true;
- return false;
- }
-
- m_frames.push_back(new_frame);
-
- // If we can get one more frame further then accept that we get back a
- // correct frame.
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame)
- return true;
-
- // We can't go further from the frame returned by GetOneMore frame. Lets try
- // to get a different frame with using the fallback unwind plan.
- if (!m_frames[m_frames.size() - 2]
- ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
- // We don't have a valid fallback unwind plan. Accept the frame as it is.
- // This is a valid situation when we are at the bottom of the stack.
- return true;
- }
-
- // Remove the possibly incorrect frame from the frame list and try to add a
- // different one with the newly selected fallback unwind plan.
- m_frames.pop_back();
- CursorSP new_frame_v2 = GetOneMoreFrame(abi);
- if (new_frame_v2 == nullptr) {
- // We haven't got a new frame from the fallback unwind plan. Accept the
- // frame from the original unwind plan. This is a valid situation when we
- // are at the bottom of the stack.
- m_frames.push_back(new_frame);
- return true;
- }
-
- // Push the new frame to the list and try to continue from this frame. If we
- // can get a new frame then accept it as the correct one.
- m_frames.push_back(new_frame_v2);
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame) {
- // If control reached here then TryFallbackUnwindPlan had succeeded for
- // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next
- // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For
- // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already
- // updated during TryFallbackUnwindPlan call above. However, cfa field
- // still needs to be updated. Hence updating it here and then returning.
- return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
- m_frames[m_frames.size() - 2]->cfa);
- }
-
- // The new frame hasn't helped in unwinding. Fall back to the original one as
- // the default unwind plan is usually more reliable then the fallback one.
- m_frames.pop_back();
- m_frames.push_back(new_frame);
- return true;
-}
-
-bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc,
- bool &behaves_like_zeroth_frame) {
- if (m_frames.size() == 0) {
- if (!AddFirstFrame())
- return false;
- }
-
- ProcessSP process_sp(m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
-
- while (idx >= m_frames.size() && AddOneMoreFrame(abi))
- ;
-
- if (idx < m_frames.size()) {
- cfa = m_frames[idx]->cfa;
- pc = m_frames[idx]->start_pc;
- if (idx == 0) {
- // Frame zero always behaves like it.
- behaves_like_zeroth_frame = true;
- } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
- // This could be an asynchronous signal, thus the
- // pc might point to the interrupted instruction rather
- // than a post-call instruction
- behaves_like_zeroth_frame = true;
- } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
- // This frame may result from signal processing installing
- // a pointer to the first byte of a signal-return trampoline
- // in the return address slot of the frame below, so this
- // too behaves like the zeroth frame (i.e. the pc might not
- // be pointing just past a call in it)
- behaves_like_zeroth_frame = true;
- } else {
- behaves_like_zeroth_frame = false;
- }
- return true;
- }
- return false;
-}
-
-lldb::RegisterContextSP
-UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t idx = frame->GetConcreteFrameIndex();
-
- if (idx == 0) {
- return m_thread.GetRegisterContext();
- }
-
- if (m_frames.size() == 0) {
- if (!AddFirstFrame())
- return reg_ctx_sp;
- }
-
- ProcessSP process_sp(m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
-
- while (idx >= m_frames.size()) {
- if (!AddOneMoreFrame(abi))
- break;
- }
-
- const uint32_t num_frames = m_frames.size();
- if (idx < num_frames) {
- Cursor *frame_cursor = m_frames[idx].get();
- reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
- }
- return reg_ctx_sp;
-}
-
-UnwindLLDB::RegisterContextLLDBSP
-UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
- RegisterContextLLDBSP reg_ctx_sp;
- if (frame_num < m_frames.size())
- reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
- return reg_ctx_sp;
-}
-
-bool UnwindLLDB::SearchForSavedLocationForRegister(
- uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
- uint32_t starting_frame_num, bool pc_reg) {
- int64_t frame_num = starting_frame_num;
- if (static_cast<size_t>(frame_num) >= m_frames.size())
- return false;
-
- // Never interrogate more than one level while looking for the saved pc
- // value. If the value isn't saved by frame_num, none of the frames lower on
- // the stack will have a useful value.
- if (pc_reg) {
- UnwindLLDB::RegisterSearchResult result;
- result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
- lldb_regnum, regloc);
- return result == UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- while (frame_num >= 0) {
- UnwindLLDB::RegisterSearchResult result;
- result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
- lldb_regnum, regloc);
-
- // We descended down to the live register context aka stack frame 0 and are
- // reading the value out of a live register.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
- regloc.type ==
- UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
- return true;
- }
-
- // If we have unwind instructions saying that register N is saved in
- // register M in the middle of the stack (and N can equal M here, meaning
- // the register was not used in this function), then change the register
- // number we're looking for to M and keep looking for a concrete location
- // down the stack, or an actual value from a live RegisterContext at frame
- // 0.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
- regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
- frame_num > 0) {
- result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- lldb_regnum = regloc.location.register_number;
- }
-
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- return true;
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
- return false;
- frame_num--;
- }
- return false;
-}
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
deleted file mode 100644
index ff5db39730b5..000000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ /dev/null
@@ -1,158 +0,0 @@
-//===-- UnwindLLDB.h --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_UnwindLLDB_h_
-#define lldb_UnwindLLDB_h_
-
-#include <vector>
-
-#include "lldb/Symbol/FuncUnwinders.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/UnwindPlan.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-public.h"
-
-namespace lldb_private {
-
-class RegisterContextLLDB;
-
-class UnwindLLDB : public lldb_private::Unwind {
-public:
- UnwindLLDB(lldb_private::Thread &thread);
-
- ~UnwindLLDB() override = default;
-
- enum RegisterSearchResult {
- eRegisterFound = 0,
- eRegisterNotFound,
- eRegisterIsVolatile
- };
-
-protected:
- friend class lldb_private::RegisterContextLLDB;
-
- struct RegisterLocation {
- enum RegisterLocationTypes {
- eRegisterNotSaved = 0, // register was not preserved by callee. If
- // volatile reg, is unavailable
- eRegisterSavedAtMemoryLocation, // register is saved at a specific word of
- // target mem (target_memory_location)
- eRegisterInRegister, // register is available in a (possible other)
- // register (register_number)
- eRegisterSavedAtHostMemoryLocation, // register is saved at a word in
- // lldb's address space
- eRegisterValueInferred, // register val was computed (and is in
- // inferred_value)
- eRegisterInLiveRegisterContext // register value is in a live (stack frame
- // #0) register
- };
- int type;
- union {
- lldb::addr_t target_memory_location;
- uint32_t
- register_number; // in eRegisterKindLLDB register numbering system
- void *host_memory_location;
- uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer ==
- // cfa + offset
- } location;
- };
-
- void DoClear() override {
- m_frames.clear();
- m_candidate_frame.reset();
- m_unwind_complete = false;
- }
-
- uint32_t DoGetFrameCount() override;
-
- bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &start_pc,
- bool &behaves_like_zeroth_frame) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP;
-
- // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame
- // 1's RegisterContextLLDB)
- // The RegisterContext for frame_num must already exist or this returns an
- // empty shared pointer.
- RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num);
-
- // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the
- // first one that
- // has a saved location for this reg.
- bool SearchForSavedLocationForRegister(
- uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
- uint32_t starting_frame_num, bool pc_register);
-
- /// Provide the list of user-specified trap handler functions
- ///
- /// The Platform is one source of trap handler function names; that
- /// may be augmented via a setting. The setting needs to be converted
- /// into an array of ConstStrings before it can be used - we only want
- /// to do that once per thread so it's here in the UnwindLLDB object.
- ///
- /// \return
- /// Vector of ConstStrings of trap handler function names. May be
- /// empty.
- const std::vector<ConstString> &GetUserSpecifiedTrapHandlerFunctionNames() {
- return m_user_supplied_trap_handler_functions;
- }
-
-private:
- struct Cursor {
- lldb::addr_t start_pc; // The start address of the function/symbol for this
- // frame - current pc if unknown
- lldb::addr_t cfa; // The canonical frame address for this stack frame
- lldb_private::SymbolContext sctx; // A symbol context we'll contribute to &
- // provide to the StackFrame creation
- RegisterContextLLDBSP
- reg_ctx_lldb_sp; // These are all RegisterContextLLDB's
-
- Cursor()
- : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(),
- reg_ctx_lldb_sp() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Cursor);
- };
-
- typedef std::shared_ptr<Cursor> CursorSP;
- std::vector<CursorSP> m_frames;
- CursorSP m_candidate_frame;
- bool m_unwind_complete; // If this is true, we've enumerated all the frames in
- // the stack, and m_frames.size() is the
- // number of frames, etc. Otherwise we've only gone as far as directly asked,
- // and m_frames.size()
- // is how far we've currently gone.
-
- std::vector<ConstString> m_user_supplied_trap_handler_functions;
-
- // Check if Full UnwindPlan of First frame is valid or not.
- // If not then try Fallback UnwindPlan of the frame. If Fallback
- // UnwindPlan succeeds then update the Full UnwindPlan with the
- // Fallback UnwindPlan.
- void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi);
-
- CursorSP GetOneMoreFrame(ABI *abi);
-
- bool AddOneMoreFrame(ABI *abi);
-
- bool AddFirstFrame();
-
- // For UnwindLLDB only
- DISALLOW_COPY_AND_ASSIGN(UnwindLLDB);
-};
-
-} // namespace lldb_private
-
-#endif // lldb_UnwindLLDB_h_
diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
deleted file mode 100644
index 558edeec1a37..000000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-//===-- UnwindMacOSXFrameBackchain.cpp --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ArchSpec.h"
-
-#include "RegisterContextMacOSXFrameBackchain.h"
-
-#include <memory>
-
-using namespace lldb;
-using namespace lldb_private;
-
-UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread)
- : Unwind(thread), m_cursors() {}
-
-uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
- if (m_cursors.empty()) {
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- const ArchSpec &target_arch = target->GetArchitecture();
- // Frame zero should always be supplied by the thread...
- exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0));
-
- if (target_arch.GetAddressByteSize() == 8)
- GetStackFrameData_x86_64(exe_ctx);
- else
- GetStackFrameData_i386(exe_ctx);
- }
- }
- return m_cursors.size();
-}
-
-bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(
- uint32_t idx, addr_t &cfa, addr_t &pc, bool &behaves_like_zeroth_frame) {
- const uint32_t frame_count = GetFrameCount();
- if (idx < frame_count) {
- if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
- return false;
- if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
- return false;
-
- pc = m_cursors[idx].pc;
- cfa = m_cursors[idx].fp;
- behaves_like_zeroth_frame = (idx == 0);
-
- return true;
- }
- return false;
-}
-
-lldb::RegisterContextSP
-UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) {
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_idx = frame->GetConcreteFrameIndex();
- const uint32_t frame_count = GetFrameCount();
- if (concrete_idx < frame_count)
- reg_ctx_sp = std::make_shared<RegisterContextMacOSXFrameBackchain>(
- m_thread, concrete_idx, m_cursors[concrete_idx]);
- return reg_ctx_sp;
-}
-
-size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
- const ExecutionContext &exe_ctx) {
- m_cursors.clear();
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == nullptr)
- return 0;
-
- struct Frame_i386 {
- uint32_t fp;
- uint32_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert(reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP(0);
-
- Frame_i386 frame = {static_cast<uint32_t>(cursor.fp),
- static_cast<uint32_t>(cursor.pc)};
-
- m_cursors.push_back(cursor);
-
- const size_t k_frame_size = sizeof(frame);
- Status error;
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
- // Read both the FP and PC (8 bytes)
- if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
- k_frame_size)
- break;
- if (frame.pc >= 0x1000) {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back(cursor);
- }
- }
- if (!m_cursors.empty()) {
- lldb::addr_t first_frame_pc = m_cursors.front().pc;
- if (first_frame_pc != LLDB_INVALID_ADDRESS) {
- const SymbolContextItem resolve_scope =
- eSymbolContextModule | eSymbolContextCompUnit |
- eSymbolContextFunction | eSymbolContextSymbol;
-
- SymbolContext first_frame_sc(
- first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = nullptr;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol) {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize(first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr) {
- if (first_frame->GetFrameCodeAddress() ==
- addr_range_ptr->GetBaseAddress()) {
- // We are at the first instruction, so we can recover the previous PC
- // by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
- // Read the real second frame return address into frame.pc
- if (first_frame_sp &&
- process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
- error) == sizeof(frame.pc)) {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin() + 1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
- }
- }
- // uint32_t i=0;
- // printf(" PC FP\n");
- // printf(" ------------------ ------------------ \n");
- // for (i=0; i<m_cursors.size(); ++i)
- // {
- // printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i,
- // m_cursors[i].pc, m_cursors[i].fp);
- // }
- return m_cursors.size();
-}
-
-size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
- const ExecutionContext &exe_ctx) {
- m_cursors.clear();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == nullptr)
- return 0;
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- struct Frame_x86_64 {
- uint64_t fp;
- uint64_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert(reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP(0);
-
- Frame_x86_64 frame = {cursor.fp, cursor.pc};
-
- m_cursors.push_back(cursor);
- Status error;
- const size_t k_frame_size = sizeof(frame);
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
- // Read both the FP and PC (16 bytes)
- if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
- k_frame_size)
- break;
-
- if (frame.pc >= 0x1000) {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back(cursor);
- }
- }
- if (!m_cursors.empty()) {
- lldb::addr_t first_frame_pc = m_cursors.front().pc;
- if (first_frame_pc != LLDB_INVALID_ADDRESS) {
- const SymbolContextItem resolve_scope =
- eSymbolContextModule | eSymbolContextCompUnit |
- eSymbolContextFunction | eSymbolContextSymbol;
-
- SymbolContext first_frame_sc(
- first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = nullptr;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol) {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize(first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr) {
- if (first_frame->GetFrameCodeAddress() ==
- addr_range_ptr->GetBaseAddress()) {
- // We are at the first instruction, so we can recover the previous PC
- // by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
- // Read the real second frame return address into frame.pc
- if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
- error) == sizeof(frame.pc)) {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin() + 1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
- }
- }
- return m_cursors.size();
-}
diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
deleted file mode 100644
index f0bde90a53be..000000000000
--- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- UnwindMacOSXFrameBackchain.h ----------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_UnwindMacOSXFrameBackchain_h_
-#define lldb_UnwindMacOSXFrameBackchain_h_
-
-#include <vector>
-
-#include "lldb/Target/Unwind.h"
-#include "lldb/lldb-private.h"
-
-class UnwindMacOSXFrameBackchain : public lldb_private::Unwind {
-public:
- UnwindMacOSXFrameBackchain(lldb_private::Thread &thread);
-
- ~UnwindMacOSXFrameBackchain() override = default;
-
-protected:
- void DoClear() override { m_cursors.clear(); }
-
- uint32_t DoGetFrameCount() override;
-
- bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc,
- bool &behaves_like_zeroth_frame) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- friend class RegisterContextMacOSXFrameBackchain;
-
- struct Cursor {
- lldb::addr_t pc; // Program counter
- lldb::addr_t fp; // Frame pointer for us with backchain
- };
-
-private:
- std::vector<Cursor> m_cursors;
-
- size_t GetStackFrameData_i386(const lldb_private::ExecutionContext &exe_ctx);
-
- size_t
- GetStackFrameData_x86_64(const lldb_private::ExecutionContext &exe_ctx);
-
- // For UnwindMacOSXFrameBackchain only
- DISALLOW_COPY_AND_ASSIGN(UnwindMacOSXFrameBackchain);
-};
-
-#endif // lldb_UnwindMacOSXFrameBackchain_h_
diff --git a/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h
index 39cbf01ea9d2..8f0eed4f02c9 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-arm-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_arm_register_enums_h
-#define lldb_arm_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -196,4 +196,4 @@ enum {
};
}
-#endif // #ifndef lldb_arm64_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
index cc414dcde3cf..39d47b8801cc 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_arm64_register_enums_h
-#define lldb_arm64_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -261,4 +261,4 @@ enum {
};
}
-#endif // #ifndef lldb_arm64_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_ARM64_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
index d97f77122426..e6a7efd00f67 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_mips_freebsd_register_enums_h
-#define lldb_mips_freebsd_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -62,4 +62,4 @@ enum {
k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
};
}
-#endif // #ifndef lldb_mips_freebsd_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
index 2f68b8022c9a..348af27d2809 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_mips_linux_register_enums_h
-#define lldb_mips_linux_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -357,4 +357,4 @@ enum {
};
}
-#endif // #ifndef lldb_mips_linux_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h
index 6edf7ee3864d..40a75c006d84 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-ppc64-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ppc64_register_enums_h
-#define lldb_ppc64_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -133,4 +133,4 @@ enum {
k_num_vmx_registers_ppc64 = k_last_vmx_ppc64 - k_first_vmx_ppc64 + 1,
};
-#endif // #ifndef lldb_ppc64_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
index 0c381a5f3918..a7b5bc5ad9e3 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ppc64le_register_enums_h
-#define lldb_ppc64le_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -204,4 +204,4 @@ enum {
k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1,
};
-#endif // #ifndef lldb_ppc64le_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_PPC64LE_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
index bd6626108290..23c441e1c803 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_s390x_register_enums_h
-#define lldb_s390x_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -87,4 +87,4 @@ enum {
};
}
-#endif // #ifndef lldb_s390x_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_S390X_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index bfdd586d9ded..35f1a4075d09 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_x86_register_enums_h
-#define lldb_x86_register_enums_h
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H
namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
@@ -113,7 +113,8 @@ enum {
lldb_bndstatus_i386,
k_last_mpxc_i386 = lldb_bndstatus_i386,
- lldb_dr0_i386,
+ k_first_dbr_i386,
+ lldb_dr0_i386 = k_first_dbr_i386,
lldb_dr1_i386,
lldb_dr2_i386,
lldb_dr3_i386,
@@ -121,6 +122,7 @@ enum {
lldb_dr5_i386,
lldb_dr6_i386,
lldb_dr7_i386,
+ k_last_dbr_i386 = lldb_dr7_i386,
k_num_registers_i386,
k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
@@ -131,6 +133,7 @@ enum {
k_num_fpr_registers_i386 +
k_num_avx_registers_i386 +
k_num_mpx_registers_i386,
+ k_num_dbr_registers_i386 = k_last_dbr_i386 - k_first_dbr_i386 + 1,
};
// Internal codes for all x86_64 registers.
@@ -318,4 +321,4 @@ enum {
};
}
-#endif // #ifndef lldb_x86_register_enums_h
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index ab23589ae9a9..aa95e92607ad 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessElfCore.cpp --------------------------------------*- C++ -*-===//
+//===-- ProcessElfCore.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -35,6 +35,8 @@
using namespace lldb_private;
namespace ELF = llvm::ELF;
+LLDB_PLUGIN_DEFINE(ProcessElfCore)
+
ConstString ProcessElfCore::GetPluginNameStatic() {
static ConstString g_name("elf-core");
return g_name;
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 829fe9ac7199..6f6309799f43 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -13,8 +13,8 @@
// space.
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ProcessElfCore_h_
-#define liblldb_ProcessElfCore_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H
#include <list>
#include <vector>
@@ -125,7 +125,8 @@ private:
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
std::string m_dyld_plugin_name;
- DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
+ ProcessElfCore(const ProcessElfCore &) = delete;
+ const ProcessElfCore &operator=(const ProcessElfCore &) = delete;
// True if m_thread_contexts contains valid entries
bool m_thread_data_valid = false;
@@ -165,4 +166,4 @@ private:
llvm::Error parseLinuxNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
};
-#endif // liblldb_ProcessElfCore_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index fa05c457fc61..b76f26a584c0 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_arm.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -44,10 +44,12 @@ bool RegisterContextCorePOSIX_arm::WriteFPR() {
bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size) {
- value = v;
- return true;
+ if (offset + reg_info->byte_size <= GetGPRSize()) {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
}
return false;
}
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index adda43ebccbc..f9ec08ed35fc 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_arm_h_
-#define liblldb_RegisterContextCorePOSIX_arm_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -50,4 +50,4 @@ private:
lldb_private::DataExtractor m_gpr;
};
-#endif // liblldb_RegisterContextCorePOSIX_arm_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index e477c438ba12..685567416983 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_arm64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm64.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,13 +17,16 @@
using namespace lldb_private;
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
- Thread &thread, RegisterInfoInterface *register_info,
+ Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
- : RegisterContextPOSIX_arm64(thread, 0, register_info) {
+ : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
gpregset.GetByteSize());
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ m_fpregset = getRegset(
+ notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
}
RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
@@ -45,11 +48,26 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() {
bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size) {
- value = v;
- return true;
+ if (offset + reg_info->byte_size <= GetGPRSize()) {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
}
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ offset -= GetGPRSize();
+ if (IsFPR(reg) && offset + reg_info->byte_size <= GetFPUSize()) {
+ Status error;
+ value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
+ return error.Success();
+ }
+
return false;
}
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index de6d819c29ce..830e0ff91e4c 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_arm64_h_
-#define liblldb_RegisterContextCorePOSIX_arm64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -18,7 +18,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
public:
RegisterContextCorePOSIX_arm64(
lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
+ std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
const lldb_private::DataExtractor &gpregset,
llvm::ArrayRef<lldb_private::CoreNote> notes);
@@ -48,6 +48,7 @@ protected:
private:
lldb::DataBufferSP m_gpr_buffer;
lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpregset;
};
-#endif // liblldb_RegisterContextCorePOSIX_arm64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 3601f3b3b216..b5b83d899a44 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_mips64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_mips64.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
index 999c9451573b..b42a76c082f0 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_mips64_h_
-#define liblldb_RegisterContextCorePOSIX_mips64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -52,4 +52,4 @@ private:
lldb_private::DataExtractor m_fpr;
};
-#endif // liblldb_RegisterContextCorePOSIX_mips64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_MIPS64_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 6984bf4ee9b8..e15cd47cd7da 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_powerpc.cpp --------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_powerpc.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index 7684c0b31837..cf50b6e0bf70 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_powerpc_h_
-#define liblldb_RegisterContextCorePOSIX_powerpc_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -57,4 +57,4 @@ private:
lldb_private::DataExtractor m_vec;
};
-#endif // liblldb_RegisterContextCorePOSIX_powerpc_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_POWERPC_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
index 0eebf474f60e..d44fb399e18a 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_ppc64le.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
index 6e01d23dd656..8de77a7e25bf 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_ppc64le_h_
-#define liblldb_RegisterContextCorePOSIX_ppc64le_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -45,4 +45,4 @@ private:
lldb_private::DataExtractor m_vsx;
};
-#endif // liblldb_RegisterContextCorePOSIX_ppc64le_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_PPC64LE_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index d84fc3e74395..c3aa92c9f86c 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_s390x.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_s390x.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
index 729617649c4f..4560f062e06f 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_s390x_h_
-#define liblldb_RegisterContextCorePOSIX_s390x_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -52,4 +52,4 @@ private:
lldb_private::DataExtractor m_fpr;
};
-#endif // liblldb_RegisterContextCorePOSIX_s390x_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_S390X_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index 4454857e1799..6eaad9f381d6 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIXCore_x86_64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_x86_64.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
index f41991c240d2..9adfbf7e6852 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextCorePOSIX_x86_64_h_
-#define liblldb_RegisterContextCorePOSIX_x86_64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -46,4 +46,4 @@ private:
std::unique_ptr<uint8_t[]> m_fpregset;
};
-#endif // liblldb_RegisterContextCorePOSIX_x86_64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_X86_64_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
index c8829d612b31..0c21c0f50abb 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterUtilities.cpp -----------------------------------*- C++ -*-===//
+//===-- RegisterUtilities.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 49ad425db445..4e08aa280817 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_REGISTERUTILITIES_H
-#define LLDB_REGISTERUTILITIES_H
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Utility/DataExtractor.h"
@@ -118,4 +118,4 @@ constexpr RegsetDesc PPC_VSX_Desc[] = {
} // namespace lldb_private
-#endif // #ifndef LLDB_REGISTERUTILITIES_H
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 508c8a3108a6..6b5acfa4bc1b 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -1,4 +1,4 @@
-//===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
+//===-- ThreadElfCore.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -82,7 +82,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::FreeBSD: {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
- reg_interface = new RegisterInfoPOSIX_arm64(arch);
break;
case llvm::Triple::arm:
reg_interface = new RegisterInfoPOSIX_arm(arch);
@@ -111,7 +110,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::NetBSD: {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
- reg_interface = new RegisterInfoPOSIX_arm64(arch);
break;
case llvm::Triple::x86_64:
reg_interface = new RegisterContextNetBSD_x86_64(arch);
@@ -128,7 +126,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
reg_interface = new RegisterInfoPOSIX_arm(arch);
break;
case llvm::Triple::aarch64:
- reg_interface = new RegisterInfoPOSIX_arm64(arch);
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
@@ -159,7 +156,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::OpenBSD: {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
- reg_interface = new RegisterInfoPOSIX_arm64(arch);
break;
case llvm::Triple::arm:
reg_interface = new RegisterInfoPOSIX_arm(arch);
@@ -180,7 +176,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
break;
}
- if (!reg_interface) {
+ if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64) {
LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
__FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
assert(false && "Architecture or OS not supported");
@@ -189,7 +185,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>(
- *this, reg_interface, m_gpregset_data, m_notes);
+ *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch),
+ m_gpregset_data, m_notes);
break;
case llvm::Triple::arm:
m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
@@ -229,9 +226,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
reg_ctx_sp = m_thread_reg_ctx_sp;
} else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
@@ -296,25 +291,25 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data,
pr_cursig = data.GetU16(&offset);
offset += 2; // pad
- pr_sigpend = data.GetPointer(&offset);
- pr_sighold = data.GetPointer(&offset);
+ pr_sigpend = data.GetAddress(&offset);
+ pr_sighold = data.GetAddress(&offset);
pr_pid = data.GetU32(&offset);
pr_ppid = data.GetU32(&offset);
pr_pgrp = data.GetU32(&offset);
pr_sid = data.GetU32(&offset);
- pr_utime.tv_sec = data.GetPointer(&offset);
- pr_utime.tv_usec = data.GetPointer(&offset);
+ pr_utime.tv_sec = data.GetAddress(&offset);
+ pr_utime.tv_usec = data.GetAddress(&offset);
- pr_stime.tv_sec = data.GetPointer(&offset);
- pr_stime.tv_usec = data.GetPointer(&offset);
+ pr_stime.tv_sec = data.GetAddress(&offset);
+ pr_stime.tv_usec = data.GetAddress(&offset);
- pr_cutime.tv_sec = data.GetPointer(&offset);
- pr_cutime.tv_usec = data.GetPointer(&offset);
+ pr_cutime.tv_sec = data.GetAddress(&offset);
+ pr_cutime.tv_usec = data.GetAddress(&offset);
- pr_cstime.tv_sec = data.GetPointer(&offset);
- pr_cstime.tv_usec = data.GetPointer(&offset);
+ pr_cstime.tv_sec = data.GetAddress(&offset);
+ pr_cstime.tv_usec = data.GetAddress(&offset);
return error;
}
@@ -367,7 +362,7 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
offset += 4;
}
- pr_flag = data.GetPointer(&offset);
+ pr_flag = data.GetAddress(&offset);
if (arch.IsMIPS()) {
// The pr_uid and pr_gid is always 32 bit irrespective of platforms
diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
index ddcf35013b34..8d973bb840d2 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ThreadElfCore_h_
-#define liblldb_ThreadElfCore_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/Thread.h"
@@ -173,4 +173,4 @@ protected:
bool CalculateStopInfo() override;
};
-#endif // liblldb_ThreadElfCore_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index 064bbde8442e..fdaa60e2df41 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===//
+//===-- GDBRemoteClientBase.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -41,7 +41,7 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
{
std::lock_guard<std::mutex> lock(m_mutex);
- m_continue_packet = payload;
+ m_continue_packet = std::string(payload);
m_should_stop = false;
}
ContinueLock cont_lock(*this);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index ea294ffcef26..cd9f6ebd7642 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteClientBase_h_
-#define liblldb_GDBRemoteClientBase_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H
#include "GDBRemoteCommunication.h"
@@ -149,4 +149,4 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationClient_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECLIENTBASE_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 7cea013eea7f..bfacd41dc1a3 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===//
+//===-- GDBRemoteCommunication.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -50,7 +50,7 @@
#include <compression.h>
#endif
-#if LLVM_ENABLE_ZLIB
+#if defined(HAVE_LIBZ)
#include <zlib.h>
#endif
@@ -125,7 +125,7 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
packet.Write(payload.data(), payload.size());
packet.PutChar('#');
packet.PutHex8(CalculcateChecksum(payload));
- std::string packet_str = packet.GetString();
+ std::string packet_str = std::string(packet.GetString());
return SendRawPacketNoLock(packet_str);
}
@@ -582,7 +582,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
}
#endif
-#if LLVM_ENABLE_ZLIB
+#if defined(HAVE_LIBZ)
if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
decompressed_buffer != nullptr &&
m_compression_type == CompressionType::ZlibDeflate) {
@@ -763,7 +763,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
if (m_bytes[0] == '$' && total_length > 4) {
for (size_t i = 0; !binary && i < total_length; ++i) {
unsigned char c = m_bytes[i];
- if (isprint(c) == 0 && isspace(c) == 0) {
+ if (!llvm::isPrint(c) && !llvm::isSpace(c)) {
binary = true;
}
}
@@ -810,31 +810,9 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
GDBRemotePacket::ePacketTypeRecv, total_length);
// Copy the packet from m_bytes to packet_str expanding the run-length
- // encoding in the process. Reserve enough byte for the most common case
- // (no RLE used)
- std ::string packet_str;
- packet_str.reserve(m_bytes.length());
- for (std::string::const_iterator c = m_bytes.begin() + content_start;
- c != m_bytes.begin() + content_end; ++c) {
- if (*c == '*') {
- // '*' indicates RLE. Next character will give us the repeat count
- // and previous character is what is to be repeated.
- char char_to_repeat = packet_str.back();
- // Number of time the previous character is repeated
- int repeat_count = *++c + 3 - ' ';
- // We have the char_to_repeat and repeat_count. Now push it in the
- // packet.
- for (int i = 0; i < repeat_count; ++i)
- packet_str.push_back(char_to_repeat);
- } else if (*c == 0x7d) {
- // 0x7d is the escape character. The next character is to be XOR'd
- // with 0x20.
- char escapee = *++c ^ 0x20;
- packet_str.push_back(escapee);
- } else {
- packet_str.push_back(*c);
- }
- }
+ // encoding in the process.
+ std ::string packet_str =
+ ExpandRLE(m_bytes.substr(content_start, content_end - content_start));
packet = StringExtractorGDBRemote(packet_str);
if (m_bytes[0] == '$' || m_bytes[0] == '%') {
@@ -891,7 +869,7 @@ Status GDBRemoteCommunication::StartListenThread(const char *hostname,
else
snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
m_listen_url = listen_url;
- SetConnection(new ConnectionFileDescriptor());
+ SetConnection(std::make_unique<ConnectionFileDescriptor>());
llvm::Expected<HostThread> listen_thread = ThreadLauncher::LaunchThread(
listen_url, GDBRemoteCommunication::ListenThread, this);
if (!listen_thread)
@@ -1274,11 +1252,12 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Unable to connect: %s", status.AsCString());
- client.SetConnection(conn_up.release());
+ client.SetConnection(std::move(conn_up));
if (llvm::Error error = accept_status.get().ToError())
return error;
- server.SetConnection(new ConnectionFileDescriptor(accept_socket));
+ server.SetConnection(
+ std::make_unique<ConnectionFileDescriptor>(accept_socket));
return llvm::Error::success();
}
@@ -1382,3 +1361,30 @@ void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
break;
}
}
+
+std::string GDBRemoteCommunication::ExpandRLE(std::string packet) {
+ // Reserve enough byte for the most common case (no RLE used).
+ std::string decoded;
+ decoded.reserve(packet.size());
+ for (std::string::const_iterator c = packet.begin(); c != packet.end(); ++c) {
+ if (*c == '*') {
+ // '*' indicates RLE. Next character will give us the repeat count and
+ // previous character is what is to be repeated.
+ char char_to_repeat = decoded.back();
+ // Number of time the previous character is repeated.
+ int repeat_count = *++c + 3 - ' ';
+ // We have the char_to_repeat and repeat_count. Now push it in the
+ // packet.
+ for (int i = 0; i < repeat_count; ++i)
+ decoded.push_back(char_to_repeat);
+ } else if (*c == 0x7d) {
+ // 0x7d is the escape character. The next character is to be XOR'd with
+ // 0x20.
+ char escapee = *++c ^ 0x20;
+ decoded.push_back(escapee);
+ } else {
+ decoded.push_back(*c);
+ }
+ }
+ return decoded;
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 0b670018bd69..b1e2075a64fe 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunication_h_
-#define liblldb_GDBRemoteCommunication_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
#include "GDBRemoteCommunicationHistory.h"
@@ -142,6 +142,9 @@ public:
static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
GDBRemoteCommunication &server);
+ /// Expand GDB run-length encoding.
+ static std::string ExpandRLE(std::string);
+
protected:
std::chrono::seconds m_packet_timeout;
uint32_t m_echo_number;
@@ -223,7 +226,9 @@ private:
void *m_decompression_scratch = nullptr;
#endif
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
+ GDBRemoteCommunication(const GDBRemoteCommunication &) = delete;
+ const GDBRemoteCommunication &
+ operator=(const GDBRemoteCommunication &) = delete;
};
} // namespace process_gdb_remote
@@ -239,4 +244,4 @@ struct format_provider<
};
} // namespace llvm
-#endif // liblldb_GDBRemoteCommunication_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATION_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index b2f1ee527e8b..c75d5e106cd0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -45,6 +45,13 @@ using namespace lldb_private::process_gdb_remote;
using namespace lldb_private;
using namespace std::chrono;
+llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
+ const QOffsets &offsets) {
+ return os << llvm::formatv(
+ "QOffsets({0}, [{1:@[x]}])", offsets.segments,
+ llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
+}
+
// GDBRemoteCommunicationClient constructor
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
: GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
@@ -573,7 +580,8 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
if (response.IsUnsupportedResponse()) {
m_supports_jThreadsInfo = false;
} else if (!response.Empty()) {
- object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
}
}
}
@@ -685,7 +693,7 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
if (result != PacketResult::Success)
return result;
- const std::string &this_string = this_response.GetStringRef();
+ const std::string &this_string = std::string(this_response.GetStringRef());
// Check for m or l as first character; l seems to mean this is the last
// chunk
@@ -757,7 +765,7 @@ bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
return true;
if (response.GetChar() == 'E') {
// A string the describes what failed when launching...
- error_str = response.GetStringRef().substr(1);
+ error_str = std::string(response.GetStringRef().substr(1));
} else {
error_str.assign("unknown error occurred launching process");
}
@@ -833,7 +841,7 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket(
bool send_hex_encoding = false;
for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
++p) {
- if (isprint(*p)) {
+ if (llvm::isPrint(*p)) {
switch (*p) {
case '$':
case '#':
@@ -1000,7 +1008,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
while (response.GetNameColonValue(name, value)) {
if (name.equals("name")) {
success = true;
- m_gdb_server_name = value;
+ m_gdb_server_name = std::string(value);
} else if (name.equals("version")) {
llvm::StringRef major, minor;
std::tie(major, minor) = value.split('.');
@@ -1045,7 +1053,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
}
#endif
-#if LLVM_ENABLE_ZLIB
+#if defined(HAVE_LIBZ)
if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "zlib-deflate") {
@@ -1123,6 +1131,20 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
return true;
}
+static void ParseOSType(llvm::StringRef value, std::string &os_name,
+ std::string &environment) {
+ if (value.equals("iossimulator") || value.equals("tvossimulator") ||
+ value.equals("watchossimulator")) {
+ environment = "simulator";
+ os_name = value.drop_back(environment.size()).str();
+ } else if (value.equals("maccatalyst")) {
+ os_name = "ios";
+ environment = "macabi";
+ } else {
+ os_name = value.str();
+ }
+}
+
bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
@@ -1158,7 +1180,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
if (!value.getAsInteger(0, sub))
++num_keys_decoded;
} else if (name.equals("arch")) {
- arch_name = value;
+ arch_name = std::string(value);
++num_keys_decoded;
} else if (name.equals("triple")) {
StringExtractor extractor(value);
@@ -1181,14 +1203,10 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
extractor.GetHexByteString(m_os_kernel);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- if (value.equals("maccatalyst")) {
- os_name = "ios";
- environment = "macabi";
- } else
- os_name = value;
+ ParseOSType(value, os_name, environment);
++num_keys_decoded;
} else if (name.equals("vendor")) {
- vendor_name = value;
+ vendor_name = std::string(value);
++num_keys_decoded;
} else if (name.equals("endian")) {
byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
@@ -1956,9 +1974,9 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
} else if (name.equals("cpusubtype")) {
value.getAsInteger(0, sub);
} else if (name.equals("vendor")) {
- vendor = value;
+ vendor = std::string(value);
} else if (name.equals("ostype")) {
- os_type = value;
+ os_type = std::string(value);
}
}
@@ -2045,14 +2063,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
extractor.GetHexByteString(triple);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- if (value.equals("maccatalyst")) {
- os_name = "ios";
- environment = "macabi";
- } else
- os_name = value;
+ ParseOSType(value, os_name, environment);
++num_keys_decoded;
} else if (name.equals("vendor")) {
- vendor_name = value;
+ vendor_name = std::string(value);
++num_keys_decoded;
} else if (name.equals("endian")) {
byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
@@ -2069,7 +2083,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
if (!value.getAsInteger(16, pid))
++num_keys_decoded;
} else if (name.equals("elf_abi")) {
- elf_abi = value;
+ elf_abi = std::string(value);
++num_keys_decoded;
}
}
@@ -2140,7 +2154,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
uint32_t GDBRemoteCommunicationClient::FindProcesses(
const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos) {
- process_infos.Clear();
+ process_infos.clear();
if (m_supports_qfProcessInfo) {
StreamString packet;
@@ -2220,7 +2234,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
ProcessInstanceInfo process_info;
if (!DecodeProcessInfoResponse(response, process_info))
break;
- process_infos.Append(process_info);
+ process_infos.push_back(process_info);
response = StringExtractorGDBRemote();
} while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
PacketResult::Success);
@@ -2229,7 +2243,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
return 0;
}
}
- return process_infos.GetSize();
+ return process_infos.size();
}
bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
@@ -2536,7 +2550,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
return 0;
StructuredData::ObjectSP data =
- StructuredData::ParseJSON(response.GetStringRef());
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (!data)
return 0;
@@ -2557,7 +2571,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer(
std::string socket_name;
if (StructuredData::ObjectSP socket_name_osp =
element->GetValueForKey(llvm::StringRef("socket_name")))
- socket_name = socket_name_osp->GetStringValue();
+ socket_name = std::string(socket_name_osp->GetStringValue());
if (port != 0 || !socket_name.empty())
connection_urls.emplace_back(port, socket_name);
@@ -2783,12 +2797,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
thread_ids.push_back(1);
}
} else {
-#if !defined(LLDB_CONFIGURATION_DEBUG)
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
- LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending "
- "packet 'qfThreadInfo'");
-#endif
+ LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "
+ "packet 'qfThreadInfo'");
sequence_mutex_unavailable = true;
}
return thread_ids.size();
@@ -3478,7 +3490,7 @@ GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
return error;
} else
options.setTraceParams(
- static_pointer_cast<StructuredData::Dictionary>(
+ std::static_pointer_cast<StructuredData::Dictionary>(
custom_params_sp));
}
} else {
@@ -3530,6 +3542,46 @@ Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
return error;
}
+llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(
+ "qOffsets", response, /*send_async=*/false) != PacketResult::Success)
+ return llvm::None;
+ if (!response.IsNormalResponse())
+ return llvm::None;
+
+ QOffsets result;
+ llvm::StringRef ref = response.GetStringRef();
+ const auto &GetOffset = [&] {
+ addr_t offset;
+ if (ref.consumeInteger(16, offset))
+ return false;
+ result.offsets.push_back(offset);
+ return true;
+ };
+
+ if (ref.consume_front("Text=")) {
+ result.segments = false;
+ if (!GetOffset())
+ return llvm::None;
+ if (!ref.consume_front(";Data=") || !GetOffset())
+ return llvm::None;
+ if (ref.empty())
+ return result;
+ if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
+ return result;
+ } else if (ref.consume_front("TextSeg=")) {
+ result.segments = true;
+ if (!GetOffset())
+ return llvm::None;
+ if (ref.empty())
+ return result;
+ if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
+ return result;
+ }
+ return llvm::None;
+}
+
bool GDBRemoteCommunicationClient::GetModuleInfo(
const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
ModuleSpec &module_spec) {
@@ -3571,7 +3623,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
StringExtractor extractor(value);
std::string uuid;
extractor.GetHexByteString(uuid);
- module_spec.GetUUID().SetFromStringRef(uuid, uuid.size() / 2);
+ module_spec.GetUUID().SetFromStringRef(uuid);
} else if (name == "triple") {
StringExtractor extractor(value);
std::string triple;
@@ -3607,8 +3659,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
if (!dict->GetValueForKeyAsString("uuid", string))
return llvm::None;
- if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
- string.size())
+ if (!result.GetUUID().SetFromStringRef(string))
return llvm::None;
if (!dict->GetValueForKeyAsInteger("file_offset", integer))
@@ -3667,7 +3718,7 @@ GDBRemoteCommunicationClient::GetModulesInfo(
}
StructuredData::ObjectSP response_object_sp =
- StructuredData::ParseJSON(response.GetStringRef());
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (!response_object_sp)
return llvm::None;
@@ -3722,7 +3773,7 @@ bool GDBRemoteCommunicationClient::ReadExtFeature(
return false;
}
- const std::string &str = chunk.GetStringRef();
+ const std::string &str = std::string(chunk.GetStringRef());
if (str.length() == 0) {
// should have some data in chunk
err.SetErrorString("Empty response from $qXfer packet");
@@ -3936,7 +3987,7 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
send_async) == PacketResult::Success) {
m_supported_async_json_packets_sp =
- StructuredData::ParseJSON(response.GetStringRef());
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
if (m_supported_async_json_packets_sp &&
!m_supported_async_json_packets_sp->GetAsArray()) {
// We were returned something other than a JSON array. This is
@@ -4002,7 +4053,7 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
// Build command: Configure{type_name}: serialized config data.
StreamGDBRemote stream;
stream.PutCString("QConfigure");
- stream.PutCString(type_name.AsCString());
+ stream.PutCString(type_name.GetStringRef());
stream.PutChar(':');
if (config_sp) {
// Gather the plain-text version of the configuration data.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 11fd40bce44f..8df08cbde735 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationClient_h_
-#define liblldb_GDBRemoteCommunicationClient_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
#include "GDBRemoteClientBase.h"
@@ -20,6 +20,7 @@
#include "lldb/Host/File.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/GDBRemote.h"
+#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/StructuredData.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
@@ -31,6 +32,22 @@
namespace lldb_private {
namespace process_gdb_remote {
+/// The offsets used by the target when relocating the executable. Decoded from
+/// qOffsets packet response.
+struct QOffsets {
+ /// If true, the offsets field describes segments. Otherwise, it describes
+ /// sections.
+ bool segments;
+
+ /// The individual offsets. Section offsets have two or three members.
+ /// Segment offsets have either one of two.
+ std::vector<uint64_t> offsets;
+};
+inline bool operator==(const QOffsets &a, const QOffsets &b) {
+ return a.segments == b.segments && a.offsets == b.offsets;
+}
+llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);
+
class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
public:
GDBRemoteCommunicationClient();
@@ -425,6 +442,11 @@ public:
bool GetSharedCacheInfoSupported();
+ /// Use qOffsets to query the offset used when relocating the target
+ /// executable. If successful, the returned structure will contain at least
+ /// one value in the offsets field.
+ llvm::Optional<QOffsets> GetQOffsets();
+
bool GetModuleInfo(const FileSpec &module_file_spec,
const ArchSpec &arch_spec, ModuleSpec &module_spec);
@@ -599,10 +621,12 @@ protected:
LazyBool GetThreadPacketSupported(lldb::tid_t tid, llvm::StringRef packetStr);
private:
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
+ GDBRemoteCommunicationClient(const GDBRemoteCommunicationClient &) = delete;
+ const GDBRemoteCommunicationClient &
+ operator=(const GDBRemoteCommunicationClient &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationClient_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONCLIENT_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index 9e5646985f87..3984a45c3da1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationHistory.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index ee265ef86dff..e783e59c3455 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationHistory_h_
-#define liblldb_GDBRemoteCommunicationHistory_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
#include <string>
#include <vector>
@@ -83,4 +83,4 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationHistory_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONHISTORY_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 15c73e78bd44..920327e7d0ab 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationReplayServer.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -131,22 +131,26 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
GDBRemotePacket entry = m_packet_history.back();
m_packet_history.pop_back();
+ // Decode run-length encoding.
+ const std::string expanded_data =
+ GDBRemoteCommunication::ExpandRLE(entry.packet.data);
+
// We've handled the handshake implicitly before. Skip the packet and move
// on.
if (entry.packet.data == "+")
continue;
if (entry.type == GDBRemotePacket::ePacketTypeSend) {
- if (unexpected(entry.packet.data, packet.GetStringRef())) {
+ if (unexpected(expanded_data, packet.GetStringRef())) {
LLDB_LOG(log,
"GDBRemoteCommunicationReplayServer expected packet: '{0}'",
- entry.packet.data);
+ expanded_data);
LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'",
packet.GetStringRef());
#ifndef NDEBUG
// This behaves like a regular assert, but prints the expected and
// received packet before aborting.
- printf("Reproducer expected packet: '%s'\n", entry.packet.data.c_str());
+ printf("Reproducer expected packet: '%s'\n", expanded_data.c_str());
printf("Reproducer received packet: '%s'\n",
packet.GetStringRef().data());
llvm::report_fatal_error("Encountered unexpected packet during replay");
@@ -155,7 +159,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
}
// Ignore QEnvironment packets as they're handled earlier.
- if (entry.packet.data.find("QEnvironment") == 1) {
+ if (expanded_data.find("QEnvironment") == 1) {
assert(m_packet_history.back().type ==
GDBRemotePacket::ePacketTypeRecv);
m_packet_history.pop_back();
@@ -283,3 +287,28 @@ thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
return {};
}
+
+Status GDBRemoteCommunicationReplayServer::Connect(
+ process_gdb_remote::GDBRemoteCommunicationClient &client) {
+ repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
+ if (!loader)
+ return Status("No loader provided.");
+
+ static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
+ multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
+ repro::Reproducer::Instance().GetLoader());
+ if (!multi_loader)
+ return Status("No gdb remote provider found.");
+
+ llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
+ if (!history_file)
+ return Status("No gdb remote packet log found.");
+
+ if (auto error = LoadReplayHistory(FileSpec(*history_file)))
+ return Status("Unable to load replay history");
+
+ if (auto error = GDBRemoteCommunication::ConnectLocally(client, *this))
+ return Status("Unable to connect to replay server");
+
+ return {};
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index 0b5e910f7c6a..c13e5ee0bf92 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -6,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationReplayServer_h_
-#define liblldb_GDBRemoteCommunicationReplayServer_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
// Other libraries and framework includes
#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationClient.h"
#include "GDBRemoteCommunicationHistory.h"
// Project includes
@@ -51,6 +52,8 @@ public:
bool StartAsyncThread();
void StopAsyncThread();
+ Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client);
+
protected:
enum {
eBroadcastBitAsyncContinue = (1 << 0),
@@ -73,10 +76,13 @@ protected:
bool m_skip_acks;
private:
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer);
+ GDBRemoteCommunicationReplayServer(
+ const GDBRemoteCommunicationReplayServer &) = delete;
+ const GDBRemoteCommunicationReplayServer &
+ operator=(const GDBRemoteCommunicationReplayServer &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationReplayServer_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index ac6ecffcf854..b78f0916b9b9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationServer.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 86f0abf45e06..a7c2ea47e3ba 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationServer_h_
-#define liblldb_GDBRemoteCommunicationServer_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H
#include <functional>
#include <map>
@@ -74,7 +74,9 @@ protected:
PacketResult SendOKResponse();
private:
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
+ GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete;
+ const GDBRemoteCommunicationServer &
+ operator=(const GDBRemoteCommunicationServer &) = delete;
};
class PacketUnimplementedError
@@ -92,4 +94,4 @@ public:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServer_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVER_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 4b5fc0774a6d..08d489851799 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationServerCommon.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -334,7 +334,7 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
StringExtractorGDBRemote &packet) {
m_proc_infos_index = 0;
- m_proc_infos.Clear();
+ m_proc_infos.clear();
ProcessInstanceInfoMatch match_info;
packet.SetFilePos(::strlen("qfProcessInfo"));
@@ -416,10 +416,9 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
StringExtractorGDBRemote &packet) {
- if (m_proc_infos_index < m_proc_infos.GetSize()) {
+ if (m_proc_infos_index < m_proc_infos.size()) {
StreamString response;
- CreateProcessInfoResponse(
- m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
+ CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response);
++m_proc_infos_index;
return SendPacketNoLock(response.GetString());
}
@@ -843,6 +842,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported(
response.PutCString(";QThreadSuffixSupported+");
response.PutCString(";QListThreadsInStopReply+");
response.PutCString(";qEcho+");
+ response.PutCString(";qXfer:features:read+");
#if defined(__linux__) || defined(__NetBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
@@ -1228,7 +1228,7 @@ void GDBRemoteCommunicationServerCommon::
if (cpu_subtype != 0)
response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
- const std::string vendor = proc_triple.getVendorName();
+ const std::string vendor = proc_triple.getVendorName().str();
if (!vendor.empty())
response.Printf("vendor:%s;", vendor.c_str());
#else
@@ -1237,7 +1237,7 @@ void GDBRemoteCommunicationServerCommon::
response.PutStringAsRawHex8(proc_triple.getTriple());
response.PutChar(';');
#endif
- std::string ostype = proc_triple.getOSName();
+ std::string ostype = std::string(proc_triple.getOSName());
// Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
if (proc_triple.getVendor() == llvm::Triple::Apple) {
switch (proc_triple.getArch()) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 525546312470..0f933c09cbd4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationServerCommon_h_
-#define liblldb_GDBRemoteCommunicationServerCommon_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H
#include <string>
@@ -152,4 +152,4 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServerCommon_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERCOMMON_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index f33f0ee66304..ae2f4bd041c9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationServerLLGS.cpp --------------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationServerLLGS.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -377,6 +377,99 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf,
}
}
+static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo &reg_info) {
+ switch (reg_info.encoding) {
+ case eEncodingUint:
+ return "uint";
+ case eEncodingSint:
+ return "sint";
+ case eEncodingIEEE754:
+ return "ieee754";
+ case eEncodingVector:
+ return "vector";
+ default:
+ return "";
+ }
+}
+
+static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo &reg_info) {
+ switch (reg_info.format) {
+ case eFormatBinary:
+ return "binary";
+ case eFormatDecimal:
+ return "decimal";
+ case eFormatHex:
+ return "hex";
+ case eFormatFloat:
+ return "float";
+ case eFormatVectorOfSInt8:
+ return "vector-sint8";
+ case eFormatVectorOfUInt8:
+ return "vector-uint8";
+ case eFormatVectorOfSInt16:
+ return "vector-sint16";
+ case eFormatVectorOfUInt16:
+ return "vector-uint16";
+ case eFormatVectorOfSInt32:
+ return "vector-sint32";
+ case eFormatVectorOfUInt32:
+ return "vector-uint32";
+ case eFormatVectorOfFloat32:
+ return "vector-float32";
+ case eFormatVectorOfUInt64:
+ return "vector-uint64";
+ case eFormatVectorOfUInt128:
+ return "vector-uint128";
+ default:
+ return "";
+ };
+}
+
+static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo &reg_info) {
+ switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return "pc";
+ case LLDB_REGNUM_GENERIC_SP:
+ return "sp";
+ case LLDB_REGNUM_GENERIC_FP:
+ return "fp";
+ case LLDB_REGNUM_GENERIC_RA:
+ return "ra";
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return "flags";
+ case LLDB_REGNUM_GENERIC_ARG1:
+ return "arg1";
+ case LLDB_REGNUM_GENERIC_ARG2:
+ return "arg2";
+ case LLDB_REGNUM_GENERIC_ARG3:
+ return "arg3";
+ case LLDB_REGNUM_GENERIC_ARG4:
+ return "arg4";
+ case LLDB_REGNUM_GENERIC_ARG5:
+ return "arg5";
+ case LLDB_REGNUM_GENERIC_ARG6:
+ return "arg6";
+ case LLDB_REGNUM_GENERIC_ARG7:
+ return "arg7";
+ case LLDB_REGNUM_GENERIC_ARG8:
+ return "arg8";
+ default:
+ return "";
+ }
+}
+
+static void CollectRegNums(const uint32_t *reg_num, StreamString &response,
+ bool usehex) {
+ for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ if (usehex)
+ response.Printf("%" PRIx32, *reg_num);
+ else
+ response.Printf("%" PRIu32, *reg_num);
+ }
+}
+
static void WriteRegisterValueInHexFixedWidth(
StreamString &response, NativeRegisterContext &reg_ctx,
const RegisterInfo &reg_info, const RegisterValue *reg_value_p,
@@ -922,9 +1015,9 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
}
Status GDBRemoteCommunicationServerLLGS::InitializeConnection(
- std::unique_ptr<Connection> &&connection) {
+ std::unique_ptr<Connection> connection) {
IOObjectSP read_object_sp = connection->GetReadObject();
- GDBRemoteCommunicationServer::SetConnection(connection.release());
+ GDBRemoteCommunicationServer::SetConnection(std::move(connection));
Status error;
m_network_handle_up = m_mainloop.RegisterReadObject(
@@ -960,7 +1053,7 @@ Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) {
}
m_stdio_communication.SetCloseOnEOF(false);
- m_stdio_communication.SetConnection(conn_up.release());
+ m_stdio_communication.SetConnection(std::move(conn_up));
if (!m_stdio_communication.IsConnected()) {
error.SetErrorString(
"failed to set connection for inferior I/O communication");
@@ -1072,7 +1165,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStart(
return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
options.setTraceParams(
- static_pointer_cast<StructuredData::Dictionary>(custom_params_sp));
+ std::static_pointer_cast<StructuredData::Dictionary>(custom_params_sp));
if (buffersize == std::numeric_limits<uint64_t>::max() ||
type != lldb::TraceType::eTraceTypeProcessorTrace) {
@@ -1699,74 +1792,18 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
reg_info->byte_size * 8, reg_info->byte_offset);
- switch (reg_info->encoding) {
- case eEncodingUint:
- response.PutCString("encoding:uint;");
- break;
- case eEncodingSint:
- response.PutCString("encoding:sint;");
- break;
- case eEncodingIEEE754:
- response.PutCString("encoding:ieee754;");
- break;
- case eEncodingVector:
- response.PutCString("encoding:vector;");
- break;
- default:
- break;
- }
+ llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
+ if (!encoding.empty())
+ response << "encoding:" << encoding << ';';
- switch (reg_info->format) {
- case eFormatBinary:
- response.PutCString("format:binary;");
- break;
- case eFormatDecimal:
- response.PutCString("format:decimal;");
- break;
- case eFormatHex:
- response.PutCString("format:hex;");
- break;
- case eFormatFloat:
- response.PutCString("format:float;");
- break;
- case eFormatVectorOfSInt8:
- response.PutCString("format:vector-sint8;");
- break;
- case eFormatVectorOfUInt8:
- response.PutCString("format:vector-uint8;");
- break;
- case eFormatVectorOfSInt16:
- response.PutCString("format:vector-sint16;");
- break;
- case eFormatVectorOfUInt16:
- response.PutCString("format:vector-uint16;");
- break;
- case eFormatVectorOfSInt32:
- response.PutCString("format:vector-sint32;");
- break;
- case eFormatVectorOfUInt32:
- response.PutCString("format:vector-uint32;");
- break;
- case eFormatVectorOfFloat32:
- response.PutCString("format:vector-float32;");
- break;
- case eFormatVectorOfUInt64:
- response.PutCString("format:vector-uint64;");
- break;
- case eFormatVectorOfUInt128:
- response.PutCString("format:vector-uint128;");
- break;
- default:
- break;
- };
+ llvm::StringRef format = GetFormatNameOrEmpty(*reg_info);
+ if (!format.empty())
+ response << "format:" << format << ';';
const char *const register_set_name =
reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
- if (register_set_name) {
- response.PutCString("set:");
- response.PutCString(register_set_name);
- response.PutChar(';');
- }
+ if (register_set_name)
+ response << "set:" << register_set_name << ';';
if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
LLDB_INVALID_REGNUM)
@@ -1777,71 +1814,19 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
response.Printf("dwarf:%" PRIu32 ";",
reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
- switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
- case LLDB_REGNUM_GENERIC_PC:
- response.PutCString("generic:pc;");
- break;
- case LLDB_REGNUM_GENERIC_SP:
- response.PutCString("generic:sp;");
- break;
- case LLDB_REGNUM_GENERIC_FP:
- response.PutCString("generic:fp;");
- break;
- case LLDB_REGNUM_GENERIC_RA:
- response.PutCString("generic:ra;");
- break;
- case LLDB_REGNUM_GENERIC_FLAGS:
- response.PutCString("generic:flags;");
- break;
- case LLDB_REGNUM_GENERIC_ARG1:
- response.PutCString("generic:arg1;");
- break;
- case LLDB_REGNUM_GENERIC_ARG2:
- response.PutCString("generic:arg2;");
- break;
- case LLDB_REGNUM_GENERIC_ARG3:
- response.PutCString("generic:arg3;");
- break;
- case LLDB_REGNUM_GENERIC_ARG4:
- response.PutCString("generic:arg4;");
- break;
- case LLDB_REGNUM_GENERIC_ARG5:
- response.PutCString("generic:arg5;");
- break;
- case LLDB_REGNUM_GENERIC_ARG6:
- response.PutCString("generic:arg6;");
- break;
- case LLDB_REGNUM_GENERIC_ARG7:
- response.PutCString("generic:arg7;");
- break;
- case LLDB_REGNUM_GENERIC_ARG8:
- response.PutCString("generic:arg8;");
- break;
- default:
- break;
- }
+ llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info);
+ if (!kind_generic.empty())
+ response << "generic:" << kind_generic << ';';
if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
response.PutCString("container-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->value_regs;
- *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
- if (i > 0)
- response.PutChar(',');
- response.Printf("%" PRIx32, *reg_num);
- }
+ CollectRegNums(reg_info->value_regs, response, true);
response.PutChar(';');
}
if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
response.PutCString("invalidate-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->invalidate_regs;
- *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
- if (i > 0)
- response.PutChar(',');
- response.Printf("%" PRIx32, *reg_num);
- }
+ CollectRegNums(reg_info->invalidate_regs, response, true);
response.PutChar(';');
}
@@ -2055,7 +2040,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
packet, "P packet missing '=' char after register number");
// Parse out the value.
- uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+ uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize];
size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
// Get the thread to use.
@@ -2510,7 +2495,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
ConstString name = region_info.GetName();
if (name) {
response.PutCString("name:");
- response.PutStringAsRawHex8(name.AsCString());
+ response.PutStringAsRawHex8(name.GetStringRef());
response.PutChar(';');
}
}
@@ -2751,16 +2736,118 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
}
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
+ // Ensure we have a thread.
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ if (!thread)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No thread available");
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ // Get the register context for the first thread.
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
+
+ StreamString response;
+
+ response.Printf("<?xml version=\"1.0\"?>");
+ response.Printf("<target version=\"1.0\">");
+
+ response.Printf("<architecture>%s</architecture>",
+ m_debugged_process_up->GetArchitecture()
+ .GetTriple()
+ .getArchName()
+ .str()
+ .c_str());
+
+ response.Printf("<feature>");
+
+ const int registers_count = reg_context.GetUserRegisterCount();
+ for (int reg_index = 0; reg_index < registers_count; reg_index++) {
+ const RegisterInfo *reg_info =
+ reg_context.GetRegisterInfoAtIndex(reg_index);
+
+ if (!reg_info) {
+ LLDB_LOGF(log,
+ "%s failed to get register info for register index %" PRIu32,
+ "target.xml", reg_index);
+ continue;
+ }
+
+ response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" offset=\"%" PRIu32
+ "\" regnum=\"%d\" ",
+ reg_info->name, reg_info->byte_size * 8,
+ reg_info->byte_offset, reg_index);
+
+ if (reg_info->alt_name && reg_info->alt_name[0])
+ response.Printf("altname=\"%s\" ", reg_info->alt_name);
+
+ llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
+ if (!encoding.empty())
+ response << "encoding=\"" << encoding << "\" ";
+
+ llvm::StringRef format = GetFormatNameOrEmpty(*reg_info);
+ if (!format.empty())
+ response << "format=\"" << format << "\" ";
+
+ const char *const register_set_name =
+ reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
+ if (register_set_name)
+ response << "group=\"" << register_set_name << "\" ";
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("ehframe_regnum=\"%" PRIu32 "\" ",
+ reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("dwarf_regnum=\"%" PRIu32 "\" ",
+ reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
+
+ llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info);
+ if (!kind_generic.empty())
+ response << "generic=\"" << kind_generic << "\" ";
+
+ if (reg_info->value_regs &&
+ reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
+ response.PutCString("value_regnums=\"");
+ CollectRegNums(reg_info->value_regs, response, false);
+ response.Printf("\" ");
+ }
+
+ if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
+ response.PutCString("invalidate_regnums=\"");
+ CollectRegNums(reg_info->invalidate_regs, response, false);
+ response.Printf("\" ");
+ }
+
+ if (reg_info->dynamic_size_dwarf_expr_bytes) {
+ const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
+ response.PutCString("dynamic_size_dwarf_expr_bytes=\"");
+ for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
+ response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
+ response.Printf("\" ");
+ }
+
+ response.Printf("/>");
+ }
+
+ response.Printf("</feature>");
+ response.Printf("</target>");
+ return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml");
+}
+
+llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
llvm::StringRef annex) {
- if (object == "auxv") {
- // Make sure we have a valid process.
- if (!m_debugged_process_up ||
- (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "No process available");
- }
+ // Make sure we have a valid process.
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No process available");
+ }
+ if (object == "auxv") {
// Grab the auxv data.
auto buffer_or_error = m_debugged_process_up->GetAuxvData();
if (!buffer_or_error)
@@ -2786,6 +2873,9 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
}
+ if (object == "features" && annex == "target.xml")
+ return BuildTargetXml();
+
return llvm::make_error<PacketUnimplementedError>(
"Xfer object not supported");
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 088ba92ad11a..3ce285910c25 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_
-#define liblldb_GDBRemoteCommunicationServerLLGS_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H
#include <mutex>
#include <unordered_map>
@@ -67,7 +67,7 @@ public:
void DidExec(NativeProcessProtocol *process) override;
- Status InitializeConnection(std::unique_ptr<Connection> &&connection);
+ Status InitializeConnection(std::unique_ptr<Connection> connection);
protected:
MainLoop &m_mainloop;
@@ -199,6 +199,8 @@ protected:
static std::string XMLEncodeAttributeValue(llvm::StringRef value);
private:
+ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml();
+
void HandleInferiorState_Exited(NativeProcessProtocol *process);
void HandleInferiorState_Stopped(NativeProcessProtocol *process);
@@ -222,10 +224,13 @@ private:
void StopSTDIOForwarding();
// For GDBRemoteCommunicationServerLLGS only
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS);
+ GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) =
+ delete;
+ const GDBRemoteCommunicationServerLLGS &
+ operator=(const GDBRemoteCommunicationServerLLGS &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERLLGS_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 25cebbba8f7b..d14b79a03d17 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteCommunicationServerPlatform.cpp ----------------*- C++ -*-===//
+//===-- GDBRemoteCommunicationServerPlatform.cpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -173,7 +173,7 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
uint16_t port = UINT16_MAX;
while (packet.GetNameColonValue(name, value)) {
if (name.equals("host"))
- hostname = value;
+ hostname = std::string(value);
else if (name.equals("port"))
value.getAsInteger(0, port);
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index eacc99a012db..a8cacea78835 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_
-#define liblldb_GDBRemoteCommunicationServerPlatform_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H
#include <map>
#include <mutex>
@@ -100,10 +100,13 @@ private:
static FileSpec GetDomainSocketPath(const char *prefix);
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform);
+ GDBRemoteCommunicationServerPlatform(
+ const GDBRemoteCommunicationServerPlatform &) = delete;
+ const GDBRemoteCommunicationServerPlatform &
+ operator=(const GDBRemoteCommunicationServerPlatform &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServerPlatform_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONSERVERPLATFORM_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index ec1a54afd727..1f31b45d0fa9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -1,4 +1,4 @@
-//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===//
+//===-- GDBRemoteRegisterContext.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index b42c87b5991b..015862587103 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_GDBRemoteRegisterContext_h_
-#define lldb_GDBRemoteRegisterContext_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H
#include <vector>
@@ -88,9 +88,7 @@ protected:
void SetAllRegisterValid(bool b);
bool GetRegisterIsValid(uint32_t reg) const {
-#if defined(LLDB_CONFIGURATION_DEBUG)
assert(reg < m_reg_valid.size());
-#endif
if (reg < m_reg_valid.size())
return m_reg_valid[reg];
return false;
@@ -103,9 +101,7 @@ protected:
}
void SetRegisterIsValid(uint32_t reg, bool valid) {
-#if defined(LLDB_CONFIGURATION_DEBUG)
assert(reg < m_reg_valid.size());
-#endif
if (reg < m_reg_valid.size())
m_reg_valid[reg] = valid;
}
@@ -124,10 +120,12 @@ private:
bool SetPrimordialRegister(const RegisterInfo *reg_info,
GDBRemoteCommunicationClient &gdb_comm);
- DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
+ GDBRemoteRegisterContext(const GDBRemoteRegisterContext &) = delete;
+ const GDBRemoteRegisterContext &
+ operator=(const GDBRemoteRegisterContext &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // lldb_GDBRemoteRegisterContext_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERCONTEXT_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index a49db5d9a934..1fed8e064267 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessGDBRemote.cpp ------------------------------------*- C++ -*-===//
+//===-- ProcessGDBRemote.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -17,6 +17,9 @@
#include <unistd.h>
#endif
#include <sys/stat.h>
+#if defined(__APPLE__)
+#include <sys/sysctl.h>
+#endif
#include <sys/types.h>
#include <time.h>
@@ -90,6 +93,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+LLDB_PLUGIN_DEFINE(ProcessGDBRemote)
+
namespace lldb {
// Provide a function that can easily dump the packet history if we know a
// ProcessGDBRemote * value (which we can get from logs or from debugging). We
@@ -184,21 +189,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
#define HIGH_PORT (49151u)
#endif
-#if defined(__APPLE__) && \
- (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
-static bool rand_initialized = false;
-
-static inline uint16_t get_random_port() {
- if (!rand_initialized) {
- time_t seed = time(NULL);
-
- rand_initialized = true;
- srand(seed);
- }
- return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
-}
-#endif
-
ConstString ProcessGDBRemote::GetPluginNameStatic() {
static ConstString g_name("gdb-remote");
return g_name;
@@ -359,7 +349,8 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
StructuredData::ObjectSP triple_value =
host_info_dict->GetValueForKey("triple");
if (auto triple_string_value = triple_value->GetAsString()) {
- std::string triple_string = triple_string_value->GetValue();
+ std::string triple_string =
+ std::string(triple_string_value->GetValue());
ArchSpec host_arch(triple_string.c_str());
if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) {
GetTarget().SetArchitecture(host_arch);
@@ -638,15 +629,17 @@ Status ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
return WillLaunchOrAttach();
}
-Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
- llvm::StringRef remote_url) {
+Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error(WillLaunchOrAttach());
if (error.Fail())
return error;
- error = ConnectToDebugserver(remote_url);
+ if (repro::Reproducer::Instance().IsReplaying())
+ error = ConnectToReplayServer();
+ else
+ error = ConnectToDebugserver(remote_url);
if (error.Fail())
return error;
@@ -824,22 +817,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
// since 'O' packets can really slow down debugging if the inferior
// does a lot of output.
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
- pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, nullptr, 0)) {
- FileSpec slave_name{pty.GetSlaveName(nullptr, 0)};
+ pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY, nullptr, 0)) {
+ FileSpec secondary_name{pty.GetSecondaryName(nullptr, 0)};
if (!stdin_file_spec)
- stdin_file_spec = slave_name;
+ stdin_file_spec = secondary_name;
if (!stdout_file_spec)
- stdout_file_spec = slave_name;
+ stdout_file_spec = secondary_name;
if (!stderr_file_spec)
- stderr_file_spec = slave_name;
+ stderr_file_spec = secondary_name;
}
LLDB_LOGF(
log,
"ProcessGDBRemote::%s adjusted STDIO paths for local platform "
- "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+ "(IsHost() is true) using secondary: stdin=%s, stdout=%s, "
+ "stderr=%s",
__FUNCTION__,
stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
@@ -924,8 +918,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
SetPrivateState(SetThreadStopInfo(response));
if (!disable_stdio) {
- if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd)
- SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
+ if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd)
+ SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor());
}
}
} else {
@@ -957,7 +951,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
uint32_t retry_count = 0;
while (!m_gdb_comm.IsConnected()) {
if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) {
- m_gdb_comm.SetConnection(conn_up.release());
+ m_gdb_comm.SetConnection(std::move(conn_up));
break;
} else if (error.WasInterrupted()) {
// If we were interrupted, don't keep retrying.
@@ -1023,122 +1017,113 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);
- if (GetID() != LLDB_INVALID_PROCESS_ID) {
- BuildDynamicRegisterInfo(false);
+ BuildDynamicRegisterInfo(false);
- // See if the GDB server supports the qHostInfo information
+ // See if the GDB server supports qHostInfo or qProcessInfo packets. Prefer
+ // qProcessInfo as it will be more specific to our process.
- // See if the GDB server supports the qProcessInfo packet, if so prefer
- // that over the Host information as it will be more specific to our
- // process.
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+ if (remote_process_arch.IsValid()) {
+ process_arch = remote_process_arch;
+ LLDB_LOG(log, "gdb-remote had process architecture, using {0} {1}",
+ process_arch.GetArchitectureName(),
+ process_arch.GetTriple().getTriple());
+ } else {
+ process_arch = m_gdb_comm.GetHostArchitecture();
+ LLDB_LOG(log,
+ "gdb-remote did not have process architecture, using gdb-remote "
+ "host architecture {0} {1}",
+ process_arch.GetArchitectureName(),
+ process_arch.GetTriple().getTriple());
+ }
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
- if (remote_process_arch.IsValid()) {
- process_arch = remote_process_arch;
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s gdb-remote had process architecture, "
- "using %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
- } else {
- process_arch = m_gdb_comm.GetHostArchitecture();
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s gdb-remote did not have process "
- "architecture, using gdb-remote host architecture %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
- }
+ if (process_arch.IsValid()) {
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ if (target_arch.IsValid()) {
+ LLDB_LOG(log, "analyzing target arch, currently {0} {1}",
+ target_arch.GetArchitectureName(),
+ target_arch.GetTriple().getTriple());
+
+ // If the remote host is ARM and we have apple as the vendor, then
+ // ARM executables and shared libraries can have mixed ARM
+ // architectures.
+ // You can have an armv6 executable, and if the host is armv7, then the
+ // system will load the best possible architecture for all shared
+ // libraries it has, so we really need to take the remote host
+ // architecture as our defacto architecture in this case.
+
+ if ((process_arch.GetMachine() == llvm::Triple::arm ||
+ process_arch.GetMachine() == llvm::Triple::thumb) &&
+ process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
+ GetTarget().SetArchitecture(process_arch);
+ LLDB_LOG(log,
+ "remote process is ARM/Apple, "
+ "setting target arch to {0} {1}",
+ process_arch.GetArchitectureName(),
+ process_arch.GetTriple().getTriple());
+ } else {
+ // Fill in what is missing in the triple
+ const llvm::Triple &remote_triple = process_arch.GetTriple();
+ llvm::Triple new_target_triple = target_arch.GetTriple();
+ if (new_target_triple.getVendorName().size() == 0) {
+ new_target_triple.setVendor(remote_triple.getVendor());
- if (process_arch.IsValid()) {
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- if (target_arch.IsValid()) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
- target_arch.GetTriple().getTriple().c_str()
- ? target_arch.GetTriple().getTriple().c_str()
- : "<null>");
-
- // If the remote host is ARM and we have apple as the vendor, then
- // ARM executables and shared libraries can have mixed ARM
- // architectures.
- // You can have an armv6 executable, and if the host is armv7, then the
- // system will load the best possible architecture for all shared
- // libraries it has, so we really need to take the remote host
- // architecture as our defacto architecture in this case.
-
- if ((process_arch.GetMachine() == llvm::Triple::arm ||
- process_arch.GetMachine() == llvm::Triple::thumb) &&
- process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
- GetTarget().SetArchitecture(process_arch);
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s remote process is ARM/Apple, "
- "setting target arch to %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
- process_arch.GetTriple().getTriple().c_str()
- ? process_arch.GetTriple().getTriple().c_str()
- : "<null>");
- } else {
- // Fill in what is missing in the triple
- const llvm::Triple &remote_triple = process_arch.GetTriple();
- llvm::Triple new_target_triple = target_arch.GetTriple();
- if (new_target_triple.getVendorName().size() == 0) {
- new_target_triple.setVendor(remote_triple.getVendor());
-
- if (new_target_triple.getOSName().size() == 0) {
- new_target_triple.setOS(remote_triple.getOS());
-
- if (new_target_triple.getEnvironmentName().size() == 0)
- new_target_triple.setEnvironment(
- remote_triple.getEnvironment());
- }
+ if (new_target_triple.getOSName().size() == 0) {
+ new_target_triple.setOS(remote_triple.getOS());
- ArchSpec new_target_arch = target_arch;
- new_target_arch.SetTriple(new_target_triple);
- GetTarget().SetArchitecture(new_target_arch);
+ if (new_target_triple.getEnvironmentName().size() == 0)
+ new_target_triple.setEnvironment(remote_triple.getEnvironment());
}
- }
- LLDB_LOGF(log,
- "ProcessGDBRemote::%s final target arch after "
- "adjustments for remote architecture: %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
- target_arch.GetTriple().getTriple().c_str()
- ? target_arch.GetTriple().getTriple().c_str()
- : "<null>");
- } else {
- // The target doesn't have a valid architecture yet, set it from the
- // architecture we got from the remote GDB server
- GetTarget().SetArchitecture(process_arch);
+ ArchSpec new_target_arch = target_arch;
+ new_target_arch.SetTriple(new_target_triple);
+ GetTarget().SetArchitecture(new_target_arch);
+ }
}
+
+ LLDB_LOG(log,
+ "final target arch after adjustments for remote architecture: "
+ "{0} {1}",
+ target_arch.GetArchitectureName(),
+ target_arch.GetTriple().getTriple());
+ } else {
+ // The target doesn't have a valid architecture yet, set it from the
+ // architecture we got from the remote GDB server
+ GetTarget().SetArchitecture(process_arch);
}
+ }
+
+ MaybeLoadExecutableModule();
+
+ // Find out which StructuredDataPlugins are supported by the debug monitor.
+ // These plugins transmit data over async $J packets.
+ if (StructuredData::Array *supported_packets =
+ m_gdb_comm.GetSupportedStructuredDataPlugins())
+ MapSupportedStructuredDataPlugins(*supported_packets);
+}
+
+void ProcessGDBRemote::MaybeLoadExecutableModule() {
+ ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (!module_sp)
+ return;
+
+ llvm::Optional<QOffsets> offsets = m_gdb_comm.GetQOffsets();
+ if (!offsets)
+ return;
- // Find out which StructuredDataPlugins are supported by the debug monitor.
- // These plugins transmit data over async $J packets.
- auto supported_packets_array =
- m_gdb_comm.GetSupportedStructuredDataPlugins();
- if (supported_packets_array)
- MapSupportedStructuredDataPlugins(*supported_packets_array);
+ bool is_uniform =
+ size_t(llvm::count(offsets->offsets, offsets->offsets[0])) ==
+ offsets->offsets.size();
+ if (!is_uniform)
+ return; // TODO: Handle non-uniform responses.
+
+ bool changed = false;
+ module_sp->SetLoadAddress(GetTarget(), offsets->offsets[0],
+ /*value_is_offset=*/true, changed);
+ if (changed) {
+ ModuleList list;
+ list.Append(module_sp);
+ m_process->GetTarget().ModulesDidLoad(list);
}
}
@@ -1576,7 +1561,8 @@ bool ProcessGDBRemote::UpdateThreadIDList() {
for (int i = 0; i < nItems; i++) {
// Get the thread stop info
StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
- const std::string &stop_info_str = stop_info.GetStringRef();
+ const std::string &stop_info_str =
+ std::string(stop_info.GetStringRef());
m_thread_pcs.clear();
const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
@@ -2040,14 +2026,14 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
});
}
} else if (key == g_key_name) {
- thread_name = object->GetStringValue();
+ thread_name = std::string(object->GetStringValue());
} else if (key == g_key_qaddr) {
thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
} else if (key == g_key_queue_name) {
queue_vars_valid = true;
- queue_name = object->GetStringValue();
+ queue_name = std::string(object->GetStringValue());
} else if (key == g_key_queue_kind) {
- std::string queue_kind_str = object->GetStringValue();
+ std::string queue_kind_str = std::string(object->GetStringValue());
if (queue_kind_str == "serial") {
queue_vars_valid = true;
queue_kind = eQueueKindSerial;
@@ -2071,9 +2057,9 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
else
associated_with_dispatch_queue = eLazyBoolNo;
} else if (key == g_key_reason) {
- reason = object->GetStringValue();
+ reason = std::string(object->GetStringValue());
} else if (key == g_key_description) {
- description = object->GetStringValue();
+ description = std::string(object->GetStringValue());
} else if (key == g_key_registers) {
StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
@@ -2084,7 +2070,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
const uint32_t reg =
StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10);
if (reg != UINT32_MAX)
- expedited_register_map[reg] = object->GetStringValue();
+ expedited_register_map[reg] =
+ std::string(object->GetStringValue());
return true; // Keep iterating through all array items
});
}
@@ -2227,7 +2214,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
// Now convert the HEX bytes into a string value
name_extractor.GetHexByteString(thread_name);
} else if (key.compare("name") == 0) {
- thread_name = value;
+ thread_name = std::string(value);
} else if (key.compare("qaddr") == 0) {
value.getAsInteger(16, thread_dispatch_qaddr);
} else if (key.compare("dispatch_queue_t") == 0) {
@@ -2248,7 +2235,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
if (!value.getAsInteger(0, queue_serial_number))
queue_vars_valid = true;
} else if (key.compare("reason") == 0) {
- reason = value;
+ reason = std::string(value);
} else if (key.compare("description") == 0) {
StringExtractor desc_extractor(value);
// Now convert the HEX bytes into a string value
@@ -2297,7 +2284,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
reason = "watchpoint";
StreamString ostr;
ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
- description = ostr.GetString();
+ description = std::string(ostr.GetString());
} else if (key.compare("library") == 0) {
auto error = LoadModules();
if (error) {
@@ -2308,7 +2295,7 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
} else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
uint32_t reg = UINT32_MAX;
if (!key.getAsInteger(16, reg))
- expedited_register_map[reg] = std::move(value);
+ expedited_register_map[reg] = std::string(std::move(value));
}
}
@@ -2585,7 +2572,7 @@ Status ProcessGDBRemote::DoDestroy() {
"to k packet: %s",
response.GetStringRef().data());
exit_string.assign("got unexpected response to k packet: ");
- exit_string.append(response.GetStringRef());
+ exit_string.append(std::string(response.GetStringRef()));
}
} else {
LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet");
@@ -3127,7 +3114,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
if (error_no != UINT8_MAX)
error.SetErrorStringWithFormat(
- "error: %d sending the breakpoint request", errno);
+ "error: %d sending the breakpoint request", error_no);
else
error.SetErrorString("error sending the breakpoint request");
return error;
@@ -3356,30 +3343,10 @@ Status ProcessGDBRemote::DoSignal(int signo) {
return error;
}
-Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
- if (!loader)
- return Status("No loader provided.");
-
- static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
- multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
- repro::Reproducer::Instance().GetLoader());
-
- if (!multi_loader)
- return Status("No gdb remote provider found.");
-
- llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
- if (!history_file)
- return Status("No gdb remote packet log found.");
-
- // Load replay history.
- if (auto error =
- m_gdb_replay_server.LoadReplayHistory(FileSpec(*history_file)))
- return Status("Unable to load replay history");
-
- // Make a local connection.
- if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm,
- m_gdb_replay_server))
- return Status("Unable to connect to replay server");
+Status ProcessGDBRemote::ConnectToReplayServer() {
+ Status status = m_gdb_replay_server.Connect(m_gdb_comm);
+ if (status.Fail())
+ return status;
// Enable replay mode.
m_replay_mode = true;
@@ -3404,8 +3371,8 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
if (platform_sp && !platform_sp->IsHost())
return Status("Lost debug server connection");
- if (repro::Loader *loader = repro::Reproducer::Instance().GetLoader())
- return ConnectToReplayServer(loader);
+ if (repro::Reproducer::Instance().IsReplaying())
+ return ConnectToReplayServer();
auto error = LaunchAndConnectToDebugserver(process_info);
if (error.Fail()) {
@@ -3452,6 +3419,23 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
+#if defined(__APPLE__)
+ // On macOS 11, we need to support x86_64 applications translated to
+ // arm64. We check whether a binary is translated and spawn the correct
+ // debugserver accordingly.
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
+ static_cast<int>(process_info.GetProcessID()) };
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo,
+ &bufsize, NULL, 0) == 0 && bufsize > 0) {
+ if (processInfo.kp_proc.p_flag & P_TRANSLATED) {
+ FileSpec rosetta_debugserver("/Library/Apple/usr/libexec/oah/debugserver");
+ debugserver_launch_info.SetExecutableFile(rosetta_debugserver, false);
+ }
+ }
+#endif
+
int communication_fd = -1;
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
// Use a socketpair on non-Windows systems for security and performance
@@ -3486,7 +3470,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
// Our process spawned correctly, we can now set our connection to use
// our end of the socket pair
cleanup_our.release();
- m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true));
+ m_gdb_comm.SetConnection(
+ std::make_unique<ConnectionFileDescriptor>(our_socket, true));
#endif
StartAsyncThread();
}
@@ -3648,7 +3633,7 @@ void ProcessGDBRemote::StopAsyncThread() {
bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
// get the packet at a string
- const std::string &pkt = packet.GetStringRef();
+ const std::string &pkt = std::string(packet.GetStringRef());
// skip %stop:
StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
@@ -3794,7 +3779,7 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
} // switch(stop_state)
} // else // if in All-stop-mode
} // if (continue_packet)
- } // case eBroadcastBitAysncContinue
+ } // case eBroadcastBitAsyncContinue
break;
case eBroadcastBitAsyncThreadShouldExit:
@@ -4030,7 +4015,8 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) {
if (!response.Empty()) {
- object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
}
}
}
@@ -4102,7 +4088,8 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) {
if (!response.Empty()) {
- object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
}
}
}
@@ -4135,7 +4122,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse) {
if (!response.Empty()) {
- object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ object_sp =
+ StructuredData::ParseJSON(std::string(response.GetStringRef()));
}
}
}
@@ -4419,7 +4407,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
});
if (!gdb_type.empty() && !(encoding_set || format_set)) {
- if (gdb_type.find("int") == 0) {
+ if (llvm::StringRef(gdb_type).startswith("int")) {
reg_info.format = eFormatHex;
reg_info.encoding = eEncodingUint;
} else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
@@ -4682,7 +4670,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
// value.
module.set_base_is_offset(true);
} else if (name == "l_ld") {
- // the memory address of the libraries PT_DYAMIC section.
+ // the memory address of the libraries PT_DYNAMIC section.
module.set_dynamic(StringConvert::ToUInt64(
value.data(), LLDB_INVALID_ADDRESS, 0));
}
@@ -5069,7 +5057,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
}
// This is an asynchronous JSON packet, destined for a StructuredDataPlugin.
- StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet);
+ StructuredData::ObjectSP json_sp =
+ StructuredData::ParseJSON(std::string(packet));
if (log) {
if (json_sp) {
StreamString json_str;
@@ -5276,7 +5265,7 @@ public:
result.SetStatus(eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf(" packet: %s\n", packet_cstr);
- std::string response_str = response.GetStringRef();
+ std::string response_str = std::string(response.GetStringRef());
if (strstr(packet_cstr, "qGetProfileData") != nullptr) {
response_str = process->HarmonizeThreadIdsForProfileData(response);
@@ -5329,7 +5318,7 @@ public:
[&output_strm](llvm::StringRef output) { output_strm << output; });
result.SetStatus(eReturnStatusSuccessFinishResult);
output_strm.Printf(" packet: %s\n", packet.GetData());
- const std::string &response_str = response.GetStringRef();
+ const std::string &response_str = std::string(response.GetStringRef());
if (response_str.empty())
output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 9ea3940103b6..ba967727ae3b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ProcessGDBRemote_h_
-#define liblldb_ProcessGDBRemote_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H
#include <atomic>
#include <map>
@@ -85,7 +85,7 @@ public:
Status WillAttachToProcessWithName(const char *process_name,
bool wait_for_launch) override;
- Status DoConnectRemote(Stream *strm, llvm::StringRef remote_url) override;
+ Status DoConnectRemote(llvm::StringRef remote_url) override;
Status WillLaunchOrAttach();
@@ -312,7 +312,7 @@ protected:
bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status ConnectToReplayServer(repro::Loader *loader);
+ Status ConnectToReplayServer();
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info);
@@ -377,6 +377,7 @@ protected:
bool UpdateThreadIDList();
void DidLaunchOrAttach(ArchSpec &process_arch);
+ void MaybeLoadExecutableModule();
Status ConnectToDebugserver(llvm::StringRef host_port);
@@ -386,7 +387,7 @@ protected:
DynamicLoader *GetDynamicLoader() override;
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
- std::string xml_filename,
+ std::string xml_filename,
uint32_t &cur_reg_num,
uint32_t &reg_offset);
@@ -449,10 +450,11 @@ private:
llvm::DenseMap<ModuleCacheKey, ModuleSpec, ModuleCacheInfo>
m_cached_module_specs;
- DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote);
+ ProcessGDBRemote(const ProcessGDBRemote &) = delete;
+ const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete;
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_ProcessGDBRemote_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTE_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index 8cadc45824b3..40990ef66494 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessGDBRemoteLog.cpp ---------------------------------*- C++ -*-===//
+//===-- ProcessGDBRemoteLog.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index d9b8d4536afe..bd3e993cf72a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ProcessGDBRemoteLog_h_
-#define liblldb_ProcessGDBRemoteLog_h_
-
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
#include "lldb/Utility/Log.h"
@@ -43,4 +42,4 @@ public:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_ProcessGDBRemoteLog_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_PROCESSGDBREMOTELOG_H
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
index 9cbe3d40ca2c..d4c3c8b94b7e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -11,8 +11,8 @@ let Definition = "processgdbremote" in {
Desc<"The file that provides the description for remote target registers.">;
def UseSVR4: Property<"use-libraries-svr4", "Boolean">,
Global,
- DefaultFalse,
- Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules.">;
+ DefaultTrue,
+ Desc<"If true, the libraries-svr4 feature will be used to get a hold of the process's loaded modules. This setting is only effective if lldb was build with xml support.">;
def UseGPacketForReading: Property<"use-g-packet-for-reading", "Boolean">,
Global,
DefaultFalse,
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 9da481979f73..6deabf8d5d71 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -1,4 +1,4 @@
-//===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===//
+//===-- ThreadGDBRemote.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -311,9 +311,7 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
read_all_registers_at_once, write_all_registers_at_once);
}
} else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index c74be169abaf..5ad11170fec4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ThreadGDBRemote_h_
-#define liblldb_ThreadGDBRemote_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H
#include <string>
@@ -116,4 +116,4 @@ protected:
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_ThreadGDBRemote_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_THREADGDBREMOTE_H
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 3c0e1cb49d1d..0c7f4cbbb859 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -1,4 +1,4 @@
-//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
+//===-- MinidumpParser.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index 4bcb2b47d45a..c4d7612b5f8d 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_MinidumpParser_h_
-#define liblldb_MinidumpParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
#include "MinidumpTypes.h"
@@ -100,7 +100,6 @@ private:
MinidumpParser(lldb::DataBufferSP data_sp,
std::unique_ptr<llvm::object::MinidumpFile> file);
-private:
lldb::DataBufferSP m_data_sp;
std::unique_ptr<llvm::object::MinidumpFile> m_file;
ArchSpec m_arch;
@@ -108,4 +107,4 @@ private:
} // end namespace minidump
} // end namespace lldb_private
-#endif // liblldb_MinidumpParser_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp b/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
index ed00b1cc07db..abddd79ad7dc 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -1,4 +1,4 @@
-//===-- MinidumpTypes.cpp ---------------------------------------*- C++ -*-===//
+//===-- MinidumpTypes.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
index a9c807930ebf..a7ac65120e2b 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_MinidumpTypes_h_
-#define liblldb_MinidumpTypes_h_
-
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H
#include "lldb/Utility/Status.h"
@@ -120,4 +119,4 @@ private:
} // namespace minidump
} // namespace lldb_private
-#endif // liblldb_MinidumpTypes_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPTYPES_H
diff --git a/lldb/source/Plugins/Process/minidump/NtStructures.h b/lldb/source/Plugins/Process/minidump/NtStructures.h
index fdb0cfb7981e..1dafbe4a4f50 100644
--- a/lldb/source/Plugins/Process/minidump/NtStructures.h
+++ b/lldb/source/Plugins/Process/minidump/NtStructures.h
@@ -1,3 +1,7 @@
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_NTSTRUCTURES_H
+
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_NTSTRUCTURES_H
+
//===-- NtStructures.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -34,3 +38,5 @@ struct TEB64 {
#endif // liblldb_Plugins_Process_Minidump_NtStructures_h_
} // namespace minidump
} // namespace lldb_private
+
+#endif
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 5c090dc6e12f..fc8ee346f449 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -1,4 +1,4 @@
-//===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===//
+//===-- ProcessMinidump.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -41,6 +41,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace minidump;
+LLDB_PLUGIN_DEFINE(ProcessMinidump)
+
namespace {
/// A minimal ObjectFile implementation providing a dummy object file for the
@@ -226,8 +228,10 @@ Status ProcessMinidump::DoLoadCore() {
llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid();
if (!pid) {
- error.SetErrorString("failed to parse PID");
- return error;
+ GetTarget().GetDebugger().GetAsyncErrorStream()->PutCString(
+ "Unable to retrieve process ID from minidump file, setting process ID "
+ "to 1.\n");
+ pid = 1;
}
SetID(pid.getValue());
@@ -253,7 +257,7 @@ void ProcessMinidump::RefreshStateAfterStop() {
// TODO: The definition and use of this "dump requested" constant
// in Breakpad are actually Linux-specific, and for similar use
- // cases on Mac/Windows it defines differnt constants, referring
+ // cases on Mac/Windows it defines different constants, referring
// to them as "simulated" exceptions; consider moving this check
// down to the OS-specific paths and checking each OS for its own
// constant.
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 750164cf8aaf..839b0e7563f7 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ProcessMinidump_h_
-#define liblldb_ProcessMinidump_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H
#include "MinidumpParser.h"
#include "MinidumpTypes.h"
@@ -119,4 +119,4 @@ private:
} // namespace minidump
} // namespace lldb_private
-#endif // liblldb_ProcessMinidump_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_PROCESSMINIDUMP_H
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
index 72dead07dcb4..eb48785263fc 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextMinidump_ARM.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
index 7af3b98a6fe7..857f9c0a3767 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMinidump_ARM_h_
-#define liblldb_RegisterContextMinidump_ARM_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H
#include "MinidumpTypes.h"
@@ -95,4 +95,4 @@ protected:
} // end namespace minidump
} // end namespace lldb_private
-#endif // liblldb_RegisterContextMinidump_ARM_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM_H
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
index bbd0e14a3267..c7809c5f19b6 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===//
+//===-- RegisterContextMinidump_ARM64.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
index f9e7f39eea60..8ae751095c04 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMinidump_ARM64_h_
-#define liblldb_RegisterContextMinidump_ARM64_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H
#include "MinidumpTypes.h"
@@ -79,4 +79,4 @@ protected:
} // end namespace minidump
} // end namespace lldb_private
-#endif // liblldb_RegisterContextMinidump_ARM64_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_ARM64_H
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
index 8ac2abb22093..38d7de77e3bf 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMinidump_x86_32.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextMinidump_x86_32.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
index d787f78ec7d3..9592d335eff7 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMinidump_x86_32_h_
-#define liblldb_RegisterContextMinidump_x86_32_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H
#include "MinidumpTypes.h"
@@ -132,4 +132,4 @@ enum class MinidumpContext_x86_32_Flags : uint32_t {
} // end namespace minidump
} // end namespace lldb_private
-#endif // liblldb_RegisterContextMinidump_x86_32_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
index 515ccf6b2c3c..3c593f0db6ec 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextMinidump_x86_64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextMinidump_x86_64.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
index 34ddd477a9d1..d920ea9d823f 100644
--- a/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
+++ b/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegisterContextMinidump_h_
-#define liblldb_RegisterContextMinidump_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
#include "MinidumpTypes.h"
@@ -177,4 +177,4 @@ enum class MinidumpContext_x86_64_Flags : uint32_t {
} // end namespace minidump
} // end namespace lldb_private
-#endif // liblldb_RegisterContextMinidump_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
diff --git a/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
index 5262de5a94c4..e146a1a1af92 100644
--- a/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -1,4 +1,4 @@
-//===-- ThreadMinidump.cpp --------------------------------------*- C++ -*-===//
+//===-- ThreadMinidump.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/Process/minidump/ThreadMinidump.h b/lldb/source/Plugins/Process/minidump/ThreadMinidump.h
index 44c41bc9f50e..aed7cfbc1b16 100644
--- a/lldb/source/Plugins/Process/minidump/ThreadMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ThreadMinidump_h_
-#define liblldb_ThreadMinidump_h_
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H
#include "MinidumpTypes.h"
@@ -42,4 +42,4 @@ protected:
} // namespace minidump
} // namespace lldb_private
-#endif // liblldb_ThreadMinidump_h_
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_THREADMINIDUMP_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index ecee8cc674f8..acd6128d84c5 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -57,3 +57,35 @@ llvm::Error Lua::LoadModule(llvm::StringRef filename) {
lua_setglobal(m_lua_state, module_name.GetCString());
return llvm::Error::success();
}
+
+llvm::Error Lua::ChangeIO(FILE *out, FILE *err) {
+ assert(out != nullptr);
+ assert(err != nullptr);
+
+ lua_getglobal(m_lua_state, "io");
+
+ lua_getfield(m_lua_state, -1, "stdout");
+ if (luaL_Stream *s = static_cast<luaL_Stream *>(
+ luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
+ s->f = out;
+ lua_pop(m_lua_state, 1);
+ } else {
+ lua_pop(m_lua_state, 2);
+ return llvm::make_error<llvm::StringError>("could not get stdout",
+ llvm::inconvertibleErrorCode());
+ }
+
+ lua_getfield(m_lua_state, -1, "stderr");
+ if (luaL_Stream *s = static_cast<luaL_Stream *>(
+ luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
+ s->f = out;
+ lua_pop(m_lua_state, 1);
+ } else {
+ lua_pop(m_lua_state, 2);
+ return llvm::make_error<llvm::StringError>("could not get stderr",
+ llvm::inconvertibleErrorCode());
+ }
+
+ lua_pop(m_lua_state, 1);
+ return llvm::Error::success();
+}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
index f2984a925dfe..300115aac8a7 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -38,6 +38,7 @@ public:
llvm::Error Run(llvm::StringRef buffer);
llvm::Error LoadModule(llvm::StringRef filename);
+ llvm::Error ChangeIO(FILE *out, FILE *err);
private:
lua_State *m_lua_state;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 701d68d1ec08..8cbeac4563c3 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -1,4 +1,4 @@
-//===-- ScriptInterpreterLua.cpp --------------------------------*- C++ -*-===//
+//===-- ScriptInterpreterLua.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -15,10 +15,13 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/Support/FormatAdapters.h"
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ScriptInterpreterLua)
+
class IOHandlerLuaInterpreter : public IOHandlerDelegate,
public IOHandlerEditline {
public:
@@ -28,15 +31,23 @@ public:
">>> ", "..> ", true, debugger.GetUseColor(), 0,
*this, nullptr),
m_script_interpreter(script_interpreter) {
+ llvm::cantFail(m_script_interpreter.GetLua().ChangeIO(
+ debugger.GetOutputFile().GetStream(),
+ debugger.GetErrorFile().GetStream()));
llvm::cantFail(m_script_interpreter.EnterSession(debugger.GetID()));
}
- ~IOHandlerLuaInterpreter() {
+ ~IOHandlerLuaInterpreter() override {
llvm::cantFail(m_script_interpreter.LeaveSession());
}
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override {
+ if (llvm::StringRef(data).rtrim() == "quit") {
+ io_handler.SetIsDone(true);
+ return;
+ }
+
if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) {
*GetOutputStreamFileSP() << llvm::toString(std::move(error));
}
@@ -55,12 +66,43 @@ ScriptInterpreterLua::~ScriptInterpreterLua() {}
bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *result,
const ExecuteScriptOptions &options) {
+ if (command.empty()) {
+ if (result)
+ result->AppendError("empty command passed to lua\n");
+ return false;
+ }
+
+ llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+ io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+ options.GetEnableIO(), m_debugger, result);
+ if (!io_redirect_or_error) {
+ if (result)
+ result->AppendErrorWithFormatv(
+ "failed to redirect I/O: {0}\n",
+ llvm::fmt_consume(io_redirect_or_error.takeError()));
+ else
+ llvm::consumeError(io_redirect_or_error.takeError());
+ return false;
+ }
+
+ ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
+ if (llvm::Error e =
+ m_lua->ChangeIO(io_redirect.GetOutputFile()->GetStream(),
+ io_redirect.GetErrorFile()->GetStream())) {
+ result->AppendErrorWithFormatv("lua failed to redirect I/O: {0}\n",
+ llvm::toString(std::move(e)));
+ return false;
+ }
+
if (llvm::Error e = m_lua->Run(command)) {
result->AppendErrorWithFormatv(
"lua failed attempting to evaluate '{0}': {1}\n", command,
llvm::toString(std::move(e)));
return false;
}
+
+ io_redirect.Flush();
return true;
}
@@ -68,25 +110,23 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
- Debugger &debugger = m_debugger;
-
// At the moment, the only time the debugger does not have an input file
// handle is when this is called directly from lua, in which case it is
// both dangerous and unnecessary (not to mention confusing) to try to embed
// a running interpreter loop inside the already running lua interpreter
// loop, so we won't do it.
-
- if (!debugger.GetInputFile().IsValid())
+ if (!m_debugger.GetInputFile().IsValid())
return;
- IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(debugger, *this));
- debugger.PushIOHandler(io_handler_sp);
+ IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(m_debugger, *this));
+ m_debugger.RunIOHandlerAsync(io_handler_sp);
}
bool ScriptInterpreterLua::LoadScriptingModule(
const char *filename, bool init_session, lldb_private::Status &error,
StructuredData::ObjectSP *module_sp) {
+ FileSystem::Instance().Collect(filename);
if (llvm::Error e = m_lua->LoadModule(filename)) {
error.SetErrorStringWithFormatv("lua failed to import '{0}': {1}\n",
filename, llvm::toString(std::move(e)));
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
index 4e922151385b..bcc6ab24f6d0 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -25,7 +25,7 @@ public:
void ExecuteInterpreterLoop() override;
- virtual bool
+ bool
LoadScriptingModule(const char *filename, bool init_session,
lldb_private::Status &error,
StructuredData::ObjectSP *module_sp = nullptr) override;
diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 3517f831970d..d9c32cc132d4 100644
--- a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -1,4 +1,4 @@
-//===-- ScriptInterpreterNone.cpp -------------------------------*- C++ -*-===//
+//===-- ScriptInterpreterNone.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -20,6 +20,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(ScriptInterpreterNone)
+
ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger)
: ScriptInterpreter(debugger, eScriptLanguageNone) {}
diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
index 242065cc23e8..c438b6315c5d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
+++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ScriptInterpreterNone_h_
-#define liblldb_ScriptInterpreterNone_h_
+#ifndef LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H
+#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H
#include "lldb/Interpreter/ScriptInterpreter.h"
@@ -44,4 +44,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_ScriptInterpreterNone_h_
+#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_NONE_SCRIPTINTERPRETERNONE_H
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index e5a67653e334..6f040fdef09b 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -1,4 +1,4 @@
-//===-- PythonDataObjects.cpp -----------------------------------*- C++ -*-===//
+//===-- PythonDataObjects.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -44,7 +44,15 @@ template <>
Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
if (!obj)
return obj.takeError();
- return obj.get().AsLongLong();
+ return obj->AsLongLong();
+}
+
+template <>
+Expected<unsigned long long>
+python::As<unsigned long long>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ return obj->AsUnsignedLongLong();
}
template <>
@@ -58,7 +66,56 @@ Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
auto utf8 = str.AsUTF8();
if (!utf8)
return utf8.takeError();
- return utf8.get();
+ return std::string(utf8.get());
+}
+
+Expected<long long> PythonObject::AsLongLong() const {
+ if (!m_py_obj)
+ return nullDeref();
+#if PY_MAJOR_VERSION < 3
+ if (!PyLong_Check(m_py_obj)) {
+ PythonInteger i(PyRefType::Borrowed, m_py_obj);
+ return i.AsLongLong();
+ }
+#endif
+ assert(!PyErr_Occurred());
+ long long r = PyLong_AsLongLong(m_py_obj);
+ if (PyErr_Occurred())
+ return exception();
+ return r;
+}
+
+Expected<long long> PythonObject::AsUnsignedLongLong() const {
+ if (!m_py_obj)
+ return nullDeref();
+#if PY_MAJOR_VERSION < 3
+ if (!PyLong_Check(m_py_obj)) {
+ PythonInteger i(PyRefType::Borrowed, m_py_obj);
+ return i.AsUnsignedLongLong();
+ }
+#endif
+ assert(!PyErr_Occurred());
+ long long r = PyLong_AsUnsignedLongLong(m_py_obj);
+ if (PyErr_Occurred())
+ return exception();
+ return r;
+}
+
+// wraps on overflow, instead of raising an error.
+Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
+ if (!m_py_obj)
+ return nullDeref();
+#if PY_MAJOR_VERSION < 3
+ if (!PyLong_Check(m_py_obj)) {
+ PythonInteger i(PyRefType::Borrowed, m_py_obj);
+ return i.AsModuloUnsignedLongLong();
+ }
+#endif
+ assert(!PyErr_Occurred());
+ unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
+ if (PyErr_Occurred())
+ return exception();
+ return r;
}
void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
@@ -463,32 +520,22 @@ void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
#endif
}
-int64_t PythonInteger::GetInteger() const {
- if (m_py_obj) {
- assert(PyLong_Check(m_py_obj) &&
- "PythonInteger::GetInteger has a PyObject that isn't a PyLong");
-
- int overflow = 0;
- int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
- if (overflow != 0) {
- // We got an integer that overflows, like 18446744072853913392L we can't
- // use PyLong_AsLongLong() as it will return 0xffffffffffffffff. If we
- // use the unsigned long long it will work as expected.
- const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
- result = static_cast<int64_t>(uval);
- }
- return result;
- }
- return UINT64_MAX;
-}
-
void PythonInteger::SetInteger(int64_t value) {
*this = Take<PythonInteger>(PyLong_FromLongLong(value));
}
StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
StructuredData::IntegerSP result(new StructuredData::Integer);
- result->SetValue(GetInteger());
+ // FIXME this is really not ideal. Errors are silently converted to 0
+ // and overflows are silently wrapped. But we'd need larger changes
+ // to StructuredData to fix it, so that's how it is for now.
+ llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong();
+ if (!value) {
+ llvm::consumeError(value.takeError());
+ result->SetValue(0);
+ } else {
+ result->SetValue(value.get());
+ }
return result;
}
@@ -1044,7 +1091,7 @@ std::string PythonException::ReadBacktrace() const {
if (!backtrace) {
std::string message =
std::string(toCString()) + "\n" +
- "Traceback unavailble, an error occurred while reading it:\n";
+ "Traceback unavailable, an error occurred while reading it:\n";
return (message + llvm::toString(backtrace.takeError()));
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index b75045b239a8..22f6c67eb7a5 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -36,7 +36,7 @@
// can never fail to assert instead, such as the creation of
// PythonString from a string literal.
//
-// * Elimintate Reset(), and make all non-default constructors private.
+// * Eliminate Reset(), and make all non-default constructors private.
// Python objects should be created with Retain<> or Take<>, and they
// should be assigned with operator=
//
@@ -90,7 +90,9 @@ public:
void Serialize(llvm::json::OStream &s) const override;
private:
- DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
+ StructuredPythonObject(const StructuredPythonObject &) = delete;
+ const StructuredPythonObject &
+ operator=(const StructuredPythonObject &) = delete;
};
enum class PyObjectType {
@@ -319,7 +321,6 @@ public:
StructuredData::ObjectSP CreateStructuredObject() const;
-public:
template <typename... T>
llvm::Expected<PythonObject> CallMethod(const char *name,
const T &... t) const {
@@ -360,15 +361,12 @@ public:
return !!r;
}
- llvm::Expected<long long> AsLongLong() {
- if (!m_py_obj)
- return nullDeref();
- assert(!PyErr_Occurred());
- long long r = PyLong_AsLongLong(m_py_obj);
- if (PyErr_Occurred())
- return exception();
- return r;
- }
+ llvm::Expected<long long> AsLongLong() const;
+
+ llvm::Expected<long long> AsUnsignedLongLong() const;
+
+ // wraps on overflow, instead of raising an error.
+ llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
llvm::Expected<bool> IsInstance(const PythonObject &cls) {
if (!m_py_obj || !cls.IsValid())
@@ -400,6 +398,10 @@ template <>
llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
template <>
+llvm::Expected<unsigned long long>
+As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
+
+template <>
llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
@@ -491,8 +493,6 @@ public:
static bool Check(PyObject *py_obj);
static void Convert(PyRefType &type, PyObject *&py_obj);
- int64_t GetInteger() const;
-
void SetInteger(int64_t value);
StructuredData::IntegerSP CreateStructuredInteger() const;
@@ -595,7 +595,7 @@ public:
// safe, returns invalid on error;
static PythonModule ImportModule(llvm::StringRef name) {
- std::string s = name;
+ std::string s = std::string(name);
auto mod = Import(s.c_str());
if (!mod) {
llvm::consumeError(mod.takeError());
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 06e0d5bfa63f..9f56b4fa60a5 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1,4 +1,4 @@
-//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
+//===-- ScriptInterpreterPython.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -16,7 +16,6 @@
#include "PythonDataObjects.h"
#include "PythonReadline.h"
#include "ScriptInterpreterPythonImpl.h"
-
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -26,7 +25,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
@@ -35,13 +33,9 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Utility/Timer.h"
-
-#if defined(_WIN32)
-#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
-#endif
-
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatAdapters.h"
@@ -56,6 +50,8 @@ using namespace lldb_private;
using namespace lldb_private::python;
using llvm::Expected;
+LLDB_PLUGIN_DEFINE(ScriptInterpreterPython)
+
// Defined in the SWIG source file
#if PY_MAJOR_VERSION >= 3
extern "C" PyObject *PyInit__lldb(void);
@@ -222,10 +218,6 @@ struct InitializePythonRAII {
public:
InitializePythonRAII()
: m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) {
- // Python will muck with STDIN terminal state, so save off any current TTY
- // settings so we can restore them.
- m_stdin_tty_state.Save(STDIN_FILENO, false);
-
InitializePythonHome();
#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
@@ -269,20 +261,40 @@ public:
// We initialized the threads in this function, just unlock the GIL.
PyEval_SaveThread();
}
-
- m_stdin_tty_state.Restore();
}
private:
void InitializePythonHome() {
-#if defined(LLDB_PYTHON_HOME)
+#if LLDB_EMBED_PYTHON_HOME
#if PY_MAJOR_VERSION >= 3
- size_t size = 0;
- static wchar_t *g_python_home = Py_DecodeLocale(LLDB_PYTHON_HOME, &size);
+ typedef wchar_t* str_type;
#else
- static char g_python_home[] = LLDB_PYTHON_HOME;
+ typedef char* str_type;
#endif
- Py_SetPythonHome(g_python_home);
+ static str_type g_python_home = []() -> str_type {
+ const char *lldb_python_home = LLDB_PYTHON_HOME;
+ const char *absolute_python_home = nullptr;
+ llvm::SmallString<64> path;
+ if (llvm::sys::path::is_absolute(lldb_python_home)) {
+ absolute_python_home = lldb_python_home;
+ } else {
+ FileSpec spec = HostInfo::GetShlibDir();
+ if (!spec)
+ return nullptr;
+ spec.GetPath(path);
+ llvm::sys::path::append(path, lldb_python_home);
+ absolute_python_home = path.c_str();
+ }
+#if PY_MAJOR_VERSION >= 3
+ size_t size = 0;
+ return Py_DecodeLocale(absolute_python_home, &size);
+#else
+ return strdup(absolute_python_home);
+#endif
+ }();
+ if (g_python_home != nullptr) {
+ Py_SetPythonHome(g_python_home);
+ }
#else
#if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7
// For Darwin, the only Python version supported is the one shipped in the
@@ -471,7 +483,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_run_one_line_str_global(),
m_dictionary_name(m_debugger.GetInstanceName().AsCString()),
m_active_io_handler(eIOHandlerNone), m_session_is_active(false),
- m_pty_slave_is_open(false), m_valid_session(true), m_lock_count(0),
+ m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0),
m_command_thread_state(nullptr) {
InitializePrivate();
@@ -853,7 +865,7 @@ static std::string GenerateUniqueName(const char *base_name_wanted,
else
sstr.Printf("%s_%p", base_name_wanted, name_token);
- return sstr.GetString();
+ return std::string(sstr.GetString());
}
bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() {
@@ -877,15 +889,6 @@ bool ScriptInterpreterPythonImpl::GetEmbeddedInterpreterModuleObjects() {
return m_run_one_line_function.IsValid();
}
-static void ReadThreadBytesReceived(void *baton, const void *src,
- size_t src_len) {
- if (src && src_len) {
- Stream *strm = (Stream *)baton;
- strm->Write(src, src_len);
- strm->Flush();
- }
-}
-
bool ScriptInterpreterPythonImpl::ExecuteOneLine(
llvm::StringRef command, CommandReturnObject *result,
const ExecuteScriptOptions &options) {
@@ -901,77 +904,21 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
// another string to pass to PyRun_SimpleString messes up the escaping. So
// we use the following more complicated method to pass the command string
// directly down to Python.
- Debugger &debugger = m_debugger;
-
- FileSP input_file_sp;
- StreamFileSP output_file_sp;
- StreamFileSP error_file_sp;
- Communication output_comm(
- "lldb.ScriptInterpreterPythonImpl.ExecuteOneLine.comm");
- bool join_read_thread = false;
- if (options.GetEnableIO()) {
- if (result) {
- input_file_sp = debugger.GetInputFileSP();
- // Set output to a temporary file so we can forward the results on to
- // the result object
-
- Pipe pipe;
- Status pipe_result = pipe.CreateNew(false);
- if (pipe_result.Success()) {
-#if defined(_WIN32)
- lldb::file_t read_file = pipe.GetReadNativeHandle();
- pipe.ReleaseReadFileDescriptor();
- std::unique_ptr<ConnectionGenericFile> conn_up(
- new ConnectionGenericFile(read_file, true));
-#else
- std::unique_ptr<ConnectionFileDescriptor> conn_up(
- new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(),
- true));
-#endif
- if (conn_up->IsConnected()) {
- output_comm.SetConnection(conn_up.release());
- output_comm.SetReadThreadBytesReceivedCallback(
- ReadThreadBytesReceived, &result->GetOutputStream());
- output_comm.StartReadThread();
- join_read_thread = true;
- FILE *outfile_handle =
- fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
- output_file_sp = std::make_shared<StreamFile>(outfile_handle, true);
- error_file_sp = output_file_sp;
- if (outfile_handle)
- ::setbuf(outfile_handle, nullptr);
-
- result->SetImmediateOutputFile(
- debugger.GetOutputStream().GetFileSP());
- result->SetImmediateErrorFile(
- debugger.GetErrorStream().GetFileSP());
- }
- }
- }
- if (!input_file_sp || !output_file_sp || !error_file_sp)
- debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp,
- error_file_sp);
- } else {
- auto nullin = FileSystem::Instance().Open(
- FileSpec(FileSystem::DEV_NULL),
- File::eOpenOptionRead);
- auto nullout = FileSystem::Instance().Open(
- FileSpec(FileSystem::DEV_NULL),
- File::eOpenOptionWrite);
- if (!nullin) {
- result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n",
- llvm::fmt_consume(nullin.takeError()));
- return false;
- }
- if (!nullout) {
- result->AppendErrorWithFormatv("failed to open /dev/null: {0}\n",
- llvm::fmt_consume(nullout.takeError()));
- return false;
- }
- input_file_sp = std::move(nullin.get());
- error_file_sp = output_file_sp = std::make_shared<StreamFile>(std::move(nullout.get()));
+ llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+ io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+ options.GetEnableIO(), m_debugger, result);
+ if (!io_redirect_or_error) {
+ if (result)
+ result->AppendErrorWithFormatv(
+ "failed to redirect I/O: {0}\n",
+ llvm::fmt_consume(io_redirect_or_error.takeError()));
+ else
+ llvm::consumeError(io_redirect_or_error.takeError());
+ return false;
}
+ ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
bool success = false;
{
// WARNING! It's imperative that this RAII scope be as tight as
@@ -987,8 +934,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
Locker::AcquireLock | Locker::InitSession |
(options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
- Locker::FreeAcquiredLock | Locker::TearDownSession, input_file_sp,
- output_file_sp->GetFileSP(), error_file_sp->GetFileSP());
+ Locker::FreeAcquiredLock | Locker::TearDownSession,
+ io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+ io_redirect.GetErrorFile());
// Find the correct script interpreter dictionary in the main module.
PythonDictionary &session_dict = GetSessionDictionary();
@@ -1014,21 +962,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
}
}
- // Flush our output and error file handles
- output_file_sp->Flush();
- error_file_sp->Flush();
- }
-
- if (join_read_thread) {
- // Close the write end of the pipe since we are done with our one line
- // script. This should cause the read thread that output_comm is using to
- // exit
- output_file_sp->GetFile().Close();
- // The close above should cause this thread to exit when it gets to the
- // end of file, so let it get all its data
- output_comm.JoinReadThread();
- // Now we can close the read end of the pipe
- output_comm.Disconnect();
+ io_redirect.Flush();
}
if (success)
@@ -1064,7 +998,7 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
if (io_handler_sp) {
- debugger.PushIOHandler(io_handler_sp);
+ debugger.RunIOHandlerAsync(io_handler_sp);
}
}
@@ -1343,8 +1277,8 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
bp_options->SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
return error;
- } else
- return error;
+ }
+ return error;
}
// Set a Python one-liner as the callback for the watchpoint.
@@ -1970,8 +1904,7 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState(
}
if (should_step)
return lldb::eStateStepping;
- else
- return lldb::eStateRunning;
+ return lldb::eStateRunning;
}
StructuredData::GenericSP
@@ -2043,8 +1976,7 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
if (depth_as_int <= lldb::kLastSearchDepthKind)
return (lldb::SearchDepth)depth_as_int;
- else
- return lldb::eSearchDepthModule;
+ return lldb::eSearchDepthModule;
}
StructuredData::ObjectSP
@@ -2748,6 +2680,7 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
{
FileSpec target_file(pathname);
FileSystem::Instance().Resolve(target_file);
+ FileSystem::Instance().Collect(target_file);
std::string basename(target_file.GetFilename().GetCString());
StreamString command_stream;
@@ -3010,39 +2943,42 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
return ret_val;
}
-// in Python, a special attribute __doc__ contains the docstring for an object
-// (function, method, class, ...) if any is defined Otherwise, the attribute's
-// value is None
+/// In Python, a special attribute __doc__ contains the docstring for an object
+/// (function, method, class, ...) if any is defined Otherwise, the attribute's
+/// value is None.
bool ScriptInterpreterPythonImpl::GetDocumentationForItem(const char *item,
std::string &dest) {
dest.clear();
+
if (!item || !*item)
return false;
+
std::string command(item);
command += ".__doc__";
- char *result_ptr = nullptr; // Python is going to point this to valid data if
- // ExecuteOneLineWithReturn returns successfully
+ // Python is going to point this to valid data if ExecuteOneLineWithReturn
+ // returns successfully.
+ char *result_ptr = nullptr;
if (ExecuteOneLineWithReturn(
- command.c_str(), ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
+ command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
&result_ptr,
ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) {
if (result_ptr)
dest.assign(result_ptr);
return true;
- } else {
- StreamString str_stream;
- str_stream.Printf(
- "Function %s was not found. Containing module might be missing.", item);
- dest = str_stream.GetString();
- return false;
}
+
+ StreamString str_stream;
+ str_stream << "Function " << item
+ << " was not found. Containing module might be missing.";
+ dest = std::string(str_stream.GetString());
+
+ return false;
}
bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
StructuredData::GenericSP cmd_obj_sp, std::string &dest) {
- bool got_string = false;
dest.clear();
Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
@@ -3076,12 +3012,12 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
if (PyErr_Occurred())
PyErr_Clear();
- // right now we know this function exists and is callable..
+ // Right now we know this function exists and is callable.
PythonObject py_return(
PyRefType::Owned,
PyObject_CallMethod(implementor.get(), callee_name, nullptr));
- // if it fails, print the error but otherwise go on
+ // If it fails, print the error but otherwise go on.
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
@@ -3091,9 +3027,10 @@ bool ScriptInterpreterPythonImpl::GetShortHelpForCommandObject(
PythonString py_string(PyRefType::Borrowed, py_return.get());
llvm::StringRef return_data(py_string.GetString());
dest.assign(return_data.data(), return_data.size());
- got_string = true;
+ return true;
}
- return got_string;
+
+ return false;
}
uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
@@ -3131,20 +3068,15 @@ uint32_t ScriptInterpreterPythonImpl::GetFlagsForCommandObject(
if (PyErr_Occurred())
PyErr_Clear();
- // right now we know this function exists and is callable..
- PythonObject py_return(
- PyRefType::Owned,
- PyObject_CallMethod(implementor.get(), callee_name, nullptr));
+ long long py_return = unwrapOrSetPythonException(
+ As<long long>(implementor.CallMethod(callee_name)));
// if it fails, print the error but otherwise go on
if (PyErr_Occurred()) {
PyErr_Print();
PyErr_Clear();
- }
-
- if (py_return.IsAllocated() && PythonInteger::Check(py_return.get())) {
- PythonInteger int_value(PyRefType::Borrowed, py_return.get());
- result = int_value.GetInteger();
+ } else {
+ result = py_return;
}
return result;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 1fa198b07e54..22b2c8152eac 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -395,7 +395,7 @@ public:
std::string m_dictionary_name;
ActiveIOHandler m_active_io_handler;
bool m_session_is_active;
- bool m_pty_slave_is_open;
+ bool m_pty_secondary_is_open;
bool m_valid_session;
uint32_t m_lock_count;
PyThreadState *m_command_thread_state;
diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index c6b234baa8c8..5ceaf886b812 100644
--- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -1,4 +1,4 @@
-//===-- StructuredDataDarwinLog.cpp -----------------------------*- C++ -*-===//
+//===-- StructuredDataDarwinLog.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -36,6 +36,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(StructuredDataDarwinLog)
+
#pragma mark -
#pragma mark Anonymous Namespace
@@ -706,9 +708,9 @@ private:
attribute_end_pos + 1, operation_end_pos - (attribute_end_pos + 1));
// add filter spec
- auto rule_sp =
- FilterRule::CreateRule(accept, attribute_index, ConstString(operation),
- rule_text.substr(operation_end_pos + 1), error);
+ auto rule_sp = FilterRule::CreateRule(
+ accept, attribute_index, ConstString(operation),
+ std::string(rule_text.substr(operation_end_pos + 1)), error);
if (rule_sp && error.Success())
m_filter_rules.push_back(rule_sp);
@@ -979,7 +981,7 @@ EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) {
EnableOptionsSP options_sp(new EnableOptions());
options_sp->NotifyOptionParsingStarting(&exe_ctx);
- CommandReturnObject result;
+ CommandReturnObject result(debugger.GetUseColor());
// Parse the arguments.
auto options_property_sp =
@@ -1034,7 +1036,7 @@ bool RunEnableCommand(CommandInterpreter &interpreter) {
}
// Run the command.
- CommandReturnObject return_object;
+ CommandReturnObject return_object(interpreter.GetDebugger().GetUseColor());
interpreter.HandleCommand(command_stream.GetData(), eLazyBoolNo,
return_object);
return return_object.Succeeded();
diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h
index 8fa1eed66efb..caa94af1f30e 100644
--- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h
+++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef StructuredDataDarwinLog_h
-#define StructuredDataDarwinLog_h
+#ifndef LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H
+#define LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H
#include "lldb/Target/StructuredDataPlugin.h"
@@ -34,7 +34,7 @@ public:
/// Return whether the DarwinLog functionality is enabled.
///
- /// The DarwinLog functionality is enabled if the user expicitly enabled
+ /// The DarwinLog functionality is enabled if the user explicitly enabled
/// it with the enable command, or if the user has the setting set
/// that controls if we always enable it for newly created/attached
/// processes.
@@ -115,4 +115,4 @@ private:
};
}
-#endif /* StructuredDataPluginDarwinLog_hpp */
+#endif // LLDB_SOURCE_PLUGINS_STRUCTUREDDATA_DARWINLOG_STRUCTUREDDATADARWINLOG_H
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index b2c4d0883341..eeec7296747e 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===//
+//===-- SymbolFileBreakpad.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,6 +25,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::breakpad;
+LLDB_PLUGIN_DEFINE(SymbolFileBreakpad)
+
char SymbolFileBreakpad::ID;
class SymbolFileBreakpad::LineIterator {
@@ -292,7 +294,7 @@ uint32_t SymbolFileBreakpad::ResolveSymbolContext(
}
void SymbolFileBreakpad::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
// TODO
@@ -305,7 +307,7 @@ void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
}
void SymbolFileBreakpad::FindTypes(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
TypeMap &types) {}
@@ -406,20 +408,25 @@ GetRule(llvm::StringRef &unwind_rules) {
}
static const RegisterInfo *
-ResolveRegister(const SymbolFile::RegisterInfoResolver &resolver,
+ResolveRegister(const llvm::Triple &triple,
+ const SymbolFile::RegisterInfoResolver &resolver,
llvm::StringRef name) {
- if (name.consume_front("$"))
- return resolver.ResolveName(name);
-
- return nullptr;
+ if (triple.isX86() || triple.isMIPS()) {
+ // X86 and MIPS registers have '$' in front of their register names. Arm and
+ // AArch64 don't.
+ if (!name.consume_front("$"))
+ return nullptr;
+ }
+ return resolver.ResolveName(name);
}
static const RegisterInfo *
-ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
+ResolveRegisterOrRA(const llvm::Triple &triple,
+ const SymbolFile::RegisterInfoResolver &resolver,
llvm::StringRef name) {
if (name == ".ra")
return resolver.ResolveNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- return ResolveRegister(resolver, name);
+ return ResolveRegister(triple, resolver, name);
}
llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
@@ -438,6 +445,7 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
llvm::BumpPtrAllocator node_alloc;
+ llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple();
while (auto rule = GetRule(unwind_rules)) {
node_alloc.Reset();
llvm::StringRef lhs = rule->first;
@@ -453,7 +461,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
if (name == ".cfa" && lhs != ".cfa")
return postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
- if (const RegisterInfo *info = ResolveRegister(resolver, name)) {
+ if (const RegisterInfo *info =
+ ResolveRegister(triple, resolver, name)) {
return postfix::MakeNode<postfix::RegisterNode>(
node_alloc, info->kinds[eRegisterKindLLDB]);
}
@@ -468,7 +477,8 @@ bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
if (lhs == ".cfa") {
row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
- } else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
+ } else if (const RegisterInfo *info =
+ ResolveRegisterOrRA(triple, resolver, lhs)) {
UnwindPlan::Row::RegisterLocation loc;
loc.SetIsDWARFExpression(saved.data(), saved.size());
row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
@@ -572,6 +582,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
return nullptr;
}
auto it = program.begin();
+ llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple();
const auto &symbol_resolver =
[&](postfix::SymbolNode &symbol) -> postfix::Node * {
llvm::StringRef name = symbol.GetName();
@@ -579,7 +590,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
if (rule.first == name)
return rule.second;
}
- if (const RegisterInfo *info = ResolveRegister(resolver, name))
+ if (const RegisterInfo *info = ResolveRegister(triple, resolver, name))
return postfix::MakeNode<postfix::RegisterNode>(
node_alloc, info->kinds[eRegisterKindLLDB]);
return nullptr;
@@ -609,7 +620,7 @@ SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
// Now process the rest of the assignments.
for (++it; it != program.end(); ++it) {
- const RegisterInfo *info = ResolveRegister(resolver, it->first);
+ const RegisterInfo *info = ResolveRegister(triple, resolver, it->first);
// It is not an error if the resolution fails because the program may
// contain temporary variables.
if (!info)
@@ -694,18 +705,18 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
"How did we create compile units without a base address?");
SupportFileMap map;
- data.line_table_up = std::make_unique<LineTable>(&cu);
- std::unique_ptr<LineSequence> line_seq_up(
- data.line_table_up->CreateLineSequenceContainer());
+ std::vector<std::unique_ptr<LineSequence>> sequences;
+ std::unique_ptr<LineSequence> line_seq_up =
+ LineTable::CreateLineSequenceContainer();
llvm::Optional<addr_t> next_addr;
auto finish_sequence = [&]() {
- data.line_table_up->AppendLineEntryToSequence(
+ LineTable::AppendLineEntryToSequence(
line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0,
/*file_idx*/ 0, /*is_start_of_statement*/ false,
/*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
/*is_epilogue_begin*/ false, /*is_terminal_entry*/ true);
- data.line_table_up->InsertSequence(line_seq_up.get());
- line_seq_up->Clear();
+ sequences.push_back(std::move(line_seq_up));
+ line_seq_up = LineTable::CreateLineSequenceContainer();
};
LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
@@ -722,7 +733,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
// Discontiguous entries. Finish off the previous sequence and reset.
finish_sequence();
}
- data.line_table_up->AppendLineEntryToSequence(
+ LineTable::AppendLineEntryToSequence(
line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0,
map[record->FileNum], /*is_start_of_statement*/ true,
/*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
@@ -731,6 +742,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
}
if (next_addr)
finish_sequence();
+ data.line_table_up = std::make_unique<LineTable>(&cu, std::move(sequences));
data.support_files = map.translate(cu.GetPrimaryFile(), *m_files);
}
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index de271224a65d..90dbcc77627a 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
-#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/Core/FileSpecList.h"
@@ -82,7 +82,7 @@ public:
size_t ParseBlocksRecursive(Function &func) override { return 0; }
void FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
+ const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
VariableList &variables) override {}
@@ -110,14 +110,14 @@ public:
TypeList &type_list) override {}
void FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
+ const CompilerDeclContext &parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines, SymbolContextList &sc_list) override;
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
- void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files,
TypeMap &types) override;
@@ -135,7 +135,7 @@ public:
CompilerDeclContext
FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx) override {
+ const CompilerDeclContext &parent_decl_ctx) override {
return CompilerDeclContext();
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 0a5073b8cd9e..33ab11a3ca40 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -1,4 +1,4 @@
-//===-- AppleDWARFIndex.cpp ------------------------------------*- C++ -*-===//
+//===-- AppleDWARFIndex.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -52,54 +52,70 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
return nullptr;
}
-void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
- if (m_apple_names_up)
- m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
+void AppleDWARFIndex::GetGlobalVariables(
+ ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
+ if (!m_apple_names_up)
+ return;
+ m_apple_names_up->FindByName(
+ basename.GetStringRef(),
+ DIERefCallback(callback, basename.GetStringRef()));
}
-void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) {
+void AppleDWARFIndex::GetGlobalVariables(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_names_up)
return;
DWARFMappedHash::DIEInfoArray hash_data;
- if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
- DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+ m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
+ // This is not really the DIE name.
+ DWARFMappedHash::ExtractDIEArray(hash_data,
+ DIERefCallback(callback, regex.GetText()));
}
-void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
- DIEArray &offsets) {
+void AppleDWARFIndex::GetGlobalVariables(
+ const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_names_up)
return;
DWARFMappedHash::DIEInfoArray hash_data;
- if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
- cu.GetNextUnitOffset(), hash_data))
- DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
+ m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(),
+ hash_data);
+ DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback));
}
-void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
- DIEArray &offsets) {
- if (m_apple_objc_up)
- m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
+void AppleDWARFIndex::GetObjCMethods(
+ ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
+ if (!m_apple_objc_up)
+ return;
+ m_apple_objc_up->FindByName(
+ class_name.GetStringRef(),
+ DIERefCallback(callback, class_name.GetStringRef()));
}
-void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
- bool must_be_implementation,
- DIEArray &offsets) {
- if (m_apple_types_up) {
- m_apple_types_up->FindCompleteObjCClassByName(
- class_name.GetStringRef(), offsets, must_be_implementation);
- }
+void AppleDWARFIndex::GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ if (!m_apple_types_up)
+ return;
+ m_apple_types_up->FindCompleteObjCClassByName(
+ class_name.GetStringRef(),
+ DIERefCallback(callback, class_name.GetStringRef()),
+ must_be_implementation);
}
-void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
- if (m_apple_types_up)
- m_apple_types_up->FindByName(name.GetStringRef(), offsets);
+void AppleDWARFIndex::GetTypes(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
+ if (!m_apple_types_up)
+ return;
+ m_apple_types_up->FindByName(name.GetStringRef(),
+ DIERefCallback(callback, name.GetStringRef()));
}
-void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
- DIEArray &offsets) {
+void AppleDWARFIndex::GetTypes(
+ const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_types_up)
return;
@@ -119,7 +135,8 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
if (log)
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
- type_name.GetStringRef(), tag, qualified_name_hash, offsets);
+ type_name.GetStringRef(), tag, qualified_name_hash,
+ DIERefCallback(callback, type_name.GetStringRef()));
return;
}
@@ -133,54 +150,52 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
if (!has_qualified_name_hash && (context.GetSize() > 1) &&
(context[1].tag == DW_TAG_class_type ||
context[1].tag == DW_TAG_structure_type)) {
- DIEArray class_matches;
- m_apple_types_up->FindByName(context[1].name, class_matches);
- if (class_matches.empty())
+ if (m_apple_types_up->FindByName(context[1].name,
+ [&](DIERef ref) { return false; }))
return;
}
if (log)
m_module.LogMessage(log, "FindByNameAndTag()");
- m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
+ m_apple_types_up->FindByNameAndTag(
+ type_name.GetStringRef(), tag,
+ DIERefCallback(callback, type_name.GetStringRef()));
return;
}
- m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+ m_apple_types_up->FindByName(
+ type_name.GetStringRef(),
+ DIERefCallback(callback, type_name.GetStringRef()));
}
-void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
- if (m_apple_namespaces_up)
- m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
+void AppleDWARFIndex::GetNamespaces(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
+ if (!m_apple_namespaces_up)
+ return;
+ m_apple_namespaces_up->FindByName(
+ name.GetStringRef(), DIERefCallback(callback, name.GetStringRef()));
}
-void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
- const CompilerDeclContext &parent_decl_ctx,
- uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) {
- DIEArray offsets;
- m_apple_names_up->FindByName(name.GetStringRef(), offsets);
- for (const DIERef &die_ref : offsets) {
- ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
- name_type_mask, dies);
- }
+void AppleDWARFIndex::GetFunctions(
+ ConstString name, SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) {
+ return ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf,
+ parent_decl_ctx, name_type_mask, callback);
+ });
}
-void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) {
+void AppleDWARFIndex::GetFunctions(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
if (!m_apple_names_up)
return;
DWARFMappedHash::DIEInfoArray hash_data;
- if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
- DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
-}
-
-void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
- llvm::StringRef name) {
- m_module.ReportErrorIfModifyDetected(
- "the DWARF debug information has been modified (accelerator table had "
- "bad die 0x%8.8x for '%s')\n",
- ref.die_offset(), name.str().c_str());
+ m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data);
+ DWARFMappedHash::ExtractDIEArray(hash_data,
+ DIERefCallback(callback, regex.GetText()));
}
void AppleDWARFIndex::Dump(Stream &s) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
index d15d61e270b3..a7032f50e590 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_APPLEDWARFINDEX_H
-#define LLDB_APPLEDWARFINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h"
@@ -32,23 +32,33 @@ public:
void Preload() override {}
- void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
- void GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) override;
- void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
- void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
- void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
- DIEArray &offsets) override;
- void GetTypes(ConstString name, DIEArray &offsets) override;
- void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
- void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void
+ GetGlobalVariables(ConstString basename,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const DWARFUnit &cu,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetObjCMethods(ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetNamespaces(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) override;
- void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetFunctions(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
- void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override;
void Dump(Stream &s) override;
private:
@@ -59,4 +69,4 @@ private:
};
} // namespace lldb_private
-#endif // LLDB_APPLEDWARFINDEX_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
index f7f2a5bf006b..7a8ab9c9bcfd 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -1,4 +1,4 @@
-//===-- DIERef.cpp ----------------------------------------------*- C++ -*-===//
+//===-- DIERef.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
index 5546bb7e8b86..f7e09ee17283 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DIERef_h_
-#define SymbolFileDWARF_DIERef_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
#include "lldb/Core/dwarf.h"
#include "llvm/ADT/Optional.h"
@@ -44,6 +44,16 @@ public:
dw_offset_t die_offset() const { return m_die_offset; }
+ bool operator<(DIERef other) const {
+ if (m_dwo_num_valid != other.m_dwo_num_valid)
+ return m_dwo_num_valid < other.m_dwo_num_valid;
+ if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num))
+ return m_dwo_num < other.m_dwo_num;
+ if (m_section != other.m_section)
+ return m_section < other.m_section;
+ return m_die_offset < other.m_die_offset;
+ }
+
private:
uint32_t m_dwo_num : 30;
uint32_t m_dwo_num_valid : 1;
@@ -60,4 +70,4 @@ template<> struct format_provider<DIERef> {
};
} // namespace llvm
-#endif // SymbolFileDWARF_DIERef_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 7ee4727cde91..2e0a7fd3ecd3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFASTParser_h_
-#define SymbolFileDWARF_DWARFASTParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H
#include "DWARFDefines.h"
#include "lldb/Core/PluginInterface.h"
@@ -55,4 +55,4 @@ public:
const lldb_private::ExecutionContext *exe_ctx = nullptr);
};
-#endif // SymbolFileDWARF_DWARFASTParser_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 232063a6f339..2d1db66e7fd9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFASTParserClang.cpp ---------------------------------*- C++ -*-===//
+//===-- DWARFASTParserClang.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,17 +13,17 @@
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"
-#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
+#include "SymbolFileDWARFDwo.h"
#include "UniqueDWARFASTType.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ClangASTImporter.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -35,6 +35,8 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/Demangle/Demangle.h"
+
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -55,7 +57,7 @@
using namespace lldb;
using namespace lldb_private;
-DWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast)
+DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
: m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
DWARFASTParserClang::~DWARFASTParserClang() {}
@@ -85,39 +87,10 @@ static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) {
return false;
}
-struct BitfieldInfo {
- uint64_t bit_size;
- uint64_t bit_offset;
-
- BitfieldInfo()
- : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {}
-
- void Clear() {
- bit_size = LLDB_INVALID_ADDRESS;
- bit_offset = LLDB_INVALID_ADDRESS;
- }
-
- bool IsValid() const {
- return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
- }
-
- bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
- if (IsValid()) {
- // This bitfield info is valid, so any subsequent bitfields must not
- // overlap and must be at a higher bit offset than any previous bitfield
- // + size.
- return (bit_size + bit_offset) <= next_bit_offset;
- } else {
- // If the this BitfieldInfo is not valid, then any offset isOK
- return true;
- }
- }
-};
ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
if (!m_clang_ast_importer_up) {
- m_clang_ast_importer_up.reset(new ClangASTImporter);
+ m_clang_ast_importer_up = std::make_unique<ClangASTImporter>();
}
return *m_clang_ast_importer_up;
}
@@ -184,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// The type in the Clang module must have the same language as the current CU.
LanguageSet languages;
- languages.Insert(die.GetCU()->GetLanguageType());
+ languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU()));
llvm::DenseSet<SymbolFile *> searched_symbol_files;
clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
searched_symbol_files, pcm_types);
@@ -239,14 +212,15 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
TypeSP type_sp(new Type(
die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(),
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
- &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward));
+ &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
+ TypePayloadClang(GetOwningClangModule(die))));
dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
- if (tag_decl)
+ clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
+ if (tag_decl) {
LinkDeclContextToDIE(tag_decl, die);
- else {
+ } else {
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
if (defn_decl_ctx)
LinkDeclContextToDIE(defn_decl_ctx, die);
@@ -255,7 +229,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
return type_sp;
}
-static void CompleteExternalTagDeclType(ClangASTContext &ast,
+static void CompleteExternalTagDeclType(TypeSystemClang &ast,
ClangASTImporter &ast_importer,
clang::DeclContext *decl_ctx,
DWARFDIE die,
@@ -277,8 +251,8 @@ static void CompleteExternalTagDeclType(ClangASTContext &ast,
type_name_cstr ? type_name_cstr : "", die.GetOffset());
// We need to make the type look complete otherwise, we might crash in
// Clang when adding children.
- if (ClangASTContext::StartTagDeclarationDefinition(type))
- ClangASTContext::CompleteTagDeclarationDefinition(type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(type))
+ TypeSystemClang::CompleteTagDeclarationDefinition(type);
}
}
@@ -533,7 +507,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
DWARF_LOG_LOOKUPS));
SymbolFileDWARF *dwarf = die.GetDWARF();
const dw_tag_t tag = die.Tag();
- LanguageType cu_language = die.GetLanguage();
+ LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
Type::ResolveState resolve_state = Type::ResolveState::Unresolved;
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
TypeSP type_sp;
@@ -735,7 +709,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
type_sp = std::make_shared<Type>(
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
- clang_type, resolve_state);
+ clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die)));
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
@@ -755,8 +729,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
if (type_sp)
return type_sp;
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
+ DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
@@ -818,27 +791,28 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
clang_type = m_ast.CreateEnumerationType(
attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr),
- attrs.decl, enumerator_clang_type, attrs.is_scoped_enum);
+ GetOwningClangModule(die), attrs.decl, enumerator_clang_type,
+ attrs.is_scoped_enum);
} else {
- enumerator_clang_type =
- m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+ enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
}
- LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+ LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die);
type_sp = std::make_shared<Type>(
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl,
- clang_type, Type::ResolveState::Forward);
+ clang_type, Type::ResolveState::Forward,
+ TypePayloadClang(GetOwningClangModule(die)));
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
if (die.HasChildren()) {
bool is_signed = false;
enumerator_clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(clang_type, is_signed,
type_sp->GetByteSize().getValueOr(0), die);
}
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
} else {
dwarf->GetObjectFile()->GetModule()->ReportError(
"DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
@@ -948,7 +922,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
if (complete_objc_class_type_sp) {
CompilerType type_clang_forward_type =
complete_objc_class_type_sp->GetForwardCompilerType();
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ if (TypeSystemClang::IsObjCObjectOrInterfaceType(
type_clang_forward_type))
class_opaque_type = type_clang_forward_type;
}
@@ -1053,7 +1027,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
} else {
CompilerType class_opaque_type =
class_type->GetForwardCompilerType();
- if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
+ if (TypeSystemClang::IsCXXClassType(class_opaque_type)) {
if (class_opaque_type.IsBeingDefined() || alternate_defn) {
if (!is_static && !die.HasChildren()) {
// We have a C++ member function with no children (this
@@ -1198,27 +1172,38 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
if (!function_decl) {
+ const char *name = attrs.name.GetCString();
+
+ // We currently generate function templates with template parameters in
+ // their name. In order to get closer to the AST that clang generates
+ // we want to strip these from the name when creating the AST.
+ if (attrs.mangled_name) {
+ llvm::ItaniumPartialDemangler D;
+ if (!D.partialDemangle(attrs.mangled_name))
+ name = D.getFunctionBaseName(nullptr, nullptr);
+ }
+
// We just have a function that isn't part of a class
function_decl = m_ast.CreateFunctionDeclaration(
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
- attrs.name.GetCString(), clang_type, attrs.storage,
+ GetOwningClangModule(die), name, clang_type, attrs.storage,
attrs.is_inline);
if (has_template_params) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
+ TypeSystemClang::TemplateParameterInfos template_param_infos;
ParseTemplateParameterInfos(die, template_param_infos);
template_function_decl = m_ast.CreateFunctionDeclaration(
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
- attrs.name.GetCString(), clang_type, attrs.storage,
- attrs.is_inline);
+ GetOwningClangModule(die), attrs.name.GetCString(), clang_type,
+ attrs.storage, attrs.is_inline);
clang::FunctionTemplateDecl *func_template_decl =
m_ast.CreateFunctionTemplateDecl(
- containing_decl_ctx, template_function_decl,
- attrs.name.GetCString(), template_param_infos);
+ containing_decl_ctx, GetOwningClangModule(die),
+ template_function_decl, name, template_param_infos);
m_ast.CreateFunctionTemplateSpecializationInfo(
- function_decl, func_template_decl, template_param_infos);
+ template_function_decl, func_template_decl, template_param_infos);
}
lldbassert(function_decl);
@@ -1278,44 +1263,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
if (attrs.byte_stride == 0 && attrs.bit_stride == 0)
attrs.byte_stride = element_type->GetByteSize().getValueOr(0);
CompilerType array_element_type = element_type->GetForwardCompilerType();
-
- if (ClangASTContext::IsCXXClassType(array_element_type) &&
- !array_element_type.GetCompleteType()) {
- ModuleSP module_sp = die.GetModule();
- if (module_sp) {
- if (die.GetCU()->GetProducer() == eProducerClang)
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nTry "
- "compiling the source file with -fstandalone-debug or "
- "disable -gmodules",
- die.GetOffset(), type_die.GetOffset());
- else
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nPlease "
- "file a bug against the compiler and include the "
- "preprocessed output for %s",
- die.GetOffset(), type_die.GetOffset(), GetUnitName(die).c_str());
- }
-
- // We have no choice other than to pretend that the element class
- // type is complete. If we don't do this, clang will crash when
- // trying to layout the class. Since we provide layout
- // assistance, all ivars in this class and other classes will be
- // fine, this is the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(array_element_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(array_element_type);
- } else {
- module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
- "start its definition.\nPlease file a "
- "bug and attach the file at the start "
- "of this error message",
- type_die.GetOffset());
- }
- }
+ CompleteType(array_element_type);
uint64_t array_element_bit_stride =
attrs.byte_stride * 8 + attrs.bit_stride;
@@ -1357,7 +1305,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
CompilerType class_clang_type = class_type->GetLayoutCompilerType();
- CompilerType clang_type = ClangASTContext::CreateMemberPointerType(
+ CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(
class_clang_type, pointee_clang_type);
if (llvm::Optional<uint64_t> clang_type_size =
@@ -1370,6 +1318,28 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
return nullptr;
}
+void DWARFASTParserClang::CompleteType(CompilerType type) {
+ // Technically, enums can be incomplete too, but we don't handle those as they
+ // are emitted even under -flimit-debug-info.
+ if (!TypeSystemClang::IsCXXClassType(type))
+ return;
+
+ if (type.GetCompleteType())
+ return;
+
+ // No complete definition in this module. Mark the class as complete to
+ // satisfy local ast invariants, but make a note of the fact that
+ // it is not _really_ complete so we can later search for a definition in a
+ // different module.
+ // Since we provide layout assistance, layouts of types containing this class
+ // will be correct even if we are not able to find the definition elsewhere.
+ bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
+ lldbassert(started && "Unable to start a class type definition.");
+ TypeSystemClang::CompleteTagDeclarationDefinition(type);
+ const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
+ m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
+}
+
TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
if (!type_sp)
@@ -1412,7 +1382,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
CompilerType clang_type;
const dw_tag_t tag = die.Tag();
SymbolFileDWARF *dwarf = die.GetDWARF();
- LanguageType cu_language = die.GetLanguage();
+ LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION |
DWARF_LOG_LOOKUPS);
@@ -1544,8 +1514,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
if (type_sp)
return type_sp;
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
+ DWARFDeclContext die_decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
// type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
// type_name_const_str);
@@ -1611,12 +1580,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
if (attrs.name.GetStringRef().contains('<')) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
+ TypeSystemClang::TemplateParameterInfos template_param_infos;
if (ParseTemplateParameterInfos(die, template_param_infos)) {
clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
- attrs.name.GetCString(), tag_decl_kind,
- template_param_infos);
+ m_ast.ParseClassTemplateDecl(
+ decl_ctx, GetOwningClangModule(die), attrs.accessibility,
+ attrs.name.GetCString(), tag_decl_kind, template_param_infos);
if (!class_template_decl) {
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
@@ -1631,8 +1600,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
clang::ClassTemplateSpecializationDecl *class_specialization_decl =
m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
+ decl_ctx, GetOwningClangModule(die), class_template_decl,
+ tag_decl_kind, template_param_infos);
clang_type = m_ast.CreateClassTemplateSpecializationType(
class_specialization_decl);
clang_type_was_created = true;
@@ -1645,8 +1614,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
if (!clang_type_was_created) {
clang_type_was_created = true;
clang_type = m_ast.CreateRecordType(
- decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind,
- attrs.class_language, &metadata, attrs.exports_symbols);
+ decl_ctx, GetOwningClangModule(die), attrs.accessibility,
+ attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
+ &metadata, attrs.exports_symbols);
}
}
@@ -1654,12 +1624,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
// parameters in any class methods need it for the clang types for
// function prototypes.
LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
- type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
- attrs.byte_size, nullptr, LLDB_INVALID_UID,
- Type::eEncodingIsUID, &attrs.decl,
- clang_type, Type::ResolveState::Forward);
-
- type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class);
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type,
+ Type::ResolveState::Forward,
+ TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class));
// Add our type to the unique type map so we don't end up creating many
// copies of the same type over and over in the ASTContext for our
@@ -1705,8 +1674,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
// these child definitions.
if (!die.HasChildren()) {
// No children for this struct/union/class, lets finish it
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
+ TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
} else {
dwarf->GetObjectFile()->GetModule()->ReportError(
"DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
@@ -1718,7 +1687,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
if (tag == DW_TAG_structure_type) // this only applies in C
{
clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
+ TypeSystemClang::GetAsRecordDecl(clang_type);
if (record_decl) {
GetClangASTImporter().SetRecordLayout(
@@ -1736,7 +1705,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
if (attrs.class_language != eLanguageTypeObjC &&
attrs.class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
// Leave this as a forward declaration until we need to know the
// details of the type. lldb_private::Type will automatically call
@@ -1752,9 +1721,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
// binaries.
dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
- die.GetID();
+ dwarf->GetForwardDeclClangTypeToDie().try_emplace(
+ ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
+ *die.GetDIERef());
m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
}
}
@@ -1799,7 +1768,7 @@ public:
m_property_getter_name(property_getter_name),
m_property_attributes(property_attributes) {
if (metadata != nullptr) {
- m_metadata_up.reset(new ClangASTMetadata());
+ m_metadata_up = std::make_unique<ClangASTMetadata>();
*m_metadata_up = *metadata;
}
}
@@ -1819,14 +1788,14 @@ public:
m_property_attributes = rhs.m_property_attributes;
if (rhs.m_metadata_up) {
- m_metadata_up.reset(new ClangASTMetadata());
+ m_metadata_up = std::make_unique<ClangASTMetadata>();
*m_metadata_up = *rhs.m_metadata_up;
}
return *this;
}
bool Finalize() {
- return ClangASTContext::AddObjCClassProperty(
+ return TypeSystemClang::AddObjCClassProperty(
m_class_opaque_type, m_property_name, m_property_opaque_type,
m_ivar_decl, m_property_setter_name, m_property_getter_name,
m_property_attributes, m_metadata_up.get());
@@ -1845,14 +1814,14 @@ private:
bool DWARFASTParserClang::ParseTemplateDIE(
const DWARFDIE &die,
- ClangASTContext::TemplateParameterInfos &template_param_infos) {
+ TypeSystemClang::TemplateParameterInfos &template_param_infos) {
const dw_tag_t tag = die.Tag();
bool is_template_template_argument = false;
switch (tag) {
case DW_TAG_GNU_template_parameter_pack: {
- template_param_infos.packed_args.reset(
- new ClangASTContext::TemplateParameterInfos);
+ template_param_infos.packed_args =
+ std::make_unique<TypeSystemClang::TemplateParameterInfos>();
for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
child_die = child_die.GetSibling()) {
if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
@@ -1954,7 +1923,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
bool DWARFASTParserClang::ParseTemplateParameterInfos(
const DWARFDIE &parent_die,
- ClangASTContext::TemplateParameterInfos &template_param_infos) {
+ TypeSystemClang::TemplateParameterInfos &template_param_infos) {
if (!parent_die)
return false;
@@ -1988,141 +1957,102 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
ClangASTImporter::LayoutInfo layout_info;
- {
- if (die.HasChildren()) {
- LanguageType class_language = eLanguageTypeUnknown;
- if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) {
- class_language = eLanguageTypeObjC;
- // For objective C we don't start the definition when the class is
- // created.
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
- }
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type) {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_union_type) {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_class_type) {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
-
- std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
- std::vector<int> member_accessibilities;
- bool is_a_class = false;
- // Parse members and base classes first
- std::vector<DWARFDIE> member_function_dies;
-
- DelayedPropertyList delayed_properties;
- ParseChildMembers(die, clang_type, class_language, bases,
- member_accessibilities, member_function_dies,
- delayed_properties, default_accessibility, is_a_class,
- layout_info);
-
- // Now parse any methods if there were any...
- for (const DWARFDIE &die : member_function_dies)
- dwarf->ResolveType(die);
-
- if (class_language == eLanguageTypeObjC) {
- ConstString class_name(clang_type.GetTypeName());
- if (class_name) {
- DIEArray method_die_offsets;
- dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
-
- if (!method_die_offsets.empty()) {
- DWARFDebugInfo *debug_info = dwarf->DebugInfo();
-
- const size_t num_matches = method_die_offsets.size();
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = method_die_offsets[i];
- DWARFDIE method_die = debug_info->GetDIE(die_ref);
-
- if (method_die)
- method_die.ResolveType();
- }
- }
-
- for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
- pe = delayed_properties.end();
- pi != pe; ++pi)
- pi->Finalize();
- }
- }
+ if (die.HasChildren()) {
+ const bool type_is_objc_object_or_interface =
+ TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type);
+ if (type_is_objc_object_or_interface) {
+ // For objective C we don't start the definition when the class is
+ // created.
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
+ }
+
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
+
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
+ std::vector<int> member_accessibilities;
+ bool is_a_class = false;
+ // Parse members and base classes first
+ std::vector<DWARFDIE> member_function_dies;
+
+ DelayedPropertyList delayed_properties;
+ ParseChildMembers(die, clang_type, bases, member_accessibilities,
+ member_function_dies, delayed_properties,
+ default_accessibility, is_a_class, layout_info);
+
+ // Now parse any methods if there were any...
+ for (const DWARFDIE &die : member_function_dies)
+ dwarf->ResolveType(die);
+
+ if (type_is_objc_object_or_interface) {
+ ConstString class_name(clang_type.GetTypeName());
+ if (class_name) {
+ dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) {
+ method_die.ResolveType();
+ return true;
+ });
- // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
- // need to tell the clang type it is actually a class.
- if (class_language != eLanguageTypeObjC) {
- if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
- clang::TTK_Class);
+ for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
+ pe = delayed_properties.end();
+ pi != pe; ++pi)
+ pi->Finalize();
}
+ }
- // Since DW_TAG_structure_type gets used for both classes and
- // structures, we may need to set any DW_TAG_member fields to have a
- // "private" access if none was specified. When we parsed the child
- // members we tracked that actual accessibility value for each
- // DW_TAG_member in the "member_accessibilities" array. If the value
- // for the member is zero, then it was set to the
- // "default_accessibility" which for structs was "public". Below we
- // correct this by setting any fields to "private" that weren't
- // correctly set.
- if (is_a_class && !member_accessibilities.empty()) {
- // This is a class and all members that didn't have their access
- // specified are private.
- m_ast.SetDefaultAccessForRecordFields(
- m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
- &member_accessibilities.front(), member_accessibilities.size());
+ // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
+ // need to tell the clang type it is actually a class.
+ if (!type_is_objc_object_or_interface) {
+ if (is_a_class && tag_decl_kind != clang::TTK_Class)
+ m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
+ clang::TTK_Class);
+ }
+
+ // Since DW_TAG_structure_type gets used for both classes and
+ // structures, we may need to set any DW_TAG_member fields to have a
+ // "private" access if none was specified. When we parsed the child
+ // members we tracked that actual accessibility value for each
+ // DW_TAG_member in the "member_accessibilities" array. If the value
+ // for the member is zero, then it was set to the
+ // "default_accessibility" which for structs was "public". Below we
+ // correct this by setting any fields to "private" that weren't
+ // correctly set.
+ if (is_a_class && !member_accessibilities.empty()) {
+ // This is a class and all members that didn't have their access
+ // specified are private.
+ m_ast.SetDefaultAccessForRecordFields(
+ m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
+ &member_accessibilities.front(), member_accessibilities.size());
+ }
+
+ if (!bases.empty()) {
+ // Make sure all base classes refer to complete types and not forward
+ // declarations. If we don't do this, clang will crash with an
+ // assertion in the call to clang_type.TransferBaseClasses()
+ for (const auto &base_class : bases) {
+ clang::TypeSourceInfo *type_source_info =
+ base_class->getTypeSourceInfo();
+ if (type_source_info)
+ CompleteType(m_ast.GetType(type_source_info->getType()));
}
- if (!bases.empty()) {
- // Make sure all base classes refer to complete types and not forward
- // declarations. If we don't do this, clang will crash with an
- // assertion in the call to clang_type.TransferBaseClasses()
- for (const auto &base_class : bases) {
- clang::TypeSourceInfo *type_source_info =
- base_class->getTypeSourceInfo();
- if (type_source_info) {
- CompilerType base_class_type =
- m_ast.GetType(type_source_info->getType());
- if (!base_class_type.GetCompleteType()) {
- auto module = dwarf->GetObjectFile()->GetModule();
- module->ReportError(":: Class '%s' has a base class '%s' which "
- "does not have a complete definition.",
- die.GetName(),
- base_class_type.GetTypeName().GetCString());
- if (die.GetCU()->GetProducer() == eProducerClang)
- module->ReportError(":: Try compiling the source file with "
- "-fstandalone-debug.");
-
- // We have no choice other than to pretend that the base class
- // is complete. If we don't do this, clang will crash when we
- // call setBases() inside of
- // "clang_type.TransferBaseClasses()" below. Since we
- // provide layout assistance, all ivars in this class and other
- // classes will be fine, this is the best we can do short of
- // crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(
- base_class_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(
- base_class_type);
- }
- }
- }
- }
-
- m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
- std::move(bases));
- }
+ m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
+ std::move(bases));
}
}
m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType());
- ClangASTContext::BuildIndirectFields(clang_type);
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ TypeSystemClang::BuildIndirectFields(clang_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() ||
!layout_info.vbase_offsets.empty()) {
@@ -2144,14 +2074,14 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die,
lldb_private::Type *type,
CompilerType &clang_type) {
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
if (die.HasChildren()) {
bool is_signed = false;
clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(clang_type, is_signed,
type->GetByteSize().getValueOr(0), die);
}
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
}
return (bool)clang_type;
}
@@ -2211,7 +2141,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
clang::Decl *clang_decl = GetClangDeclForDIE(die);
if (clang_decl != nullptr)
- return CompilerDecl(&m_ast, clang_decl);
+ return m_ast.GetCompilerDecl(clang_decl);
return CompilerDecl();
}
@@ -2340,9 +2270,11 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
func_name.SetValue(ConstString(mangled), true);
else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
die.GetParent().Tag() == DW_TAG_partial_unit) &&
- Language::LanguageIsCPlusPlus(die.GetLanguage()) &&
- !Language::LanguageIsObjC(die.GetLanguage()) && name &&
- strcmp(name, "main") != 0) {
+ Language::LanguageIsCPlusPlus(
+ SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
+ !Language::LanguageIsObjC(
+ SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
+ name && strcmp(name, "main") != 0) {
// If the mangled name is not present in the DWARF, generate the
// demangled name using the decl context. We skip if the function is
// "main" as its name is never mangled.
@@ -2352,10 +2284,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
unsigned type_quals = 0;
std::vector<CompilerType> param_types;
std::vector<clang::ParmVarDecl *> param_decls;
- DWARFDeclContext decl_ctx;
StreamString sstr;
- die.GetDWARFDeclContext(decl_ctx);
+ DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
sstr << decl_ctx.GetQualifiedName();
clang::DeclContext *containing_decl_ctx =
@@ -2382,8 +2313,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
FunctionSP func_sp;
std::unique_ptr<Declaration> decl_up;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_up.reset(new Declaration(die.GetCU()->GetFile(decl_file),
- decl_line, decl_column));
+ decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file),
+ decl_line, decl_column);
SymbolFileDWARF *dwarf = die.GetDWARF();
// Supply the type _only_ if it has already been parsed
@@ -2413,13 +2344,12 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
void DWARFASTParserClang::ParseSingleMember(
const DWARFDIE &die, const DWARFDIE &parent_die,
- lldb_private::CompilerType &class_clang_type,
- const lldb::LanguageType class_language,
+ const lldb_private::CompilerType &class_clang_type,
std::vector<int> &member_accessibilities,
- lldb::AccessType &default_accessibility,
+ lldb::AccessType default_accessibility,
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
- BitfieldInfo &last_field_info) {
+ FieldInfo &last_field_info) {
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
const dw_tag_t tag = die.Tag();
// Get the parent byte size so we can verify any members will fit
@@ -2430,453 +2360,400 @@ void DWARFASTParserClang::ParseSingleMember(
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- const char *name = nullptr;
- const char *prop_name = nullptr;
- const char *prop_getter_name = nullptr;
- const char *prop_setter_name = nullptr;
- uint32_t prop_attributes = 0;
-
- bool is_artificial = false;
- DWARFFormValue encoding_form;
- AccessType accessibility = eAccessNone;
- uint32_t member_byte_offset =
- (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
- llvm::Optional<uint64_t> byte_size;
- int64_t bit_offset = 0;
- uint64_t data_bit_offset = UINT64_MAX;
- size_t bit_size = 0;
- bool is_external =
- false; // On DW_TAG_members, this means the member is static
- uint32_t i;
- for (i = 0; i < num_attributes && !is_artificial; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_type:
- encoding_form = form_value;
- break;
- case DW_AT_bit_offset:
- bit_offset = form_value.Signed();
- break;
- case DW_AT_bit_size:
- bit_size = form_value.Unsigned();
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_data_bit_offset:
- data_bit_offset = form_value.Unsigned();
- break;
- case DW_AT_data_member_location:
- if (form_value.BlockData()) {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, // ExecutionContext *
- nullptr, // RegisterContext *
- module_sp,
- DataExtractor(debug_info_data, block_offset, block_length),
- die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
- memberOffset, nullptr)) {
- member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
- }
- } else {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning of
- // the containing entity.
- member_byte_offset = form_value.Unsigned();
+ if (num_attributes == 0)
+ return;
+
+ const char *name = nullptr;
+ const char *prop_name = nullptr;
+ const char *prop_getter_name = nullptr;
+ const char *prop_setter_name = nullptr;
+ uint32_t prop_attributes = 0;
+
+ bool is_artificial = false;
+ DWARFFormValue encoding_form;
+ AccessType accessibility = eAccessNone;
+ uint32_t member_byte_offset =
+ (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
+ llvm::Optional<uint64_t> byte_size;
+ int64_t bit_offset = 0;
+ uint64_t data_bit_offset = UINT64_MAX;
+ size_t bit_size = 0;
+ bool is_external =
+ false; // On DW_TAG_members, this means the member is static
+ uint32_t i;
+ for (i = 0; i < num_attributes && !is_artificial; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ // DW_AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // DW_AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of the
+ // field starts. AT_bit_offset can be negative.
+ //
+ // DW_AT_bit_size indicates the size of the field in bits.
+ switch (attr) {
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ encoding_form = form_value;
+ break;
+ case DW_AT_bit_offset:
+ bit_offset = form_value.Signed();
+ break;
+ case DW_AT_bit_size:
+ bit_size = form_value.Unsigned();
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_data_bit_offset:
+ data_bit_offset = form_value.Unsigned();
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData()) {
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DWARFDataExtractor &debug_info_data = die.GetData();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ nullptr, // ExecutionContext *
+ nullptr, // RegisterContext *
+ module_sp,
+ DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
+ member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
}
- break;
+ } else {
+ // With DWARF 3 and later, if the value is an integer constant,
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
+ member_byte_offset = form_value.Unsigned();
+ }
+ break;
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
- case DW_AT_artificial:
- is_artificial = form_value.Boolean();
- break;
- case DW_AT_APPLE_property_name:
- prop_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_getter:
- prop_getter_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_setter:
- prop_setter_name = form_value.AsCString();
- break;
- case DW_AT_APPLE_property_attribute:
- prop_attributes = form_value.Unsigned();
- break;
- case DW_AT_external:
- is_external = form_value.Boolean();
- break;
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_APPLE_property_name:
+ prop_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_getter:
+ prop_getter_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_setter:
+ prop_setter_name = form_value.AsCString();
+ break;
+ case DW_AT_APPLE_property_attribute:
+ prop_attributes = form_value.Unsigned();
+ break;
+ case DW_AT_external:
+ is_external = form_value.Boolean();
+ break;
- default:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_mutable:
- case DW_AT_visibility:
- case DW_AT_sibling:
- break;
- }
+ default:
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_mutable:
+ case DW_AT_visibility:
+ case DW_AT_sibling:
+ break;
}
}
+ }
- if (prop_name) {
- ConstString fixed_setter;
+ if (prop_name) {
+ ConstString fixed_setter;
- // Check if the property getter/setter were provided as full names.
- // We want basenames, so we extract them.
+ // Check if the property getter/setter were provided as full names.
+ // We want basenames, so we extract them.
- if (prop_getter_name && prop_getter_name[0] == '-') {
- ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
- prop_getter_name = prop_getter_method.GetSelector().GetCString();
- }
+ if (prop_getter_name && prop_getter_name[0] == '-') {
+ ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
+ prop_getter_name = prop_getter_method.GetSelector().GetCString();
+ }
- if (prop_setter_name && prop_setter_name[0] == '-') {
- ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
- prop_setter_name = prop_setter_method.GetSelector().GetCString();
- }
+ if (prop_setter_name && prop_setter_name[0] == '-') {
+ ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
+ prop_setter_name = prop_setter_method.GetSelector().GetCString();
+ }
- // If the names haven't been provided, they need to be filled in.
+ // If the names haven't been provided, they need to be filled in.
- if (!prop_getter_name) {
- prop_getter_name = prop_name;
- }
- if (!prop_setter_name && prop_name[0] &&
- !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
- StreamString ss;
+ if (!prop_getter_name) {
+ prop_getter_name = prop_name;
+ }
+ if (!prop_setter_name && prop_name[0] &&
+ !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
+ StreamString ss;
- ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
+ ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
- fixed_setter.SetString(ss.GetString());
- prop_setter_name = fixed_setter.GetCString();
- }
+ fixed_setter.SetString(ss.GetString());
+ prop_setter_name = fixed_setter.GetCString();
}
+ }
- // Clang has a DWARF generation bug where sometimes it represents
- // fields that are references with bad byte size and bit size/offset
- // information such as:
- //
- // DW_AT_byte_size( 0x00 )
- // DW_AT_bit_size( 0x40 )
- // DW_AT_bit_offset( 0xffffffffffffffc0 )
- //
- // So check the bit offset to make sure it is sane, and if the values
- // are not sane, remove them. If we don't do this then we will end up
- // with a crash if we try to use this type in an expression when clang
- // becomes unhappy with its recycled debug info.
+ // Clang has a DWARF generation bug where sometimes it represents
+ // fields that are references with bad byte size and bit size/offset
+ // information such as:
+ //
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_bit_size( 0x40 )
+ // DW_AT_bit_offset( 0xffffffffffffffc0 )
+ //
+ // So check the bit offset to make sure it is sane, and if the values
+ // are not sane, remove them. If we don't do this then we will end up
+ // with a crash if we try to use this type in an expression when clang
+ // becomes unhappy with its recycled debug info.
+
+ if (byte_size.getValueOr(0) == 0 && bit_offset < 0) {
+ bit_size = 0;
+ bit_offset = 0;
+ }
+
+ const bool class_is_objc_object_or_interface =
+ TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type);
+
+ // FIXME: Make Clang ignore Objective-C accessibility for expressions
+ if (class_is_objc_object_or_interface)
+ accessibility = eAccessNone;
- if (byte_size.getValueOr(0) == 0 && bit_offset < 0) {
- bit_size = 0;
- bit_offset = 0;
+ // Handle static members
+ if (is_external && member_byte_offset == UINT32_MAX) {
+ Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
+
+ if (var_type) {
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+ TypeSystemClang::AddVariableToRecordType(
+ class_clang_type, name, var_type->GetLayoutCompilerType(),
+ accessibility);
}
+ return;
+ }
- // FIXME: Make Clang ignore Objective-C accessibility for expressions
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus)
- accessibility = eAccessNone;
+ if (!is_artificial) {
+ Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
- // Handle static members
- if (is_external && member_byte_offset == UINT32_MAX) {
- Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
+ clang::FieldDecl *field_decl = nullptr;
+ const uint64_t character_width = 8;
+ const uint64_t word_width = 32;
+ if (tag == DW_TAG_member) {
+ if (member_type) {
+ CompilerType member_clang_type = member_type->GetLayoutCompilerType();
- if (var_type) {
if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
- ClangASTContext::AddVariableToRecordType(
- class_clang_type, name, var_type->GetLayoutCompilerType(),
- accessibility);
- }
- return;
- }
-
- if (!is_artificial) {
- Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
-
- clang::FieldDecl *field_decl = nullptr;
- if (tag == DW_TAG_member) {
- if (member_type) {
- if (accessibility == eAccessNone)
- accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
-
- uint64_t field_bit_offset =
- (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
- if (bit_size > 0) {
-
- BitfieldInfo this_field_info;
- this_field_info.bit_offset = field_bit_offset;
- this_field_info.bit_size = bit_size;
-
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the bit
- // offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of the
- // field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- if (data_bit_offset != UINT64_MAX) {
- this_field_info.bit_offset = data_bit_offset;
- } else {
- if (!byte_size)
- byte_size = member_type->GetByteSize();
+ accessibility = default_accessibility;
+ member_accessibilities.push_back(accessibility);
- ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
- if (objfile->GetByteOrder() == eByteOrderLittle) {
- this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
- this_field_info.bit_offset -= (bit_offset + bit_size);
- } else {
- this_field_info.bit_offset += bit_offset;
- }
+ uint64_t field_bit_offset =
+ (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (bit_size > 0) {
+ FieldInfo this_field_info;
+ this_field_info.bit_offset = field_bit_offset;
+ this_field_info.bit_size = bit_size;
+
+ if (data_bit_offset != UINT64_MAX) {
+ this_field_info.bit_offset = data_bit_offset;
+ } else {
+ if (!byte_size)
+ byte_size = member_type->GetByteSize();
+
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ if (objfile->GetByteOrder() == eByteOrderLittle) {
+ this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ } else {
+ this_field_info.bit_offset += bit_offset;
}
+ }
+
+ if ((this_field_info.bit_offset >= parent_bit_size) ||
+ (last_field_info.IsBitfield() &&
+ !last_field_info.NextBitfieldOffsetIsValid(
+ this_field_info.bit_offset))) {
+ ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+ objfile->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
+ "bit offset (0x%8.8" PRIx64
+ ") member will be ignored. Please file a bug against the "
+ "compiler and include the preprocessed output for %s\n",
+ die.GetID(), DW_TAG_value_to_name(tag), name,
+ this_field_info.bit_offset, GetUnitName(parent_die).c_str());
+ return;
+ }
+
+ // Update the field bit offset we will report for layout
+ field_bit_offset = this_field_info.bit_offset;
+
+ // Objective-C has invalid DW_AT_bit_offset values in older
+ // versions of clang, so we have to be careful and only insert
+ // unnamed bitfields if we have a new enough clang.
+ bool detect_unnamed_bitfields = true;
+
+ if (class_is_objc_object_or_interface)
+ detect_unnamed_bitfields =
+ die.GetCU()->Supports_unnamed_objc_bitfields();
- if ((this_field_info.bit_offset >= parent_bit_size) ||
- !last_field_info.NextBitfieldOffsetIsValid(
- this_field_info.bit_offset)) {
- ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
- objfile->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
- "bit offset (0x%8.8" PRIx64
- ") member will be ignored. Please file a bug against the "
- "compiler and include the preprocessed output for %s\n",
- die.GetID(), DW_TAG_value_to_name(tag), name,
- this_field_info.bit_offset, GetUnitName(parent_die).c_str());
- this_field_info.Clear();
- return;
+ if (detect_unnamed_bitfields) {
+ clang::Optional<FieldInfo> unnamed_field_info;
+ uint64_t last_field_end = 0;
+
+ last_field_end =
+ last_field_info.bit_offset + last_field_info.bit_size;
+
+ if (!last_field_info.IsBitfield()) {
+ // The last field was not a bit-field...
+ // but if it did take up the entire word then we need to extend
+ // last_field_end so the bit-field does not step into the last
+ // fields padding.
+ if (last_field_end != 0 && ((last_field_end % word_width) != 0))
+ last_field_end += word_width - (last_field_end % word_width);
}
- // Update the field bit offset we will report for layout
- field_bit_offset = this_field_info.bit_offset;
-
- // If the member to be emitted did not start on a character
- // boundary and there is empty space between the last field and
- // this one, then we need to emit an anonymous member filling
- // up the space up to its start. There are three cases here:
- //
- // 1 If the previous member ended on a character boundary, then
- // we can emit an
- // anonymous member starting at the most recent character
- // boundary.
- //
- // 2 If the previous member did not end on a character boundary
- // and the distance
- // from the end of the previous member to the current member
- // is less than a
- // word width, then we can emit an anonymous member starting
- // right after the
- // previous member and right before this member.
- //
- // 3 If the previous member did not end on a character boundary
- // and the distance
- // from the end of the previous member to the current member
- // is greater than
- // or equal a word width, then we act as in Case 1.
-
- const uint64_t character_width = 8;
- const uint64_t word_width = 32;
-
- // Objective-C has invalid DW_AT_bit_offset values in older
- // versions of clang, so we have to be careful and only insert
- // unnamed bitfields if we have a new enough clang.
- bool detect_unnamed_bitfields = true;
-
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus)
- detect_unnamed_bitfields =
- die.GetCU()->Supports_unnamed_objc_bitfields();
-
- if (detect_unnamed_bitfields) {
- BitfieldInfo anon_field_info;
-
- if ((this_field_info.bit_offset % character_width) !=
- 0) // not char aligned
- {
- uint64_t last_field_end = 0;
-
- if (last_field_info.IsValid())
- last_field_end =
- last_field_info.bit_offset + last_field_info.bit_size;
-
- if (this_field_info.bit_offset != last_field_end) {
- if (((last_field_end % character_width) == 0) || // case 1
- (this_field_info.bit_offset - last_field_end >=
- word_width)) // case 3
- {
- anon_field_info.bit_size =
- this_field_info.bit_offset % character_width;
- anon_field_info.bit_offset =
- this_field_info.bit_offset - anon_field_info.bit_size;
- } else // case 2
- {
- anon_field_info.bit_size =
- this_field_info.bit_offset - last_field_end;
- anon_field_info.bit_offset = last_field_end;
- }
- }
- }
+ // If we have a gap between the last_field_end and the current
+ // field we have an unnamed bit-field.
+ // If we have a base class, we assume there is no unnamed
+ // bit-field if this is the first field since the gap can be
+ // attributed to the members from the base class. This assumption
+ // is not correct if the first field of the derived class is
+ // indeed an unnamed bit-field. We currently do not have the
+ // machinary to track the offset of the last field of classes we
+ // have seen before, so we are not handling this case.
+ if (this_field_info.bit_offset != last_field_end &&
+ this_field_info.bit_offset > last_field_end &&
+ !(last_field_info.bit_offset == 0 &&
+ last_field_info.bit_size == 0 &&
+ layout_info.base_offsets.size() != 0)) {
+ unnamed_field_info = FieldInfo{};
+ unnamed_field_info->bit_size =
+ this_field_info.bit_offset - last_field_end;
+ unnamed_field_info->bit_offset = last_field_end;
+ }
- if (anon_field_info.IsValid()) {
- clang::FieldDecl *unnamed_bitfield_decl =
- ClangASTContext::AddFieldToRecordType(
- class_clang_type, llvm::StringRef(),
- m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
- word_width),
- accessibility, anon_field_info.bit_size);
+ if (unnamed_field_info) {
+ clang::FieldDecl *unnamed_bitfield_decl =
+ TypeSystemClang::AddFieldToRecordType(
+ class_clang_type, llvm::StringRef(),
+ m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
+ word_width),
+ accessibility, unnamed_field_info->bit_size);
- layout_info.field_offsets.insert(std::make_pair(
- unnamed_bitfield_decl, anon_field_info.bit_offset));
- }
+ layout_info.field_offsets.insert(std::make_pair(
+ unnamed_bitfield_decl, unnamed_field_info->bit_offset));
}
- last_field_info = this_field_info;
- } else {
- last_field_info.Clear();
}
- CompilerType member_clang_type = member_type->GetLayoutCompilerType();
- if (!member_clang_type.IsCompleteType())
- member_clang_type.GetCompleteType();
-
- {
- // Older versions of clang emit array[0] and array[1] in the
- // same way (<rdar://problem/12566646>). If the current field
- // is at the end of the structure, then there is definitely no
- // room for extra elements and we override the type to
- // array[0].
-
- CompilerType member_array_element_type;
- uint64_t member_array_size;
- bool member_array_is_incomplete;
-
- if (member_clang_type.IsArrayType(&member_array_element_type,
- &member_array_size,
- &member_array_is_incomplete) &&
- !member_array_is_incomplete) {
- uint64_t parent_byte_size =
- parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
- UINT64_MAX);
-
- if (member_byte_offset >= parent_byte_size) {
- if (member_array_size != 1 &&
- (member_array_size != 0 ||
- member_byte_offset > parent_byte_size)) {
- module_sp->ReportError(
- "0x%8.8" PRIx64
- ": DW_TAG_member '%s' refers to type 0x%8.8x"
- " which extends beyond the bounds of 0x%8.8" PRIx64,
- die.GetID(), name, encoding_form.Reference().GetOffset(),
- parent_die.GetID());
- }
+ last_field_info = this_field_info;
+ last_field_info.SetIsBitfield(true);
+ } else {
+ last_field_info.bit_offset = field_bit_offset;
- member_clang_type =
- m_ast.CreateArrayType(member_array_element_type, 0, false);
- }
- }
+ if (llvm::Optional<uint64_t> clang_type_size =
+ member_clang_type.GetByteSize(nullptr)) {
+ last_field_info.bit_size = *clang_type_size * character_width;
}
- if (ClangASTContext::IsCXXClassType(member_clang_type) &&
- !member_clang_type.GetCompleteType()) {
- if (die.GetCU()->GetProducer() == eProducerClang)
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type is a forward declaration, not a "
- "complete definition.\nTry compiling the source file "
- "with -fstandalone-debug",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name);
- else
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type is a forward declaration, not a "
- "complete definition.\nPlease file a bug against the "
- "compiler and include the preprocessed output for %s",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name, GetUnitName(parent_die).c_str());
- // We have no choice other than to pretend that the member
- // class is complete. If we don't do this, clang will crash
- // when trying to layout the class. Since we provide layout
- // assistance, all ivars in this class and other classes will
- // be fine, this is the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(
- member_clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(
- member_clang_type);
- } else {
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type claims to be a C++ class but we "
- "were not able to start its definition.\nPlease file a "
- "bug and attach the file at the start of this error "
- "message",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name);
+ last_field_info.SetIsBitfield(false);
+ }
+
+ if (!member_clang_type.IsCompleteType())
+ member_clang_type.GetCompleteType();
+
+ {
+ // Older versions of clang emit array[0] and array[1] in the
+ // same way (<rdar://problem/12566646>). If the current field
+ // is at the end of the structure, then there is definitely no
+ // room for extra elements and we override the type to
+ // array[0].
+
+ CompilerType member_array_element_type;
+ uint64_t member_array_size;
+ bool member_array_is_incomplete;
+
+ if (member_clang_type.IsArrayType(&member_array_element_type,
+ &member_array_size,
+ &member_array_is_incomplete) &&
+ !member_array_is_incomplete) {
+ uint64_t parent_byte_size =
+ parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
+ UINT64_MAX);
+
+ if (member_byte_offset >= parent_byte_size) {
+ if (member_array_size != 1 &&
+ (member_array_size != 0 ||
+ member_byte_offset > parent_byte_size)) {
+ module_sp->ReportError(
+ "0x%8.8" PRIx64
+ ": DW_TAG_member '%s' refers to type 0x%8.8x"
+ " which extends beyond the bounds of 0x%8.8" PRIx64,
+ die.GetID(), name, encoding_form.Reference().GetOffset(),
+ parent_die.GetID());
+ }
+
+ member_clang_type =
+ m_ast.CreateArrayType(member_array_element_type, 0, false);
}
}
+ }
- field_decl = ClangASTContext::AddFieldToRecordType(
- class_clang_type, name, member_clang_type, accessibility,
- bit_size);
+ CompleteType(member_clang_type);
- m_ast.SetMetadataAsUserID(field_decl, die.GetID());
+ field_decl = TypeSystemClang::AddFieldToRecordType(
+ class_clang_type, name, member_clang_type, accessibility,
+ bit_size);
- layout_info.field_offsets.insert(
- std::make_pair(field_decl, field_bit_offset));
- } else {
- if (name)
- module_sp->ReportError(
- "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
- " which was unable to be parsed",
- die.GetID(), name, encoding_form.Reference().GetOffset());
- else
- module_sp->ReportError(
- "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
- " which was unable to be parsed",
- die.GetID(), encoding_form.Reference().GetOffset());
- }
+ m_ast.SetMetadataAsUserID(field_decl, die.GetID());
+
+ layout_info.field_offsets.insert(
+ std::make_pair(field_decl, field_bit_offset));
+ } else {
+ if (name)
+ module_sp->ReportError(
+ "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
+ " which was unable to be parsed",
+ die.GetID(), name, encoding_form.Reference().GetOffset());
+ else
+ module_sp->ReportError(
+ "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
+ " which was unable to be parsed",
+ die.GetID(), encoding_form.Reference().GetOffset());
}
+ }
- if (prop_name != nullptr && member_type) {
- clang::ObjCIvarDecl *ivar_decl = nullptr;
+ if (prop_name != nullptr && member_type) {
+ clang::ObjCIvarDecl *ivar_decl = nullptr;
- if (field_decl) {
- ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
- assert(ivar_decl != nullptr);
- }
+ if (field_decl) {
+ ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
+ assert(ivar_decl != nullptr);
+ }
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- delayed_properties.push_back(DelayedAddObjCClassProperty(
- class_clang_type, prop_name, member_type->GetLayoutCompilerType(),
- ivar_decl, prop_setter_name, prop_getter_name, prop_attributes,
- &metadata));
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ delayed_properties.push_back(DelayedAddObjCClassProperty(
+ class_clang_type, prop_name, member_type->GetLayoutCompilerType(),
+ ivar_decl, prop_setter_name, prop_getter_name, prop_attributes,
+ &metadata));
- if (ivar_decl)
- m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
- }
+ if (ivar_decl)
+ m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
}
}
}
bool DWARFASTParserClang::ParseChildMembers(
const DWARFDIE &parent_die, CompilerType &class_clang_type,
- const LanguageType class_language,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
std::vector<int> &member_accessibilities,
std::vector<DWARFDIE> &member_function_dies,
@@ -2885,11 +2762,11 @@ bool DWARFASTParserClang::ParseChildMembers(
if (!parent_die)
return false;
- BitfieldInfo last_field_info;
+ FieldInfo last_field_info;
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
- ClangASTContext *ast =
- llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem());
if (ast == nullptr)
return false;
@@ -2900,7 +2777,7 @@ bool DWARFASTParserClang::ParseChildMembers(
switch (tag) {
case DW_TAG_member:
case DW_TAG_APPLE_property:
- ParseSingleMember(die, parent_die, class_clang_type, class_language,
+ ParseSingleMember(die, parent_die, class_clang_type,
member_accessibilities, default_accessibility,
delayed_properties, layout_info, last_field_info);
break;
@@ -2990,7 +2867,7 @@ bool DWARFASTParserClang::ParseChildMembers(
CompilerType base_class_clang_type =
base_class_type->GetFullCompilerType();
assert(base_class_clang_type);
- if (class_language == eLanguageTypeObjC) {
+ if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) {
ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
} else {
std::unique_ptr<clang::CXXBaseSpecifier> result =
@@ -3121,9 +2998,9 @@ size_t DWARFASTParserClang::ParseChildParameters(
function_param_types.push_back(type->GetForwardCompilerType());
clang::ParmVarDecl *param_var_decl =
- m_ast.CreateParameterDeclaration(containing_decl_ctx, name,
- type->GetForwardCompilerType(),
- storage);
+ m_ast.CreateParameterDeclaration(
+ containing_decl_ctx, GetOwningClangModule(die), name,
+ type->GetForwardCompilerType(), storage);
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
@@ -3318,10 +3195,10 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
if (dwarf && type) {
const char *name = die.GetName();
clang::DeclContext *decl_context =
- ClangASTContext::DeclContextGetAsDeclContext(
+ TypeSystemClang::DeclContextGetAsDeclContext(
dwarf->GetDeclContextContainingUID(die.GetID()));
decl = m_ast.CreateVariableDeclaration(
- decl_context, name,
+ decl_context, GetOwningClangModule(die), name,
ClangUtil::GetQualType(type->GetForwardCompilerType()));
}
break;
@@ -3330,16 +3207,16 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
SymbolFileDWARF *dwarf = die.GetDWARF();
DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
if (imported_uid) {
- CompilerDecl imported_decl = imported_uid.GetDecl();
+ CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid);
if (imported_decl) {
clang::DeclContext *decl_context =
- ClangASTContext::DeclContextGetAsDeclContext(
+ TypeSystemClang::DeclContextGetAsDeclContext(
dwarf->GetDeclContextContainingUID(die.GetID()));
if (clang::NamedDecl *clang_imported_decl =
llvm::dyn_cast<clang::NamedDecl>(
(clang::Decl *)imported_decl.GetOpaqueDecl()))
- decl =
- m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
+ decl = m_ast.CreateUsingDeclaration(
+ decl_context, OptionalClangModuleID(), clang_imported_decl);
}
}
break;
@@ -3349,15 +3226,17 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
if (imported_uid) {
- CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
+ CompilerDeclContext imported_decl_ctx =
+ SymbolFileDWARF::GetDeclContext(imported_uid);
if (imported_decl_ctx) {
clang::DeclContext *decl_context =
- ClangASTContext::DeclContextGetAsDeclContext(
+ TypeSystemClang::DeclContextGetAsDeclContext(
dwarf->GetDeclContextContainingUID(die.GetID()));
if (clang::NamespaceDecl *ns_decl =
- ClangASTContext::DeclContextGetAsNamespaceDecl(
+ TypeSystemClang::DeclContextGetAsNamespaceDecl(
imported_decl_ctx))
- decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
+ decl = m_ast.CreateUsingDirectiveDeclaration(
+ decl_context, OptionalClangModuleID(), ns_decl);
}
}
break;
@@ -3415,6 +3294,32 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
return nullptr;
}
+OptionalClangModuleID
+DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
+ if (!die.IsValid())
+ return {};
+
+ for (DWARFDIE parent = die.GetParent(); parent.IsValid();
+ parent = parent.GetParent()) {
+ const dw_tag_t tag = parent.Tag();
+ if (tag == DW_TAG_module) {
+ DWARFDIE module_die = parent;
+ auto it = m_die_to_module.find(module_die.GetDIE());
+ if (it != m_die_to_module.end())
+ return it->second;
+ const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0);
+ if (!name)
+ return {};
+
+ OptionalClangModuleID id =
+ m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die));
+ m_die_to_module.insert({module_die.GetDIE(), id});
+ return id;
+ }
+ }
+ return {};
+}
+
static bool IsSubroutine(const DWARFDIE &die) {
switch (die.Tag()) {
case DW_TAG_subprogram:
@@ -3487,7 +3392,8 @@ clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
DWARFDIE decl_context_die;
clang::DeclContext *decl_context =
GetClangDeclContextContainingDIE(die, &decl_context_die);
- decl = m_ast.CreateBlockDeclaration(decl_context);
+ decl =
+ m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die));
if (decl)
LinkDeclContextToDIE((clang::DeclContext *)decl, die);
@@ -3515,7 +3421,8 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
- namespace_name, containing_decl_ctx, is_inline);
+ namespace_name, containing_decl_ctx, GetOwningClangModule(die),
+ is_inline);
Log *log =
nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log) {
@@ -3697,9 +3604,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
}
DWARFASTParserClang *src_dwarf_ast_parser =
- (DWARFASTParserClang *)src_die.GetDWARFParser();
+ static_cast<DWARFASTParserClang *>(
+ SymbolFileDWARF::GetDWARFParser(*src_die.GetCU()));
DWARFASTParserClang *dst_dwarf_ast_parser =
- (DWARFASTParserClang *)dst_die.GetDWARFParser();
+ static_cast<DWARFASTParserClang *>(
+ SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU()));
// Now do the work of linking the DeclContexts and Types.
if (fast_path) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 4ad757247c3e..2ef49abc1da1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFASTParserClang_h_
-#define SymbolFileDWARF_DWARFASTParserClang_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
#include "clang/AST/CharUnits.h"
#include "llvm/ADT/DenseMap.h"
@@ -19,10 +19,10 @@
#include "DWARFDefines.h"
#include "DWARFFormValue.h"
#include "LogChannelDWARF.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include <vector>
@@ -36,7 +36,7 @@ struct ParsedDWARFTypeAttributes;
class DWARFASTParserClang : public DWARFASTParser {
public:
- DWARFASTParserClang(lldb_private::ClangASTContext &ast);
+ DWARFASTParserClang(lldb_private::TypeSystemClang &ast);
~DWARFASTParserClang() override;
@@ -78,15 +78,19 @@ protected:
DIEToDeclContextMap;
typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+ lldb_private::OptionalClangModuleID>
+ DIEToModuleMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
DIEToDeclMap;
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
- lldb_private::ClangASTContext &m_ast;
+ lldb_private::TypeSystemClang &m_ast;
DIEToDeclMap m_die_to_decl;
DeclToDIEMap m_decl_to_die;
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
+ DIEToModuleMap m_die_to_module;
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
/// @}
@@ -97,16 +101,15 @@ protected:
clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
bool ParseTemplateDIE(const DWARFDIE &die,
- lldb_private::ClangASTContext::TemplateParameterInfos
+ lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
bool ParseTemplateParameterInfos(
const DWARFDIE &parent_die,
- lldb_private::ClangASTContext::TemplateParameterInfos
+ lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
bool ParseChildMembers(
const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
- const lldb::LanguageType class_language,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
std::vector<int> &member_accessibilities,
std::vector<DWARFDIE> &member_function_dies,
@@ -140,6 +143,7 @@ protected:
clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
DWARFDIE *decl_ctx_die);
+ lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
const DWARFDIE &dst_class_die,
@@ -170,45 +174,31 @@ protected:
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
private:
- struct BitfieldInfo {
- uint64_t bit_size;
- uint64_t bit_offset;
+ struct FieldInfo {
+ uint64_t bit_size = 0;
+ uint64_t bit_offset = 0;
+ bool is_bitfield = false;
- BitfieldInfo()
- : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {}
+ FieldInfo() = default;
- void Clear() {
- bit_size = LLDB_INVALID_ADDRESS;
- bit_offset = LLDB_INVALID_ADDRESS;
- }
-
- bool IsValid() const {
- return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
- }
+ void SetIsBitfield(bool flag) { is_bitfield = flag; }
+ bool IsBitfield() { return is_bitfield; }
bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
- if (IsValid()) {
- // This bitfield info is valid, so any subsequent bitfields must not
- // overlap and must be at a higher bit offset than any previous bitfield
- // + size.
- return (bit_size + bit_offset) <= next_bit_offset;
- } else {
- // If the this BitfieldInfo is not valid, then any offset isOK
- return true;
- }
+ // Any subsequent bitfields must not overlap and must be at a higher
+ // bit offset than any previous bitfield + size.
+ return (bit_size + bit_offset) <= next_bit_offset;
}
};
void
ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
- lldb_private::CompilerType &class_clang_type,
- const lldb::LanguageType class_language,
+ const lldb_private::CompilerType &class_clang_type,
std::vector<int> &member_accessibilities,
- lldb::AccessType &default_accessibility,
+ lldb::AccessType default_accessibility,
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
- BitfieldInfo &last_field_info);
+ FieldInfo &last_field_info);
bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
@@ -227,6 +217,12 @@ private:
ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
+
+ /// Complete a type from debug info, or mark it as forcefully completed if
+ /// there is no of the type in the current Module. Call this function in
+ /// contexts where the usual C++ rules require a type to be complete (base
+ /// class, member, etc.).
+ void CompleteType(lldb_private::CompilerType type);
};
/// Parsed form of all attributes that are relevant for type reconstruction.
@@ -264,4 +260,4 @@ struct ParsedDWARFTypeAttributes {
uint32_t encoding = 0;
};
-#endif // SymbolFileDWARF_DWARFASTParserClang_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 741669b05754..0e9370be15fb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
+//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index c0cf8823a368..f70aa71a5958 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DWARFAbbreviationDeclaration_h_
-#define liblldb_DWARFAbbreviationDeclaration_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H
#include "DWARFAttribute.h"
#include "DWARFDefines.h"
@@ -62,4 +62,4 @@ protected:
DWARFAttribute::collection m_attributes;
};
-#endif // liblldb_DWARFAbbreviationDeclaration_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index b3594a455680..6c72d9e26221 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFAttribute.cpp --------------------------------------*- C++ -*-===//
+//===-- DWARFAttribute.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 58427b19100a..9948969f108f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFAttribute_h_
-#define SymbolFileDWARF_DWARFAttribute_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H
#include "DWARFDefines.h"
#include "DWARFFormValue.h"
@@ -82,4 +82,4 @@ protected:
collection m_infos;
};
-#endif // SymbolFileDWARF_DWARFAttribute_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFATTRIBUTE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 033105efdc53..fcb424029f5a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFBaseDIE.cpp ---------------------------------------*- C++ -*-===//
+//===-- DWARFBaseDIE.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -74,13 +74,6 @@ const char *DWARFBaseDIE::GetName() const {
return nullptr;
}
-lldb::LanguageType DWARFBaseDIE::GetLanguage() const {
- if (IsValid())
- return m_cu->GetLanguageType();
- else
- return lldb::eLanguageTypeUnknown;
-}
-
lldb::ModuleSP DWARFBaseDIE::GetModule() const {
SymbolFileDWARF *dwarf = GetDWARF();
if (dwarf)
@@ -103,24 +96,6 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
return nullptr;
}
-llvm::Expected<lldb_private::TypeSystem &> DWARFBaseDIE::GetTypeSystem() const {
- if (!m_cu)
- return llvm::make_error<llvm::StringError>(
- "Unable to get TypeSystem, no compilation unit available",
- llvm::inconvertibleErrorCode());
- return m_cu->GetTypeSystem();
-}
-
-DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const {
- auto type_system_or_err = GetTypeSystem();
- if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
- std::move(err), "Unable to get DWARFASTParser");
- return nullptr;
- }
- return type_system_or_err->GetDWARFParser();
-}
-
bool DWARFBaseDIE::HasChildren() const {
return m_die && m_die->HasChildren();
}
@@ -130,11 +105,10 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
}
size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
- uint32_t depth) const {
+ Recurse recurse) const {
if (IsValid())
- return m_die->GetAttributes(m_cu, attributes, depth);
- if (depth == 0)
- attributes.Clear();
+ return m_die->GetAttributes(m_cu, attributes, recurse);
+ attributes.Clear();
return 0;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 9652d7946e87..059b84864be7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFBaseDIE_h_
-#define SymbolFileDWARF_DWARFBaseDIE_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
@@ -57,10 +57,6 @@ public:
llvm::Optional<DIERef> GetDIERef() const;
- llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem() const;
-
- DWARFASTParser *GetDWARFParser() const;
-
void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) {
if (cu && die) {
m_cu = cu;
@@ -98,8 +94,6 @@ public:
const char *GetName() const;
- lldb::LanguageType GetLanguage() const;
-
lldb::ModuleSP GetModule() const;
// Getting attribute values from the DIE.
@@ -116,7 +110,9 @@ public:
uint64_t GetAttributeValueAsAddress(const dw_attr_t attr,
uint64_t fail_value) const;
- size_t GetAttributes(DWARFAttributes &attributes, uint32_t depth = 0) const;
+ enum class Recurse : bool { no, yes };
+ size_t GetAttributes(DWARFAttributes &attributes,
+ Recurse recurse = Recurse::yes) const;
protected:
DWARFUnit *m_cu;
@@ -126,4 +122,4 @@ protected:
bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
-#endif // SymbolFileDWARF_DWARFBaseDIE_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 718f0537d6ed..f54fe0662aa2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===//
+//===-- DWARFCompileUnit.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -33,41 +33,27 @@ void DWARFCompileUnit::BuildAddressRangeTable(
size_t num_debug_aranges = debug_aranges->GetNumRanges();
- // First get the compile unit DIE only and check if it has a DW_AT_ranges
+ // First get the compile unit DIE only and check contains ranges information.
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
const dw_offset_t cu_offset = GetOffset();
if (die) {
DWARFRangeList ranges;
const size_t num_ranges =
- die->GetAttributeAddressRanges(this, ranges, false);
+ die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true);
if (num_ranges > 0) {
- // This compile unit has DW_AT_ranges, assume this is correct if it is
- // present since clang no longer makes .debug_aranges by default and it
- // emits DW_AT_ranges for DW_TAG_compile_units. GCC also does this with
- // recent GCC builds.
for (size_t i = 0; i < num_ranges; ++i) {
const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
range.GetRangeEnd());
}
- return; // We got all of our ranges from the DW_AT_ranges attribute
+ return;
}
}
- // We don't have a DW_AT_ranges attribute, so we need to parse the DWARF
-
- // If the DIEs weren't parsed, then we don't want all dies for all compile
- // units to stay loaded when they weren't needed. So we can end up parsing
- // the DWARF and then throwing them all away to keep memory usage down.
- ScopedExtractDIEs clear_dies(ExtractDIEsScoped());
-
- die = DIEPtr();
- if (die)
- die->BuildAddressRangeTable(this, debug_aranges);
if (debug_aranges->GetNumRanges() == num_debug_aranges) {
- // We got nothing from the functions, maybe we have a line tables only
+ // We got nothing from the debug info, maybe we have a line tables only
// situation. Check the line tables and build the arange table from this.
SymbolContext sc;
sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 454637ef981c..3ec161f7dd51 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFCompileUnit_h_
-#define SymbolFileDWARF_DWARFCompileUnit_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H
#include "DWARFUnit.h"
#include "llvm/Support/Error.h"
@@ -27,9 +27,10 @@ private:
DIERef::Section section, bool is_dwo)
: DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {}
- DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
+ DWARFCompileUnit(const DWARFCompileUnit &) = delete;
+ const DWARFCompileUnit &operator=(const DWARFCompileUnit &) = delete;
friend class DWARFUnit;
};
-#endif // SymbolFileDWARF_DWARFCompileUnit_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCOMPILEUNIT_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
index 5052b825fea6..37e28a09f3c4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFContext.cpp ----------------------------------------*- C++ -*-===//
+//===-- DWARFContext.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -28,18 +28,28 @@ static DWARFDataExtractor LoadSection(SectionList *section_list,
}
const DWARFDataExtractor &
-DWARFContext::LoadOrGetSection(SectionType main_section_type,
+DWARFContext::LoadOrGetSection(llvm::Optional<SectionType> main_section_type,
llvm::Optional<SectionType> dwo_section_type,
SectionData &data) {
llvm::call_once(data.flag, [&] {
if (dwo_section_type && isDwo())
data.data = LoadSection(m_dwo_section_list, *dwo_section_type);
- else
- data.data = LoadSection(m_main_section_list, main_section_type);
+ else if (main_section_type)
+ data.data = LoadSection(m_main_section_list, *main_section_type);
});
return data.data;
}
+const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() {
+ return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugCuIndex,
+ m_data_debug_cu_index);
+}
+
+const DWARFDataExtractor &DWARFContext::getOrLoadTuIndexData() {
+ return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugTuIndex,
+ m_data_debug_tu_index);
+}
+
const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
@@ -117,32 +127,19 @@ llvm::DWARFContext &DWARFContext::GetAsLLVM() {
if (!m_llvm_context) {
llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> section_map;
uint8_t addr_size = 0;
-
- auto AddSection = [&](Section &section) {
- DataExtractor section_data;
- section.GetSectionData(section_data);
-
+ auto AddSection = [&](llvm::StringRef name, DWARFDataExtractor data) {
// Set the address size the first time we see it.
if (addr_size == 0)
- addr_size = section_data.GetByteSize();
+ addr_size = data.GetAddressByteSize();
- llvm::StringRef data = llvm::toStringRef(section_data.GetData());
- llvm::StringRef name = section.GetName().GetStringRef();
- if (name.startswith("."))
- name = name.drop_front();
section_map.try_emplace(
- name, llvm::MemoryBuffer::getMemBuffer(data, name, false));
+ name, llvm::MemoryBuffer::getMemBuffer(toStringRef(data.GetData()),
+ name, false));
};
- if (m_main_section_list) {
- for (auto &section : *m_main_section_list)
- AddSection(*section);
- }
-
- if (m_dwo_section_list) {
- for (auto &section : *m_dwo_section_list)
- AddSection(*section);
- }
+ AddSection("debug_line_str", getOrLoadLineStrData());
+ AddSection("debug_cu_index", getOrLoadCuIndexData());
+ AddSection("debug_tu_index", getOrLoadTuIndexData());
m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
index 8691001b1b76..92161a21d167 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
-#define LLDB_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFCONTEXT_H
#include "DWARFDataExtractor.h"
#include "lldb/Core/Section.h"
@@ -31,6 +31,7 @@ private:
SectionData m_data_debug_abbrev;
SectionData m_data_debug_addr;
SectionData m_data_debug_aranges;
+ SectionData m_data_debug_cu_index;
SectionData m_data_debug_info;
SectionData m_data_debug_line;
SectionData m_data_debug_line_str;
@@ -41,13 +42,17 @@ private:
SectionData m_data_debug_rnglists;
SectionData m_data_debug_str;
SectionData m_data_debug_str_offsets;
+ SectionData m_data_debug_tu_index;
SectionData m_data_debug_types;
const DWARFDataExtractor &
- LoadOrGetSection(lldb::SectionType main_section_type,
+ LoadOrGetSection(llvm::Optional<lldb::SectionType> main_section_type,
llvm::Optional<lldb::SectionType> dwo_section_type,
SectionData &data);
+ const DWARFDataExtractor &getOrLoadCuIndexData();
+ const DWARFDataExtractor &getOrLoadTuIndexData();
+
public:
explicit DWARFContext(SectionList *main_section_list,
SectionList *dwo_section_list)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index c5411a17f274..8e995e627978 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDIE.cpp --------------------------------------------*- C++ -*-===//
+//===-- DWARFDIE.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -32,7 +32,7 @@ class ElaboratingDIEIterator
// Container sizes are optimized for the case of following DW_AT_specification
// and DW_AT_abstract_origin just once.
llvm::SmallVector<DWARFDIE, 2> m_worklist;
- llvm::SmallSet<lldb::user_id_t, 3> m_seen;
+ llvm::SmallSet<DWARFDebugInfoEntry *, 3> m_seen;
void Next() {
assert(!m_worklist.empty() && "Incrementing end iterator?");
@@ -44,7 +44,7 @@ class ElaboratingDIEIterator
// And add back any items that elaborate it.
for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
if (DWARFDIE d = die.GetReferencedDIE(attr))
- if (m_seen.insert(die.GetID()).second)
+ if (m_seen.insert(die.GetDIE()).second)
m_worklist.push_back(d);
}
}
@@ -140,25 +140,64 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
}
DWARFDIE
-DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const {
- if (IsValid()) {
- SymbolFileDWARF *dwarf = GetDWARF();
- DWARFUnit *cu = GetCU();
- DWARFDebugInfoEntry *function_die = nullptr;
- DWARFDebugInfoEntry *block_die = nullptr;
- if (m_die->LookupAddress(file_addr, cu, &function_die, &block_die)) {
- if (block_die && block_die != function_die) {
- if (cu->ContainsDIEOffset(block_die->GetOffset()))
- return DWARFDIE(cu, block_die);
- else
- return DWARFDIE(dwarf->DebugInfo()->GetUnit(DIERef(
- cu->GetSymbolFileDWARF().GetDwoNum(),
- cu->GetDebugSection(), block_die->GetOffset())),
- block_die);
+DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
+ if (!IsValid())
+ return DWARFDIE();
+
+ DWARFDIE result;
+ bool check_children = false;
+ bool match_addr_range = false;
+ switch (Tag()) {
+ case DW_TAG_class_type:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_common_block:
+ check_children = true;
+ break;
+ case DW_TAG_compile_unit:
+ case DW_TAG_module:
+ case DW_TAG_catch_block:
+ case DW_TAG_subprogram:
+ case DW_TAG_try_block:
+ case DW_TAG_partial_unit:
+ match_addr_range = true;
+ break;
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ check_children = true;
+ match_addr_range = true;
+ break;
+ default:
+ break;
+ }
+
+ if (match_addr_range) {
+ DWARFRangeList ranges;
+ if (m_die->GetAttributeAddressRanges(m_cu, ranges,
+ /*check_hi_lo_pc=*/true) &&
+ ranges.FindEntryThatContains(address)) {
+ check_children = true;
+ switch (Tag()) {
+ default:
+ break;
+
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ result = *this;
+ break;
}
+ } else {
+ check_children = false;
}
}
- return DWARFDIE();
+
+ if (check_children) {
+ for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) {
+ if (DWARFDIE child_result = child.LookupDeepestBlock(address))
+ return child_result;
+ }
+ }
+ return result;
}
const char *DWARFDIE::GetMangledName() const {
@@ -333,15 +372,6 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const {
return result;
}
-void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
- if (IsValid()) {
- dwarf_decl_ctx.SetLanguage(GetLanguage());
- m_die->GetDWARFDeclContext(GetCU(), dwarf_decl_ctx);
- } else {
- dwarf_decl_ctx.Clear();
- }
-}
-
void DWARFDIE::GetDeclContext(
llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const {
const dw_tag_t tag = Tag();
@@ -418,27 +448,3 @@ bool DWARFDIE::GetDIENamesAndRanges(
} else
return false;
}
-
-CompilerDecl DWARFDIE::GetDecl() const {
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclForUIDFromDWARF(*this);
- else
- return CompilerDecl();
-}
-
-CompilerDeclContext DWARFDIE::GetDeclContext() const {
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextForUIDFromDWARF(*this);
- else
- return CompilerDeclContext();
-}
-
-CompilerDeclContext DWARFDIE::GetContainingDeclContext() const {
- DWARFASTParser *dwarf_ast = GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->GetDeclContextContainingUIDFromDWARF(*this);
- else
- return CompilerDeclContext();
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 87d52eee9dd9..13737280926c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDIE_h_
-#define SymbolFileDWARF_DWARFDIE_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
#include "DWARFBaseDIE.h"
#include "llvm/ADT/SmallSet.h"
@@ -70,8 +70,6 @@ public:
// DeclContext related functions
std::vector<DWARFDIE> GetDeclContextDIEs() const;
- void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const;
-
/// Return this DIE's decl context as it is needed to look up types
/// in Clang's -gmodules debug info format.
void GetDeclContext(
@@ -90,14 +88,6 @@ public:
int &decl_line, int &decl_column, int &call_file,
int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base) const;
-
- // CompilerDecl related functions
-
- lldb_private::CompilerDecl GetDecl() const;
-
- lldb_private::CompilerDeclContext GetDeclContext() const;
-
- lldb_private::CompilerDeclContext GetContainingDeclContext() const;
};
-#endif // SymbolFileDWARF_DWARFDIE_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
index 1678b228137f..cf483286a66d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDataExtractor.cpp ----------------------------------*- C++ -*-===//
+//===-- DWARFDataExtractor.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -23,8 +23,7 @@ DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVM() const {
return llvm::DWARFDataExtractor(
- llvm::StringRef(reinterpret_cast<const char *>(GetDataStart()),
- GetByteSize()),
+ llvm::makeArrayRef(GetDataStart(), GetByteSize()),
GetByteOrder() == lldb::eByteOrderLittle, GetAddressByteSize());
}
} // namespace lldb_private
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index 22db5e8c0b79..df92bd45d5cc 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DWARFDataExtractor_h_
-#define liblldb_DWARFDataExtractor_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/DataExtractor.h"
@@ -34,4 +34,4 @@ public:
};
}
-#endif // liblldb_DWARFDataExtractor_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDATAEXTRACTOR_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index 26301566a8e1..0f0f50a645db 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
+//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 9c4729326081..555864f44967 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugAbbrev_h_
-#define SymbolFileDWARF_DWARFDebugAbbrev_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
#include <list>
#include <map>
@@ -78,4 +78,4 @@ protected:
mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos;
};
-#endif // SymbolFileDWARF_DWARFDebugAbbrev_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index 86ce3b329b25..728cefe620a5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugArangeSet.cpp ---------------------------------*- C++ -*-===//
+//===-- DWARFDebugArangeSet.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -63,7 +63,8 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
// 1 - the version looks good
// 2 - the address byte size looks plausible
// 3 - the length seems to make sense
- // size looks plausible
+ // 4 - size looks plausible
+ // 5 - the arange tuples do not contain a segment field
if (m_header.version < 2 || m_header.version > 5)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Invalid arange header version");
@@ -81,6 +82,10 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
return llvm::make_error<llvm::object::GenericBinaryError>(
"Invalid arange header length");
+ if (m_header.seg_size)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "segmented arange entries are not supported");
+
// The first tuple following the header in each set begins at an offset
// that is a multiple of the size of a single tuple (that is, twice the
// size of an address). The header is padded, if necessary, to the
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
index db0cf22a3f45..6b5b69a70a80 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugArangeSet_h_
-#define SymbolFileDWARF_DWARFDebugArangeSet_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H
#include "lldb/Core/dwarf.h"
#include <cstdint>
@@ -59,4 +59,4 @@ protected:
DescriptorColl m_arange_descriptors;
};
-#endif // SymbolFileDWARF_DWARFDebugArangeSet_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGESET_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index c8da2381353e..7dc52c1e2df0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===//
+//===-- DWARFDebugAranges.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index 74ba011b27af..96e82619f985 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugAranges_h_
-#define SymbolFileDWARF_DWARFDebugAranges_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/RangeMap.h"
@@ -52,4 +52,4 @@ protected:
RangeToDIE m_aranges;
};
-#endif // SymbolFileDWARF_DWARFDebugAranges_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGARANGES_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 1e04baca2c58..874978bf1398 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugInfo.cpp --------------------------------------*- C++ -*-===//
+//===-- DWARFDebugInfo.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -72,10 +72,16 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
DWARFDataExtractor data = section == DIERef::Section::DebugTypes
? m_context.getOrLoadDebugTypesData()
: m_context.getOrLoadDebugInfoData();
+ const llvm::DWARFUnitIndex *index = nullptr;
+ if (m_context.isDwo())
+ index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
+ section == DIERef::Section::DebugTypes
+ ? llvm::DW_SECT_EXT_TYPES
+ : llvm::DW_SECT_INFO);
lldb::offset_t offset = 0;
while (data.ValidOffset(offset)) {
- llvm::Expected<DWARFUnitSP> unit_sp =
- DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset);
+ llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
+ m_dwarf, m_units.size(), data, section, &offset, index);
if (!unit_sp) {
// FIXME: Propagate this error up.
@@ -96,12 +102,11 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
}
void DWARFDebugInfo::ParseUnitHeadersIfNeeded() {
- if (!m_units.empty())
- return;
-
- ParseUnitsFor(DIERef::Section::DebugInfo);
- ParseUnitsFor(DIERef::Section::DebugTypes);
- llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
+ llvm::call_once(m_units_once_flag, [&] {
+ ParseUnitsFor(DIERef::Section::DebugInfo);
+ ParseUnitsFor(DIERef::Section::DebugTypes);
+ llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
+ });
}
size_t DWARFDebugInfo::GetNumUnits() {
@@ -109,7 +114,7 @@ size_t DWARFDebugInfo::GetNumUnits() {
return m_units.size();
}
-DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(user_id_t idx) {
+DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(size_t idx) {
DWARFUnit *cu = nullptr;
if (idx < GetNumUnits())
cu = m_units[idx].get();
@@ -191,7 +196,7 @@ DWARFDIE
DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
DWARFUnit *cu = GetUnit(die_ref);
if (cu)
- return cu->GetDIE(die_ref.die_offset());
+ return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset());
return DWARFDIE(); // Not found
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 056cf33a202f..bdc718a5c2fa 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugInfo_h_
-#define SymbolFileDWARF_DWARFDebugInfo_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H
#include <map>
#include <vector>
@@ -35,7 +35,7 @@ public:
lldb_private::DWARFContext &context);
size_t GetNumUnits();
- DWARFUnit *GetUnitAtIndex(lldb::user_id_t idx);
+ DWARFUnit *GetUnitAtIndex(size_t idx);
DWARFUnit *GetUnitAtOffset(DIERef::Section section, dw_offset_t cu_offset,
uint32_t *idx_ptr = nullptr);
DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
@@ -61,7 +61,10 @@ protected:
SymbolFileDWARF &m_dwarf;
lldb_private::DWARFContext &m_context;
+
+ llvm::once_flag m_units_once_flag;
UnitColl m_units;
+
std::unique_ptr<DWARFDebugAranges>
m_cu_aranges_up; // A quick address to compile unit table
@@ -76,7 +79,8 @@ private:
uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset);
- DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo);
+ DWARFDebugInfo(const DWARFDebugInfo &) = delete;
+ const DWARFDebugInfo &operator=(const DWARFDebugInfo &) = delete;
};
-#endif // SymbolFileDWARF_DWARFDebugInfo_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFO_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 320500fe608d..f6425a889da8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
+//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -395,152 +395,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
return !ranges.IsEmpty();
}
-// Dump
-//
-// Dumps a debug information entry and all of it's attributes to the specified
-// stream.
-void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s,
- uint32_t recurse_depth) const {
- const DWARFDataExtractor &data = cu->GetData();
- lldb::offset_t offset = m_offset;
-
- if (data.ValidOffset(offset)) {
- dw_uleb128_t abbrCode = data.GetULEB128(&offset);
-
- s.Printf("\n0x%8.8x: ", m_offset);
- s.Indent();
- if (abbrCode != m_abbr_idx) {
- s.Printf("error: DWARF has been modified\n");
- } else if (abbrCode) {
- const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
- if (abbrevDecl) {
- s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
- s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
-
- // Dump all data in the .debug_info/.debug_types for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- for (uint32_t i = 0; i < numAttributes; ++i) {
- DWARFFormValue form_value(cu);
- dw_attr_t attr;
- abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
-
- DumpAttribute(cu, data, &offset, s, attr, form_value);
- }
-
- const DWARFDebugInfoEntry *child = GetFirstChild();
- if (recurse_depth > 0 && child) {
- s.IndentMore();
-
- while (child) {
- child->Dump(cu, s, recurse_depth - 1);
- child = child->GetSibling();
- }
- s.IndentLess();
- }
- } else
- s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
- "code: %u\n",
- abbrCode);
- } else {
- s.Printf("NULL\n");
- }
- }
-}
-
-// DumpAttribute
-//
-// Dumps a debug information entry attribute along with it's form. Any special
-// display of attributes is done (disassemble location lists, show enumeration
-// values for attributes, etc).
-void DWARFDebugInfoEntry::DumpAttribute(
- const DWARFUnit *cu, const DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr,
- DWARFFormValue &form_value) {
- bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
-
- s.Printf(" ");
- s.Indent(DW_AT_value_to_name(attr));
-
- if (show_form) {
- s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
- }
-
- if (!form_value.ExtractValue(data, offset_ptr))
- return;
-
- if (show_form) {
- if (form_value.Form() == DW_FORM_indirect) {
- s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
- }
-
- s.PutCString("] ");
- }
-
- s.PutCString("( ");
-
- // Check to see if we have any special attribute formatters
- switch (attr) {
- case DW_AT_stmt_list:
- s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
- break;
-
- case DW_AT_language:
- s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
- break;
-
- case DW_AT_encoding:
- s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
- break;
-
- case DW_AT_frame_base:
- case DW_AT_location:
- case DW_AT_data_member_location: {
- const uint8_t *blockData = form_value.BlockData();
- if (blockData) {
- // Location description is inlined in data in the form value
- DWARFDataExtractor locationData(data,
- (*offset_ptr) - form_value.Unsigned(),
- form_value.Unsigned());
- DWARFExpression::PrintDWARFExpression(
- s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
- } else {
- // We have a location list offset as the value that is the offset into
- // the .debug_loc section that describes the value over it's lifetime
- uint64_t debug_loc_offset = form_value.Unsigned();
- DWARFExpression::PrintDWARFLocationList(s, cu, cu->GetLocationData(),
- debug_loc_offset);
- }
- } break;
-
- case DW_AT_abstract_origin:
- case DW_AT_specification: {
- DWARFDIE abstract_die = form_value.Reference();
- form_value.Dump(s);
- // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( ";
- abstract_die.GetName(s);
- } break;
-
- case DW_AT_type: {
- DWARFDIE type_die = form_value.Reference();
- s.PutCString(" ( ");
- type_die.AppendTypeName(s);
- s.PutCString(" )");
- } break;
-
- default:
- break;
- }
-
- s.PutCString(" )\n");
-}
-
// Get all attribute values for a given DIE, including following any
// specification or abstract origin attributes and including those in the
// results. Any duplicate attributes will have the first instance take
// precedence (this can happen for declaration attributes).
-size_t DWARFDebugInfoEntry::GetAttributes(
- const DWARFUnit *cu, DWARFAttributes &attributes,
- uint32_t curr_depth) const {
+size_t DWARFDebugInfoEntry::GetAttributes(const DWARFUnit *cu,
+ DWARFAttributes &attributes,
+ Recurse recurse,
+ uint32_t curr_depth) const {
const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
if (abbrevDecl) {
const DWARFDataExtractor &data = cu->GetData();
@@ -571,11 +433,13 @@ size_t DWARFDebugInfoEntry::GetAttributes(
break;
}
- if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
+ if (recurse == Recurse::yes &&
+ ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
if (form_value.ExtractValue(data, &offset)) {
DWARFDIE spec_die = form_value.Reference();
if (spec_die)
- spec_die.GetAttributes(attributes, curr_depth + 1);
+ spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes,
+ recurse, curr_depth + 1);
}
} else {
llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
@@ -819,34 +683,9 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
return name;
}
-// BuildAddressRangeTable
-void DWARFDebugInfoEntry::BuildAddressRangeTable(
- const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
- if (m_tag) {
- if (m_tag == DW_TAG_subprogram) {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
- /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
- /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
- debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
- }
- }
-
- const DWARFDebugInfoEntry *child = GetFirstChild();
- while (child) {
- child->BuildAddressRangeTable(cu, debug_aranges);
- child = child->GetSibling();
- }
- }
-}
-
-// BuildFunctionAddressRangeTable
-//
-// This function is very similar to the BuildAddressRangeTable function except
-// that the actual DIE offset for the function is placed in the table instead
-// of the compile unit offset (which is the way the standard .debug_aranges
-// section does it).
+/// This function is builds a table very similar to the standard .debug_aranges
+/// table, except that the actual DIE offset for the function is placed in the
+/// table instead of the compile unit offset.
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
@@ -854,8 +693,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
- // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
- // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
}
}
@@ -868,25 +705,34 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
}
}
-void DWARFDebugInfoEntry::GetDWARFDeclContext(
- DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const {
- const dw_tag_t tag = Tag();
- if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) {
- dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu));
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu);
- if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
- if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit &&
- parent_decl_ctx_die.Tag() != DW_TAG_partial_unit)
- parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
- parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
- }
+DWARFDeclContext
+DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die,
+ DWARFUnit *cu) {
+ DWARFDeclContext dwarf_decl_ctx;
+ for (;;) {
+ const dw_tag_t tag = die->Tag();
+ if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
+ return dwarf_decl_ctx;
+ dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu));
+ DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu);
+ if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die)
+ return dwarf_decl_ctx;
+ if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit ||
+ parent_decl_ctx_die.Tag() == DW_TAG_partial_unit)
+ return dwarf_decl_ctx;
+ die = parent_decl_ctx_die.GetDIE();
+ cu = parent_decl_ctx_die.GetCU();
}
}
+DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const {
+ return GetDWARFDeclContextStatic(this, cu);
+}
+
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
DWARFAttributes attributes;
- GetAttributes(cu, attributes);
+ GetAttributes(cu, attributes, Recurse::yes);
return GetParentDeclContextDIE(cu, attributes);
}
@@ -936,7 +782,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE(
const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
std::string &storage) const {
DWARFAttributes attributes;
- GetAttributes(cu, attributes);
+ GetAttributes(cu, attributes, Recurse::yes);
return GetQualifiedName(cu, attributes, storage);
}
@@ -993,209 +839,6 @@ DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
return storage.c_str();
}
-bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu,
- DWARFDebugInfoEntry **function_die,
- DWARFDebugInfoEntry **block_die) {
- bool found_address = false;
- if (m_tag) {
- bool check_children = false;
- bool match_addr_range = false;
- // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
- // DW_TAG_value_to_name(tag), address);
- switch (m_tag) {
- case DW_TAG_array_type:
- break;
- case DW_TAG_class_type:
- check_children = true;
- break;
- case DW_TAG_entry_point:
- case DW_TAG_enumeration_type:
- case DW_TAG_formal_parameter:
- case DW_TAG_imported_declaration:
- case DW_TAG_label:
- break;
- case DW_TAG_lexical_block:
- check_children = true;
- match_addr_range = true;
- break;
- case DW_TAG_member:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- break;
- case DW_TAG_compile_unit:
- match_addr_range = true;
- break;
- case DW_TAG_string_type:
- break;
- case DW_TAG_structure_type:
- check_children = true;
- break;
- case DW_TAG_subroutine_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- case DW_TAG_unspecified_parameters:
- case DW_TAG_variant:
- break;
- case DW_TAG_common_block:
- check_children = true;
- break;
- case DW_TAG_common_inclusion:
- case DW_TAG_inheritance:
- break;
- case DW_TAG_inlined_subroutine:
- check_children = true;
- match_addr_range = true;
- break;
- case DW_TAG_module:
- match_addr_range = true;
- break;
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_set_type:
- case DW_TAG_subrange_type:
- case DW_TAG_with_stmt:
- case DW_TAG_access_declaration:
- case DW_TAG_base_type:
- break;
- case DW_TAG_catch_block:
- match_addr_range = true;
- break;
- case DW_TAG_const_type:
- case DW_TAG_constant:
- case DW_TAG_enumerator:
- case DW_TAG_file_type:
- case DW_TAG_friend:
- case DW_TAG_namelist:
- case DW_TAG_namelist_item:
- case DW_TAG_packed_type:
- break;
- case DW_TAG_subprogram:
- match_addr_range = true;
- break;
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- case DW_TAG_GNU_template_parameter_pack:
- case DW_TAG_thrown_type:
- break;
- case DW_TAG_try_block:
- match_addr_range = true;
- break;
- case DW_TAG_variant_part:
- case DW_TAG_variable:
- case DW_TAG_volatile_type:
- case DW_TAG_dwarf_procedure:
- case DW_TAG_restrict_type:
- case DW_TAG_interface_type:
- break;
- case DW_TAG_namespace:
- check_children = true;
- break;
- case DW_TAG_imported_module:
- case DW_TAG_unspecified_type:
- break;
- case DW_TAG_partial_unit:
- match_addr_range = true;
- break;
- case DW_TAG_imported_unit:
- case DW_TAG_shared_type:
- default:
- break;
- }
-
- if (match_addr_range) {
- dw_addr_t lo_pc =
- GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (lo_pc != LLDB_INVALID_ADDRESS) {
- dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS);
- if (hi_pc != LLDB_INVALID_ADDRESS) {
- // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
- // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
- if ((lo_pc <= address) && (address < hi_pc)) {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag) {
- case DW_TAG_compile_unit: // File
- case DW_TAG_partial_unit: // File
- check_children =
- ((function_die != nullptr) || (block_die != nullptr));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != nullptr);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die) {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- }
- } else {
- // Compile units may not have a valid high/low pc when there
- // are address gaps in subroutines so we must always search
- // if there is no valid high and low PC.
- check_children =
- (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) &&
- ((function_die != nullptr) || (block_die != nullptr));
- }
- } else {
- DWARFRangeList ranges;
- if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
- ranges.FindEntryThatContains(address)) {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag) {
- case DW_TAG_compile_unit: // File
- case DW_TAG_partial_unit: // File
- check_children =
- ((function_die != nullptr) || (block_die != nullptr));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != nullptr);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die) {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- } else {
- check_children = false;
- }
- }
- }
-
- if (check_children) {
- // printf("checking children\n");
- DWARFDebugInfoEntry *child = GetFirstChild();
- while (child) {
- if (child->LookupAddress(address, cu, function_die, block_die))
- return true;
- child = child->GetSibling();
- }
- }
- }
- return found_address;
-}
-
lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const {
return GetOffset() + llvm::getULEB128Size(m_abbr_idx);
}
@@ -1210,6 +853,29 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const {
return nullptr;
}
+bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const {
+ if (Tag() != DW_TAG_variable)
+ return false;
+ const DWARFDebugInfoEntry *parent_die = GetParent();
+ while (parent_die != nullptr) {
+ switch (parent_die->Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ return false;
+
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ return true;
+
+ default:
+ break;
+ }
+ parent_die = parent_die->GetParent();
+ }
+ return false;
+}
+
bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
m_sibling_idx == rhs.m_sibling_idx &&
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index f35af6e7d498..3019e1767f18 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -6,13 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_
-#define SymbolFileDWARF_DWARFDebugInfoEntry_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
#include "SymbolFileDWARF.h"
#include "llvm/ADT/SmallVector.h"
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFBaseDIE.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugRanges.h"
#include <map>
@@ -41,23 +42,17 @@ public:
bool operator==(const DWARFDebugInfoEntry &rhs) const;
bool operator!=(const DWARFDebugInfoEntry &rhs) const;
- void BuildAddressRangeTable(const DWARFUnit *cu,
- DWARFDebugAranges *debug_aranges) const;
-
void BuildFunctionAddressRangeTable(const DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
bool Extract(const lldb_private::DWARFDataExtractor &data,
const DWARFUnit *cu, lldb::offset_t *offset_ptr);
- bool LookupAddress(const dw_addr_t address, DWARFUnit *cu,
- DWARFDebugInfoEntry **function_die,
- DWARFDebugInfoEntry **block_die);
-
- size_t GetAttributes(const DWARFUnit *cu,
- DWARFAttributes &attrs,
- uint32_t curr_depth = 0)
- const; // "curr_depth" for internal use only, don't set this yourself!!!
+ using Recurse = DWARFBaseDIE::Recurse;
+ size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs,
+ Recurse recurse = Recurse::yes) const {
+ return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */);
+ }
dw_offset_t
GetAttributeValue(const DWARFUnit *cu, const dw_attr_t attr,
@@ -106,15 +101,6 @@ public:
const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes,
std::string &storage) const;
- void Dump(const DWARFUnit *cu, lldb_private::Stream &s,
- uint32_t recurse_depth) const;
-
- static void
- DumpAttribute(const DWARFUnit *cu,
- const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr, lldb_private::Stream &s,
- dw_attr_t attr, DWARFFormValue &form_value);
-
bool GetDIENamesAndRanges(
DWARFUnit *cu, const char *&name, const char *&mangled,
DWARFRangeList &rangeList, int &decl_file, int &decl_line,
@@ -162,8 +148,7 @@ public:
return HasChildren() ? this + 1 : nullptr;
}
- void GetDWARFDeclContext(DWARFUnit *cu,
- DWARFDeclContext &dwarf_decl_ctx) const;
+ DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const;
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
@@ -172,7 +157,15 @@ public:
void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
+ // This function returns true if the variable scope is either
+ // global or (file-static). It will return false for static variables
+ // that are local to a function, as they have local scope.
+ bool IsGlobalOrStaticScopeVariable() const;
+
protected:
+ static DWARFDeclContext
+ GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
+
dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
// If zero this die has no parent
@@ -185,6 +178,10 @@ protected:
/// A copy of the DW_TAG value so we don't have to go through the compile
/// unit abbrev table
dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
+
+private:
+ size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs,
+ Recurse recurse, uint32_t curr_depth) const;
};
-#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
index 4238be7ec1c3..278950a9f336 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugMacro.cpp -------------------------------------*- C++ -*-===//
+//===-- DWARFDebugMacro.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
index c3a93a9f4d14..5c0338e950eb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugMacro_h_
-#define SymbolFileDWARF_DWARFDebugMacro_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H
#include <map>
@@ -58,4 +58,4 @@ public:
lldb_private::DebugMacrosSP &debug_macros_sp);
};
-#endif // SymbolFileDWARF_DWARFDebugMacro_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGMACRO_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 6c074002cb20..6a0f11d2a1c4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
+//===-- DWARFDebugRanges.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index 1888a7760f27..b587845a67d9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugRanges_h_
-#define SymbolFileDWARF_DWARFDebugRanges_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H
#include "lldb/Core/dwarf.h"
#include <map>
@@ -39,4 +39,4 @@ protected:
range_map m_range_map;
};
-#endif // SymbolFileDWARF_DWARFDebugRanges_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index a664314035e4..f4c8c14cc8af 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===//
+//===-- DWARFDeclContext.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 348b33464a54..9072b2dc0115 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDeclContext_h_
-#define SymbolFileDWARF_DWARFDeclContext_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
#include <string>
#include <vector>
@@ -48,6 +48,7 @@ public:
}
bool operator==(const DWARFDeclContext &rhs) const;
+ bool operator!=(const DWARFDeclContext &rhs) const { return !(*this == rhs); }
uint32_t GetSize() const { return m_entries.size(); }
@@ -85,4 +86,4 @@ protected:
lldb::LanguageType m_language;
};
-#endif // SymbolFileDWARF_DWARFDeclContext_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 2ae1bbc9f507..4e99a295ce50 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFDefines.cpp ----------------------------------------*- C++ -*-===//
+//===-- DWARFDefines.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -58,321 +58,6 @@ const char *DW_OP_value_to_name(uint32_t val) {
return llvmstr.data();
}
-DRC_class DW_OP_value_to_class(uint32_t val) {
- // FIXME: If we just used llvm's DWARFExpression printer, we could delete
- // all this code (and more in lldb's DWARFExpression.cpp).
- switch (val) {
- case 0x03:
- return DRC_ONEOPERAND;
- case 0x06:
- return DRC_ZEROOPERANDS;
- case 0x08:
- return DRC_ONEOPERAND;
- case 0x09:
- return DRC_ONEOPERAND;
- case 0x0a:
- return DRC_ONEOPERAND;
- case 0x0b:
- return DRC_ONEOPERAND;
- case 0x0c:
- return DRC_ONEOPERAND;
- case 0x0d:
- return DRC_ONEOPERAND;
- case 0x0e:
- return DRC_ONEOPERAND;
- case 0x0f:
- return DRC_ONEOPERAND;
- case 0x10:
- return DRC_ONEOPERAND;
- case 0x11:
- return DRC_ONEOPERAND;
- case 0x12:
- return DRC_ZEROOPERANDS;
- case 0x13:
- return DRC_ZEROOPERANDS;
- case 0x14:
- return DRC_ZEROOPERANDS;
- case 0x15:
- return DRC_ONEOPERAND;
- case 0x16:
- return DRC_ZEROOPERANDS;
- case 0x17:
- return DRC_ZEROOPERANDS;
- case 0x18:
- return DRC_ZEROOPERANDS;
- case 0x19:
- return DRC_ZEROOPERANDS;
- case 0x1a:
- return DRC_ZEROOPERANDS;
- case 0x1b:
- return DRC_ZEROOPERANDS;
- case 0x1c:
- return DRC_ZEROOPERANDS;
- case 0x1d:
- return DRC_ZEROOPERANDS;
- case 0x1e:
- return DRC_ZEROOPERANDS;
- case 0x1f:
- return DRC_ZEROOPERANDS;
- case 0x20:
- return DRC_ZEROOPERANDS;
- case 0x21:
- return DRC_ZEROOPERANDS;
- case 0x22:
- return DRC_ZEROOPERANDS;
- case 0x23:
- return DRC_ONEOPERAND;
- case 0x24:
- return DRC_ZEROOPERANDS;
- case 0x25:
- return DRC_ZEROOPERANDS;
- case 0x26:
- return DRC_ZEROOPERANDS;
- case 0x27:
- return DRC_ZEROOPERANDS;
- case 0x2f:
- return DRC_ONEOPERAND;
- case 0x28:
- return DRC_ONEOPERAND;
- case 0x29:
- return DRC_ZEROOPERANDS;
- case 0x2a:
- return DRC_ZEROOPERANDS;
- case 0x2b:
- return DRC_ZEROOPERANDS;
- case 0x2c:
- return DRC_ZEROOPERANDS;
- case 0x2d:
- return DRC_ZEROOPERANDS;
- case 0x2e:
- return DRC_ZEROOPERANDS;
- case 0x30:
- return DRC_ZEROOPERANDS;
- case 0x31:
- return DRC_ZEROOPERANDS;
- case 0x32:
- return DRC_ZEROOPERANDS;
- case 0x33:
- return DRC_ZEROOPERANDS;
- case 0x34:
- return DRC_ZEROOPERANDS;
- case 0x35:
- return DRC_ZEROOPERANDS;
- case 0x36:
- return DRC_ZEROOPERANDS;
- case 0x37:
- return DRC_ZEROOPERANDS;
- case 0x38:
- return DRC_ZEROOPERANDS;
- case 0x39:
- return DRC_ZEROOPERANDS;
- case 0x3a:
- return DRC_ZEROOPERANDS;
- case 0x3b:
- return DRC_ZEROOPERANDS;
- case 0x3c:
- return DRC_ZEROOPERANDS;
- case 0x3d:
- return DRC_ZEROOPERANDS;
- case 0x3e:
- return DRC_ZEROOPERANDS;
- case 0x3f:
- return DRC_ZEROOPERANDS;
- case 0x40:
- return DRC_ZEROOPERANDS;
- case 0x41:
- return DRC_ZEROOPERANDS;
- case 0x42:
- return DRC_ZEROOPERANDS;
- case 0x43:
- return DRC_ZEROOPERANDS;
- case 0x44:
- return DRC_ZEROOPERANDS;
- case 0x45:
- return DRC_ZEROOPERANDS;
- case 0x46:
- return DRC_ZEROOPERANDS;
- case 0x47:
- return DRC_ZEROOPERANDS;
- case 0x48:
- return DRC_ZEROOPERANDS;
- case 0x49:
- return DRC_ZEROOPERANDS;
- case 0x4a:
- return DRC_ZEROOPERANDS;
- case 0x4b:
- return DRC_ZEROOPERANDS;
- case 0x4c:
- return DRC_ZEROOPERANDS;
- case 0x4d:
- return DRC_ZEROOPERANDS;
- case 0x4e:
- return DRC_ZEROOPERANDS;
- case 0x4f:
- return DRC_ZEROOPERANDS;
- case 0x50:
- return DRC_ZEROOPERANDS;
- case 0x51:
- return DRC_ZEROOPERANDS;
- case 0x52:
- return DRC_ZEROOPERANDS;
- case 0x53:
- return DRC_ZEROOPERANDS;
- case 0x54:
- return DRC_ZEROOPERANDS;
- case 0x55:
- return DRC_ZEROOPERANDS;
- case 0x56:
- return DRC_ZEROOPERANDS;
- case 0x57:
- return DRC_ZEROOPERANDS;
- case 0x58:
- return DRC_ZEROOPERANDS;
- case 0x59:
- return DRC_ZEROOPERANDS;
- case 0x5a:
- return DRC_ZEROOPERANDS;
- case 0x5b:
- return DRC_ZEROOPERANDS;
- case 0x5c:
- return DRC_ZEROOPERANDS;
- case 0x5d:
- return DRC_ZEROOPERANDS;
- case 0x5e:
- return DRC_ZEROOPERANDS;
- case 0x5f:
- return DRC_ZEROOPERANDS;
- case 0x60:
- return DRC_ZEROOPERANDS;
- case 0x61:
- return DRC_ZEROOPERANDS;
- case 0x62:
- return DRC_ZEROOPERANDS;
- case 0x63:
- return DRC_ZEROOPERANDS;
- case 0x64:
- return DRC_ZEROOPERANDS;
- case 0x65:
- return DRC_ZEROOPERANDS;
- case 0x66:
- return DRC_ZEROOPERANDS;
- case 0x67:
- return DRC_ZEROOPERANDS;
- case 0x68:
- return DRC_ZEROOPERANDS;
- case 0x69:
- return DRC_ZEROOPERANDS;
- case 0x6a:
- return DRC_ZEROOPERANDS;
- case 0x6b:
- return DRC_ZEROOPERANDS;
- case 0x6c:
- return DRC_ZEROOPERANDS;
- case 0x6d:
- return DRC_ZEROOPERANDS;
- case 0x6e:
- return DRC_ZEROOPERANDS;
- case 0x6f:
- return DRC_ZEROOPERANDS;
- case 0x70:
- return DRC_ONEOPERAND;
- case 0x71:
- return DRC_ONEOPERAND;
- case 0x72:
- return DRC_ONEOPERAND;
- case 0x73:
- return DRC_ONEOPERAND;
- case 0x74:
- return DRC_ONEOPERAND;
- case 0x75:
- return DRC_ONEOPERAND;
- case 0x76:
- return DRC_ONEOPERAND;
- case 0x77:
- return DRC_ONEOPERAND;
- case 0x78:
- return DRC_ONEOPERAND;
- case 0x79:
- return DRC_ONEOPERAND;
- case 0x7a:
- return DRC_ONEOPERAND;
- case 0x7b:
- return DRC_ONEOPERAND;
- case 0x7c:
- return DRC_ONEOPERAND;
- case 0x7d:
- return DRC_ONEOPERAND;
- case 0x7e:
- return DRC_ONEOPERAND;
- case 0x7f:
- return DRC_ONEOPERAND;
- case 0x80:
- return DRC_ONEOPERAND;
- case 0x81:
- return DRC_ONEOPERAND;
- case 0x82:
- return DRC_ONEOPERAND;
- case 0x83:
- return DRC_ONEOPERAND;
- case 0x84:
- return DRC_ONEOPERAND;
- case 0x85:
- return DRC_ONEOPERAND;
- case 0x86:
- return DRC_ONEOPERAND;
- case 0x87:
- return DRC_ONEOPERAND;
- case 0x88:
- return DRC_ONEOPERAND;
- case 0x89:
- return DRC_ONEOPERAND;
- case 0x8a:
- return DRC_ONEOPERAND;
- case 0x8b:
- return DRC_ONEOPERAND;
- case 0x8c:
- return DRC_ONEOPERAND;
- case 0x8d:
- return DRC_ONEOPERAND;
- case 0x8e:
- return DRC_ONEOPERAND;
- case 0x8f:
- return DRC_ONEOPERAND;
- case 0x90:
- return DRC_ONEOPERAND;
- case 0x91:
- return DRC_ONEOPERAND;
- case 0x92:
- return DRC_TWOOPERANDS;
- case 0x93:
- return DRC_ONEOPERAND;
- case 0x94:
- return DRC_ONEOPERAND;
- case 0x95:
- return DRC_ONEOPERAND;
- case 0x96:
- return DRC_ZEROOPERANDS;
- case 0x97:
- return DRC_DWARFv3 | DRC_ZEROOPERANDS;
- case 0x98:
- return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x99:
- return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x9a:
- return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0xa3: /* DW_OP_entry_value */
- return DRC_TWOOPERANDS;
- case 0xf0:
- return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
- case 0xe0:
- return 0;
- case 0xff:
- return 0;
- default:
- return 0;
- }
-}
-
const char *DW_ATE_value_to_name(uint32_t val) {
static char invalid[100];
llvm::StringRef llvmstr = llvm::dwarf::AttributeEncodingString(val);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index d16cb07baf88..1b7102cd7e31 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDefines_h_
-#define SymbolFileDWARF_DWARFDefines_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
#include "lldb/Core/dwarf.h"
#include <stdint.h>
@@ -26,52 +26,12 @@ const char *DW_FORM_value_to_name(uint32_t val);
const char *DW_OP_value_to_name(uint32_t val);
-DRC_class DW_OP_value_to_class(uint32_t val);
-
const char *DW_ATE_value_to_name(uint32_t val);
const char *DW_LANG_value_to_name(uint32_t val);
const char *DW_LNS_value_to_name(uint32_t val);
-/* These DRC are entirely our own construction,
- although they are derived from various comments in the DWARF standard.
- Most of these are not useful to the parser, but the DW_AT and DW_FORM
- classes should prove to be usable in some fashion. */
-
-#define DRC_0x65 0x1
-#define DRC_ADDRESS 0x2
-#define DRC_BLOCK 0x4
-#define DRC_CONSTANT 0x8
-#define DRC_DWARFv3 0x10
-#define DRC_FLAG 0x20
-#define DRC_INDIRECT_SPECIAL 0x40
-#define DRC_LINEPTR 0x80
-#define DRC_LOCEXPR 0x100
-#define DRC_LOCLISTPTR 0x200
-#define DRC_MACPTR 0x400
-#define DRC_ONEOPERAND 0x800
-#define DRC_OPERANDONE_1BYTE_DELTA 0x1000
-#define DRC_OPERANDONE_2BYTE_DELTA 0x2000
-#define DRC_OPERANDONE_4BYTE_DELTA 0x4000
-#define DRC_OPERANDONE_ADDRESS 0x8000
-#define DRC_OPERANDONE_BLOCK 0x10000
-#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000
-#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000
-#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000
-#define DRC_OPERANDTWO_BLOCK 0x100000
-#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000
-#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000
-#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000
-#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000
-#define DRC_RANGELISTPTR 0x2000000
-#define DRC_REFERENCE 0x4000000
-#define DRC_STRING 0x8000000
-#define DRC_TWOOPERANDS 0x10000000
-#define DRC_VENDOR_GNU 0x20000000
-#define DRC_VENDOR_MIPS 0x40000000
-#define DRC_ZEROOPERANDS 0x80000000
-
} // namespace lldb_private
-#endif // SymbolFileDWARF_DWARFDefines_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index f660cc32b3f8..305f1cbd2826 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
+//===-- DWARFFormValue.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -454,40 +454,26 @@ void DWARFFormValue::Dump(Stream &s) const {
}
const char *DWARFFormValue::AsCString() const {
- SymbolFileDWARF &symbol_file = m_unit->GetSymbolFileDWARF();
+ DWARFContext &context = m_unit->GetSymbolFileDWARF().GetDWARFContext();
- if (m_form == DW_FORM_string) {
+ if (m_form == DW_FORM_string)
return m_value.value.cstr;
- } else if (m_form == DW_FORM_strp) {
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
- m_value.value.uval);
- } else if (m_form == DW_FORM_GNU_str_index) {
- uint32_t index_size = 4;
- lldb::offset_t offset = m_value.value.uval * index_size;
- dw_offset_t str_offset =
- symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
- &offset, index_size);
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(
- str_offset);
- }
-
- if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
- m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 ||
- m_form == DW_FORM_strx4) {
-
- // The same code as above.
- uint32_t indexSize = 4;
- lldb::offset_t offset =
- m_unit->GetStrOffsetsBase() + m_value.value.uval * indexSize;
- dw_offset_t strOffset =
- symbol_file.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
- &offset, indexSize);
- return symbol_file.GetDWARFContext().getOrLoadStrData().PeekCStr(strOffset);
+ if (m_form == DW_FORM_strp)
+ return context.getOrLoadStrData().PeekCStr(m_value.value.uval);
+
+ if (m_form == DW_FORM_GNU_str_index || m_form == DW_FORM_strx ||
+ m_form == DW_FORM_strx1 || m_form == DW_FORM_strx2 ||
+ m_form == DW_FORM_strx3 || m_form == DW_FORM_strx4) {
+
+ llvm::Optional<uint64_t> offset =
+ m_unit->GetStringOffsetSectionItem(m_value.value.uval);
+ if (!offset)
+ return nullptr;
+ return context.getOrLoadStrData().PeekCStr(*offset);
}
if (m_form == DW_FORM_line_strp)
- return symbol_file.GetDWARFContext().getOrLoadLineStrData().PeekCStr(
- m_value.value.uval);
+ return context.getOrLoadLineStrData().PeekCStr(m_value.value.uval);
return nullptr;
}
@@ -531,7 +517,7 @@ DWARFDIE DWARFFormValue::Reference() const {
case DW_FORM_ref_addr: {
DWARFUnit *ref_cu =
- m_unit->GetSymbolFileDWARF().DebugInfo()->GetUnitContainingDIEOffset(
+ m_unit->GetSymbolFileDWARF().DebugInfo().GetUnitContainingDIEOffset(
DIERef::Section::DebugInfo, value);
if (!ref_cu) {
m_unit->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
@@ -544,7 +530,7 @@ DWARFDIE DWARFFormValue::Reference() const {
case DW_FORM_ref_sig8: {
DWARFTypeUnit *tu =
- m_unit->GetSymbolFileDWARF().DebugInfo()->GetTypeUnitForHash(value);
+ m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(value);
if (!tu)
return {};
return tu->GetDIE(tu->GetTypeOffset());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 848db2990ded..b401352c693d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFFormValue_h_
-#define SymbolFileDWARF_DWARFFormValue_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
#include "DWARFDataExtractor.h"
#include <stddef.h>
@@ -86,4 +86,4 @@ protected:
ValueType m_value; // Contains all data for the form
};
-#endif // SymbolFileDWARF_DWARFFormValue_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index c122f756e81a..683033d0ee4c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFIndex.cpp -----------------------------------------*- C++ -*-===//
+//===-- DWARFIndex.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,20 +11,21 @@
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
+#include "lldb/Core/Module.h"
+
using namespace lldb_private;
using namespace lldb;
DWARFIndex::~DWARFIndex() = default;
-void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
- SymbolFileDWARF &dwarf,
- const CompilerDeclContext &parent_decl_ctx,
- uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) {
+bool DWARFIndex::ProcessFunctionDIE(
+ llvm::StringRef name, DIERef ref, SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
DWARFDIE die = dwarf.GetDIE(ref);
if (!die) {
ReportInvalidDIERef(ref, name);
- return;
+ return true;
}
// Exit early if we're searching exclusively for methods or selectors and
@@ -32,26 +33,22 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
uint32_t looking_for_nonmethods =
name_type_mask & ~(eFunctionNameTypeMethod | eFunctionNameTypeSelector);
if (!looking_for_nonmethods && parent_decl_ctx.IsValid())
- return;
+ return true;
// Otherwise, we need to also check that the context matches. If it does not
// match, we do nothing.
- if (!SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
- return;
+ if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die))
+ return true;
// In case of a full match, we just insert everything we find.
- if (name_type_mask & eFunctionNameTypeFull) {
- dies.push_back(die);
- return;
- }
+ if (name_type_mask & eFunctionNameTypeFull)
+ return callback(die);
// If looking for ObjC selectors, we need to also check if the name is a
// possible selector.
if (name_type_mask & eFunctionNameTypeSelector &&
- ObjCLanguage::IsPossibleObjCMethodName(die.GetName())) {
- dies.push_back(die);
- return;
- }
+ ObjCLanguage::IsPossibleObjCMethodName(die.GetName()))
+ return callback(die);
bool looking_for_methods = name_type_mask & lldb::eFunctionNameTypeMethod;
bool looking_for_functions = name_type_mask & lldb::eFunctionNameTypeBase;
@@ -61,6 +58,29 @@ void DWARFIndex::ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
// searching for.
if ((looking_for_methods && looking_for_functions) ||
looking_for_methods == die.IsMethod())
- dies.push_back(die);
+ return callback(die);
}
+
+ return true;
+}
+
+DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl(
+ const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback,
+ llvm::StringRef name)
+ : m_index(index),
+ m_dwarf(*llvm::cast<SymbolFileDWARF>(index.m_module.GetSymbolFile())),
+ m_callback(callback), m_name(name) {}
+
+bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const {
+ if (DWARFDIE die = m_dwarf.GetDIE(ref))
+ return m_callback(die);
+ m_index.ReportInvalidDIERef(ref, m_name);
+ return true;
+}
+
+void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const {
+ m_module.ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (accelerator table had "
+ "bad die 0x%8.8x for '%s')\n",
+ ref.die_offset(), name.str().c_str());
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
index e3c7c5e63ac8..ecf82a910b66 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_DWARFINDEX_H
-#define LLDB_DWARFINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DIERef.h"
#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
@@ -27,26 +27,38 @@ public:
/// Finds global variables with the given base name. Any additional filtering
/// (e.g., to only retrieve variables from a given context) should be done by
/// the consumer.
- virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
+ virtual void
+ GetGlobalVariables(ConstString basename,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
- virtual void GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) = 0;
- virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;
- virtual void GetObjCMethods(ConstString class_name, DIEArray &offsets) = 0;
- virtual void GetCompleteObjCClass(ConstString class_name,
- bool must_be_implementation,
- DIEArray &offsets) = 0;
- virtual void GetTypes(ConstString name, DIEArray &offsets) = 0;
- virtual void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) = 0;
- virtual void GetNamespaces(ConstString name, DIEArray &offsets) = 0;
- virtual void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
- const CompilerDeclContext &parent_decl_ctx,
- uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) = 0;
- virtual void GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) = 0;
+ virtual void
+ GetGlobalVariables(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetGlobalVariables(const DWARFUnit &cu,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetObjCMethods(ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void GetTypes(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void GetTypes(const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetNamespaces(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx,
+ uint32_t name_type_mask,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
+ virtual void
+ GetFunctions(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) = 0;
- virtual void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) = 0;
virtual void Dump(Stream &s) = 0;
protected:
@@ -56,11 +68,33 @@ protected:
/// the function given by "ref" matches search criteria given by
/// "parent_decl_ctx" and "name_type_mask", it is inserted into the "dies"
/// vector.
- void ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
+ bool ProcessFunctionDIE(llvm::StringRef name, DIERef ref,
SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
- uint32_t name_type_mask, std::vector<DWARFDIE> &dies);
+ uint32_t name_type_mask,
+ llvm::function_ref<bool(DWARFDIE die)> callback);
+
+ class DIERefCallbackImpl {
+ public:
+ DIERefCallbackImpl(const DWARFIndex &index,
+ llvm::function_ref<bool(DWARFDIE die)> callback,
+ llvm::StringRef name);
+ bool operator()(DIERef ref) const;
+
+ private:
+ const DWARFIndex &m_index;
+ SymbolFileDWARF &m_dwarf;
+ const llvm::function_ref<bool(DWARFDIE die)> m_callback;
+ const llvm::StringRef m_name;
+ };
+ DIERefCallbackImpl
+ DIERefCallback(llvm::function_ref<bool(DWARFDIE die)> callback,
+ llvm::StringRef name = {}) const {
+ return DIERefCallbackImpl(*this, callback, name);
+ }
+
+ void ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const;
};
} // namespace lldb_private
-#endif // LLDB_DWARFINDEX_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFINDEX_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
index fcc031bf1ea0..48d578977c57 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFTypeUnit.cpp ---------------------------------------*- C++ -*-===//
+//===-- DWARFTypeUnit.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
index 8967509c081a..5e4d48ab285a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFTypeUnit_h_
-#define SymbolFileDWARF_DWARFTypeUnit_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H
#include "DWARFUnit.h"
#include "llvm/Support/Error.h"
@@ -34,4 +34,4 @@ private:
friend class DWARFUnit;
};
-#endif // SymbolFileDWARF_DWARFTypeUnit_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFTYPEUNIT_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 22e3e40dac93..dfa40759a7ff 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFUnit.cpp -------------------------------------------*- C++ -*-===//
+//===-- DWARFUnit.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -188,7 +188,7 @@ void DWARFUnit::ExtractDIEsRWLocked() {
// simultaneously. We also don't need to do that as the dwo file will
// contain a superset of information. So, we don't even attempt to parse
// any remaining DIEs.
- if (m_dwo_symbol_file) {
+ if (m_dwo) {
m_die_array.front().SetHasChildren(false);
break;
}
@@ -249,10 +249,8 @@ void DWARFUnit::ExtractDIEsRWLocked() {
m_die_array.shrink_to_fit();
- if (m_dwo_symbol_file) {
- DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- dwo_cu->ExtractDIEsIfNeeded();
- }
+ if (m_dwo)
+ m_dwo->ExtractDIEsIfNeeded();
}
// This is used when a split dwarf is enabled.
@@ -261,23 +259,33 @@ void DWARFUnit::ExtractDIEsRWLocked() {
// .debug_str_offsets. At the same time, the corresponding split debug unit also
// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and
// for that case, we should find the offset (skip the section header).
-static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
+void DWARFUnit::SetDwoStrOffsetsBase() {
lldb::offset_t baseOffset = 0;
- const DWARFDataExtractor &strOffsets =
- dwo_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
- uint64_t length = strOffsets.GetU32(&baseOffset);
- if (length == 0xffffffff)
- length = strOffsets.GetU64(&baseOffset);
+ if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
+ if (const auto *contribution =
+ entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
+ baseOffset = contribution->Offset;
+ else
+ return;
+ }
- // Check version.
- if (strOffsets.GetU16(&baseOffset) < 5)
- return;
+ if (GetVersion() >= 5) {
+ const DWARFDataExtractor &strOffsets =
+ GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
+ uint64_t length = strOffsets.GetU32(&baseOffset);
+ if (length == 0xffffffff)
+ length = strOffsets.GetU64(&baseOffset);
- // Skip padding.
- baseOffset += 2;
+ // Check version.
+ if (strOffsets.GetU16(&baseOffset) < 5)
+ return;
+
+ // Skip padding.
+ baseOffset += 2;
+ }
- dwo_cu->SetStrOffsetsBase(baseOffset);
+ SetStrOffsetsBase(baseOffset);
}
// m_die_array_mutex must be already held as read/write.
@@ -336,32 +344,27 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
}
}
- if (m_is_dwo)
+ if (m_is_dwo) {
+ SetDwoStrOffsetsBase();
return;
+ }
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
+ std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die);
if (!dwo_symbol_file)
return;
- DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ uint64_t main_dwo_id =
+ cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0);
+ DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(main_dwo_id);
if (!dwo_cu)
return; // Can't fetch the compile unit from the dwo file.
+ dwo_cu->SetUserData(this);
DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
if (!dwo_cu_die.IsValid())
return; // Can't fetch the compile unit DIE from the dwo file.
- uint64_t main_dwo_id =
- cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0);
- uint64_t sub_dwo_id =
- dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
- if (main_dwo_id != sub_dwo_id)
- return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to
- // a differectn compilation.
-
- m_dwo_symbol_file = std::move(dwo_symbol_file);
-
// Here for DWO CU we want to use the address base set in the skeleton unit
// (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base
// otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_*
@@ -375,21 +378,18 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
if (GetVersion() <= 4 && gnu_ranges_base)
dwo_cu->SetRangesBase(*gnu_ranges_base);
- else if (m_dwo_symbol_file->GetDWARFContext()
+ else if (dwo_symbol_file->GetDWARFContext()
.getOrLoadRngListsData()
.GetByteSize() > 0)
dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32));
- if (GetVersion() >= 5 && m_dwo_symbol_file->GetDWARFContext()
- .getOrLoadLocListsData()
- .GetByteSize() > 0)
+ if (GetVersion() >= 5 &&
+ dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() >
+ 0)
dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32));
dwo_cu->SetBaseAddress(GetBaseAddress());
- for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) {
- DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i);
- SetDwoStrOffsetsBase(unit);
- }
+ m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu);
}
DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
@@ -467,18 +467,25 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
std::unique_ptr<llvm::DWARFLocationTable>
DWARFUnit::GetLocationTable(const DataExtractor &data) const {
llvm::DWARFDataExtractor llvm_data(
- toStringRef(data.GetData()),
- data.GetByteOrder() == lldb::eByteOrderLittle, data.GetAddressByteSize());
+ data.GetData(), data.GetByteOrder() == lldb::eByteOrderLittle,
+ data.GetAddressByteSize());
if (m_is_dwo || GetVersion() >= 5)
return std::make_unique<llvm::DWARFDebugLoclists>(llvm_data, GetVersion());
return std::make_unique<llvm::DWARFDebugLoc>(llvm_data);
}
-const DWARFDataExtractor &DWARFUnit::GetLocationData() const {
+DWARFDataExtractor DWARFUnit::GetLocationData() const {
DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext();
- return GetVersion() >= 5 ? Ctx.getOrLoadLocListsData()
- : Ctx.getOrLoadLocData();
+ const DWARFDataExtractor &data =
+ GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData();
+ if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
+ if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC))
+ return DWARFDataExtractor(data, contribution->Offset,
+ contribution->Length);
+ return DWARFDataExtractor();
+ }
+ return data;
}
void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
@@ -506,18 +513,14 @@ void DWARFUnit::ClearDIEsRWLocked() {
m_die_array.clear();
m_die_array.shrink_to_fit();
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->ClearDIEsRWLocked();
+ if (m_dwo)
+ m_dwo->ClearDIEsRWLocked();
}
lldb::ByteOrder DWARFUnit::GetByteOrder() const {
return m_dwarf.GetObjectFile()->GetByteOrder();
}
-llvm::Expected<TypeSystem &> DWARFUnit::GetTypeSystem() {
- return m_dwarf.GetTypeSystemForLanguage(GetLanguageType());
-}
-
void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
// Compare function DWARFDebugAranges::Range structures
@@ -534,9 +537,6 @@ static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
DWARFDIE
DWARFUnit::GetDIE(dw_offset_t die_offset) {
if (die_offset != DW_INVALID_OFFSET) {
- if (GetDwoSymbolFile())
- return GetDwoSymbolFile()->GetCompileUnit()->GetDIE(die_offset);
-
if (ContainsDIEOffset(die_offset)) {
ExtractDIEsIfNeeded();
DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
@@ -555,8 +555,9 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
}
DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
- if (SymbolFileDWARFDwo *dwo = GetDwoSymbolFile())
- return *dwo->GetCompileUnit();
+ ExtractUnitDIEIfNeeded();
+ if (m_dwo)
+ return *m_dwo;
return *this;
}
@@ -570,11 +571,7 @@ uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
void *DWARFUnit::GetUserData() const { return m_user_data; }
-void DWARFUnit::SetUserData(void *d) {
- m_user_data = d;
- if (m_dwo_symbol_file)
- m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
-}
+void DWARFUnit::SetUserData(void *d) { m_user_data = d; }
bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
return GetProducer() != eProducerLLVMGCC;
@@ -658,28 +655,17 @@ uint32_t DWARFUnit::GetProducerVersionUpdate() {
ParseProducerInfo();
return m_producer_version_update;
}
-LanguageType DWARFUnit::LanguageTypeFromDWARF(uint64_t val) {
- // Note: user languages between lo_user and hi_user must be handled
- // explicitly here.
- switch (val) {
- case DW_LANG_Mips_Assembler:
- return eLanguageTypeMipsAssembler;
- case DW_LANG_GOOGLE_RenderScript:
- return eLanguageTypeExtRenderScript;
- default:
- return static_cast<LanguageType>(val);
- }
-}
-LanguageType DWARFUnit::GetLanguageType() {
- if (m_language_type != eLanguageTypeUnknown)
- return m_language_type;
+uint64_t DWARFUnit::GetDWARFLanguageType() {
+ if (m_language_type)
+ return *m_language_type;
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
- if (die)
- m_language_type = LanguageTypeFromDWARF(
- die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0));
- return m_language_type;
+ if (!die)
+ m_language_type = 0;
+ else
+ m_language_type = die->GetAttributeValueAsUnsigned(this, DW_AT_language, 0);
+ return *m_language_type;
}
bool DWARFUnit::GetIsOptimized() {
@@ -738,25 +724,6 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) {
return path;
}
-static FileSpec resolveCompDir(const FileSpec &path) {
- bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex(
- 0, path, /*full*/ true) != UINT32_MAX;
-
- if (!is_symlink)
- return path;
-
- namespace fs = llvm::sys::fs;
- if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file)
- return path;
-
- FileSpec resolved_symlink;
- const auto error = FileSystem::Instance().Readlink(path, resolved_symlink);
- if (error.Success())
- return resolved_symlink;
-
- return path;
-}
-
void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
m_comp_dir = FileSpec();
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
@@ -768,7 +735,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
if (!comp_dir.empty()) {
FileSpec::Style comp_dir_style =
FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native);
- m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style));
+ m_comp_dir = FileSpec(comp_dir, comp_dir_style);
} else {
// Try to detect the style based on the DW_AT_name attribute, but just store
// the detected style in the m_comp_dir field.
@@ -795,21 +762,22 @@ void DWARFUnit::ComputeAbsolutePath() {
SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() {
ExtractUnitDIEIfNeeded();
- return m_dwo_symbol_file.get();
+ if (m_dwo)
+ return &llvm::cast<SymbolFileDWARFDwo>(m_dwo->GetSymbolFileDWARF());
+ return nullptr;
}
const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
if (m_func_aranges_up == nullptr) {
- m_func_aranges_up.reset(new DWARFDebugAranges());
+ m_func_aranges_up = std::make_unique<DWARFDebugAranges>();
const DWARFDebugInfoEntry *die = DIEPtr();
if (die)
die->BuildFunctionAddressRangeTable(this, m_func_aranges_up.get());
- if (m_dwo_symbol_file) {
- DWARFUnit *dwo_cu = m_dwo_symbol_file->GetCompileUnit();
- const DWARFDebugInfoEntry *dwo_die = dwo_cu->DIEPtr();
+ if (m_dwo) {
+ const DWARFDebugInfoEntry *dwo_die = m_dwo->DIEPtr();
if (dwo_die)
- dwo_die->BuildFunctionAddressRangeTable(dwo_cu,
+ dwo_die->BuildFunctionAddressRangeTable(m_dwo.get(),
m_func_aranges_up.get());
}
@@ -820,10 +788,13 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
}
llvm::Expected<DWARFUnitHeader>
-DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section,
- lldb::offset_t *offset_ptr) {
+DWARFUnitHeader::extract(const DWARFDataExtractor &data,
+ DIERef::Section section, lldb::offset_t *offset_ptr,
+ const llvm::DWARFUnitIndex *index) {
DWARFUnitHeader header;
header.m_offset = *offset_ptr;
+ if (index)
+ header.m_index_entry = index->getFromOffset(*offset_ptr);
header.m_length = data.GetDWARFInitialLength(offset_ptr);
header.m_version = data.GetU16(offset_ptr);
if (header.m_version == 5) {
@@ -839,6 +810,26 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
}
+ if (header.m_index_entry) {
+ if (header.m_abbr_offset) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Package unit with a non-zero abbreviation offset");
+ }
+ auto *unit_contrib = header.m_index_entry->getContribution();
+ if (!unit_contrib || unit_contrib->Length != header.m_length + 4) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Inconsistent DWARF package unit index");
+ }
+ auto *abbr_entry =
+ header.m_index_entry->getContribution(llvm::DW_SECT_ABBREV);
+ if (!abbr_entry) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "DWARF package index missing abbreviation column");
+ }
+ header.m_abbr_offset = abbr_entry->Offset;
+ }
if (header.IsTypeUnit()) {
header.m_type_hash = data.GetU64(offset_ptr);
header.m_type_offset = data.GetDWARFOffset(offset_ptr);
@@ -869,11 +860,12 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
llvm::Expected<DWARFUnitSP>
DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
const DWARFDataExtractor &debug_info,
- DIERef::Section section, lldb::offset_t *offset_ptr) {
+ DIERef::Section section, lldb::offset_t *offset_ptr,
+ const llvm::DWARFUnitIndex *index) {
assert(debug_info.ValidOffset(*offset_ptr));
auto expected_header =
- DWARFUnitHeader::extract(debug_info, section, offset_ptr);
+ DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
if (!expected_header)
return expected_header.takeError();
@@ -924,6 +916,12 @@ uint32_t DWARFUnit::GetHeaderByteSize() const {
llvm_unreachable("invalid UnitType.");
}
+llvm::Optional<uint64_t>
+DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
+ offset_t offset = GetStrOffsetsBase() + index * 4;
+ return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetU32(&offset);
+}
+
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
if (GetVersion() <= 4) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 217f9bb89ace..affad286a490 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFUnit_h_
-#define SymbolFileDWARF_DWARFUnit_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H
#include "DWARFDIE.h"
#include "DWARFDebugInfoEntry.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/Utility/XcodeSDK.h"
#include "llvm/Support/RWMutex.h"
#include <atomic>
@@ -39,6 +40,9 @@ class DWARFUnitHeader {
dw_offset_t m_length = 0;
uint16_t m_version = 0;
dw_offset_t m_abbr_offset = 0;
+
+ const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr;
+
uint8_t m_unit_type = 0;
uint8_t m_addr_size = 0;
@@ -56,6 +60,9 @@ public:
dw_offset_t GetLength() const { return m_length; }
dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
uint8_t GetUnitType() const { return m_unit_type; }
+ const llvm::DWARFUnitIndex::Entry *GetIndexEntry() const {
+ return m_index_entry;
+ }
uint64_t GetTypeHash() const { return m_type_hash; }
dw_offset_t GetTypeOffset() const { return m_type_offset; }
bool IsTypeUnit() const {
@@ -65,7 +72,7 @@ public:
static llvm::Expected<DWARFUnitHeader>
extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
- lldb::offset_t *offset_ptr);
+ lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
};
class DWARFUnit : public lldb_private::UserID {
@@ -76,9 +83,12 @@ public:
static llvm::Expected<DWARFUnitSP>
extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
const lldb_private::DWARFDataExtractor &debug_info,
- DIERef::Section section, lldb::offset_t *offset_ptr);
+ DIERef::Section section, lldb::offset_t *offset_ptr,
+ const llvm::DWARFUnitIndex *index);
virtual ~DWARFUnit();
+ bool IsDWOUnit() { return m_is_dwo; }
+
void ExtractUnitDIEIfNeeded();
void ExtractDIEsIfNeeded();
@@ -88,7 +98,8 @@ public:
bool m_clear_dies = false;
ScopedExtractDIEs(DWARFUnit &cu);
~ScopedExtractDIEs();
- DISALLOW_COPY_AND_ASSIGN(ScopedExtractDIEs);
+ ScopedExtractDIEs(const ScopedExtractDIEs &) = delete;
+ const ScopedExtractDIEs &operator=(const ScopedExtractDIEs &) = delete;
ScopedExtractDIEs(ScopedExtractDIEs &&rhs);
ScopedExtractDIEs &operator=(ScopedExtractDIEs &&rhs);
};
@@ -152,8 +163,6 @@ public:
lldb::ByteOrder GetByteOrder() const;
- llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem();
-
const DWARFDebugAranges &GetFunctionAranges();
void SetBaseAddress(dw_addr_t base_addr);
@@ -190,9 +199,7 @@ public:
uint32_t GetProducerVersionUpdate();
- static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
-
- lldb::LanguageType GetLanguageType();
+ uint64_t GetDWARFLanguageType();
bool GetIsOptimized();
@@ -213,6 +220,8 @@ public:
uint8_t GetUnitType() const { return m_header.GetUnitType(); }
bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
+ llvm::Optional<uint64_t> GetStringOffsetSectionItem(uint32_t index) const;
+
/// Return a list of address ranges resulting from a (possibly encoded)
/// range list starting at a given offset in the appropriate ranges section.
llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset);
@@ -248,7 +257,7 @@ public:
std::unique_ptr<llvm::DWARFLocationTable>
GetLocationTable(const lldb_private::DataExtractor &data) const;
- const lldb_private::DWARFDataExtractor &GetLocationData() const;
+ lldb_private::DWARFDataExtractor GetLocationData() const;
protected:
DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
@@ -279,7 +288,7 @@ protected:
}
SymbolFileDWARF &m_dwarf;
- std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
+ std::shared_ptr<DWARFUnit> m_dwo;
DWARFUnitHeader m_header;
const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
void *m_user_data = nullptr;
@@ -304,7 +313,7 @@ protected:
uint32_t m_producer_version_major = 0;
uint32_t m_producer_version_minor = 0;
uint32_t m_producer_version_update = 0;
- lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
+ llvm::Optional<uint64_t> m_language_type;
lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
llvm::Optional<lldb_private::FileSpec> m_comp_dir;
llvm::Optional<lldb_private::FileSpec> m_file_spec;
@@ -329,11 +338,13 @@ private:
void ClearDIEsRWLocked();
void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
+ void SetDwoStrOffsetsBase();
void ComputeCompDirAndGuessPathStyle();
void ComputeAbsolutePath();
- DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
+ DWARFUnit(const DWARFUnit &) = delete;
+ const DWARFUnit &operator=(const DWARFUnit &) = delete;
};
-#endif // SymbolFileDWARF_DWARFUnit_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFUNIT_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 007ef2e05e59..cb3e662a6cdf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -1,4 +1,4 @@
-//===-- DebugNamesDWARFIndex.cpp -------------------------------*- C++ -*-===//
+//===-- DebugNamesDWARFIndex.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,6 +10,7 @@
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
+#include "lldb/Core/Module.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
@@ -19,18 +20,14 @@ using namespace lldb;
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
DWARFDataExtractor debug_str,
- DWARFDebugInfo *debug_info) {
- if (!debug_info) {
- return llvm::make_error<llvm::StringError>("debug info null",
- llvm::inconvertibleErrorCode());
- }
+ SymbolFileDWARF &dwarf) {
auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
- module, std::move(index_up), debug_names, debug_str, *debug_info));
+ module, std::move(index_up), debug_names, debug_str, dwarf));
}
llvm::DenseSet<dw_offset_t>
@@ -53,12 +50,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
if (!cu)
return llvm::None;
- // This initializes the DWO symbol file. It's not possible for
- // GetDwoSymbolFile to call this automatically because of mutual recursion
- // between this and DWARFDebugInfoEntry::GetAttributeValue.
- cu->ExtractUnitDIEIfNeeded();
cu = &cu->GetNonSkeletonUnit();
-
if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
@@ -66,10 +58,18 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
return llvm::None;
}
-void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
- DIEArray &offsets) {
- if (llvm::Optional<DIERef> ref = ToDIERef(entry))
- offsets.push_back(*ref);
+bool DebugNamesDWARFIndex::ProcessEntry(
+ const DebugNames::Entry &entry,
+ llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) {
+ llvm::Optional<DIERef> ref = ToDIERef(entry);
+ if (!ref)
+ return true;
+ SymbolFileDWARF &dwarf =
+ *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile());
+ DWARFDIE die = dwarf.GetDIE(*ref);
+ if (!die)
+ return true;
+ return callback(die);
}
void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
@@ -83,23 +83,23 @@ void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
ni.getUnitOffset(), name);
}
-void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(basename, offsets);
-
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(basename.GetStringRef())) {
if (entry.tag() != DW_TAG_variable)
continue;
- Append(entry, offsets);
+ if (!ProcessEntry(entry, callback, basename.GetStringRef()))
+ return;
}
-}
-void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(regex, offsets);
+ m_fallback.GetGlobalVariables(basename, callback);
+}
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
if (!regex.Execute(nte.getString()))
@@ -111,17 +111,19 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
if (entry_or->tag() != DW_TAG_variable)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
-}
-void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
- DIEArray &offsets) {
- m_fallback.GetGlobalVariables(cu, offsets);
+ m_fallback.GetGlobalVariables(regex, callback);
+}
+void DebugNamesDWARFIndex::GetGlobalVariables(
+ const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
uint64_t cu_offset = cu.GetOffset();
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
@@ -133,18 +135,20 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
if (entry_or->getCUOffset() != cu_offset)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
-}
-void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
- bool must_be_implementation,
- DIEArray &offsets) {
- m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets);
+ m_fallback.GetGlobalVariables(cu, callback);
+}
+void DebugNamesDWARFIndex::GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
// Keep a list of incomplete types as fallback for when we don't find the
// complete type.
DIEArray incomplete_types;
@@ -165,84 +169,98 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
continue;
}
- // FIXME: We should return DWARFDIEs so we don't have to resolve it twice.
DWARFDIE die = m_debug_info.GetDIE(*ref);
- if (!die)
+ if (!die) {
+ ReportInvalidDIERef(*ref, class_name.GetStringRef());
continue;
+ }
if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
// If we find the complete version we're done.
- offsets.push_back(*ref);
+ callback(die);
return;
- } else {
- incomplete_types.push_back(*ref);
}
+ incomplete_types.push_back(*ref);
}
- offsets.insert(offsets.end(), incomplete_types.begin(),
- incomplete_types.end());
-}
+ auto dierefcallback = DIERefCallback(callback, class_name.GetStringRef());
+ for (DIERef ref : incomplete_types)
+ if (!dierefcallback(ref))
+ return;
-void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
- m_fallback.GetTypes(name, offsets);
+ m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, callback);
+}
+void DebugNamesDWARFIndex::GetTypes(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
- if (isType(entry.tag()))
- Append(entry, offsets);
+ if (isType(entry.tag())) {
+ if (!ProcessEntry(entry, callback, name.GetStringRef()))
+ return;
+ }
}
-}
-void DebugNamesDWARFIndex::GetTypes(const DWARFDeclContext &context,
- DIEArray &offsets) {
- m_fallback.GetTypes(context, offsets);
+ m_fallback.GetTypes(name, callback);
+}
- for (const DebugNames::Entry &entry :
- m_debug_names_up->equal_range(context[0].name)) {
- if (entry.tag() == context[0].tag)
- Append(entry, offsets);
+void DebugNamesDWARFIndex::GetTypes(
+ const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ auto name = context[0].name;
+ for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) {
+ if (entry.tag() == context[0].tag) {
+ if (!ProcessEntry(entry, callback, name))
+ return;
+ }
}
-}
-void DebugNamesDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
- m_fallback.GetNamespaces(name, offsets);
+ m_fallback.GetTypes(context, callback);
+}
+void DebugNamesDWARFIndex::GetNamespaces(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
- if (entry.tag() == DW_TAG_namespace)
- Append(entry, offsets);
+ if (entry.tag() == DW_TAG_namespace) {
+ if (!ProcessEntry(entry, callback, name.GetStringRef()))
+ return;
+ }
}
+
+ m_fallback.GetNamespaces(name, callback);
}
void DebugNamesDWARFIndex::GetFunctions(
ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) {
-
- std::vector<DWARFDIE> v;
- m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask, v);
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ std::set<DWARFDebugInfoEntry *> seen;
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
Tag tag = entry.tag();
if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
continue;
- if (llvm::Optional<DIERef> ref = ToDIERef(entry))
- ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
- name_type_mask, v);
+ if (llvm::Optional<DIERef> ref = ToDIERef(entry)) {
+ if (!ProcessFunctionDIE(name.GetStringRef(), *ref, dwarf, parent_decl_ctx,
+ name_type_mask, [&](DWARFDIE die) {
+ if (!seen.insert(die.GetDIE()).second)
+ return true;
+ return callback(die);
+ }))
+ return;
+ }
}
- std::set<DWARFDebugInfoEntry *> seen;
- for (DWARFDIE die : v)
- if (seen.insert(die.GetDIE()).second)
- dies.push_back(die);
+ m_fallback.GetFunctions(name, dwarf, parent_decl_ctx, name_type_mask,
+ callback);
}
-void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) {
- m_fallback.GetFunctions(regex, offsets);
-
+void DebugNamesDWARFIndex::GetFunctions(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
if (!regex.Execute(nte.getString()))
@@ -255,11 +273,15 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine)
continue;
- Append(*entry_or, offsets);
+ if (!ProcessEntry(*entry_or, callback,
+ llvm::StringRef(nte.getString())))
+ return;
}
MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
}
}
+
+ m_fallback.GetFunctions(regex, callback);
}
void DebugNamesDWARFIndex::Dump(Stream &s) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
index dca25496373f..5d041c36c8f2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_DEBUGNAMESDWARFINDEX_H
-#define LLDB_DEBUGNAMESDWARFINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "lldb/Utility/ConstString.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
@@ -20,28 +21,38 @@ class DebugNamesDWARFIndex : public DWARFIndex {
public:
static llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>>
Create(Module &module, DWARFDataExtractor debug_names,
- DWARFDataExtractor debug_str, DWARFDebugInfo *debug_info);
+ DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf);
void Preload() override { m_fallback.Preload(); }
- void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
- void GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) override;
- void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
- void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {}
- void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
- DIEArray &offsets) override;
- void GetTypes(ConstString name, DIEArray &offsets) override;
- void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
- void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void
+ GetGlobalVariables(ConstString basename,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const DWARFUnit &cu,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetObjCMethods(ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override {}
+ void GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetNamespaces(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) override;
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) override;
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
- void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
void Dump(Stream &s) override;
private:
@@ -49,11 +60,11 @@ private:
std::unique_ptr<llvm::DWARFDebugNames> debug_names_up,
DWARFDataExtractor debug_names_data,
DWARFDataExtractor debug_str_data,
- DWARFDebugInfo &debug_info)
- : DWARFIndex(module), m_debug_info(debug_info),
+ SymbolFileDWARF &dwarf)
+ : DWARFIndex(module), m_debug_info(dwarf.DebugInfo()),
m_debug_names_data(debug_names_data), m_debug_str_data(debug_str_data),
m_debug_names_up(std::move(debug_names_up)),
- m_fallback(module, &debug_info, GetUnits(*m_debug_names_up)) {}
+ m_fallback(module, dwarf, GetUnits(*m_debug_names_up)) {}
DWARFDebugInfo &m_debug_info;
@@ -67,7 +78,9 @@ private:
ManualDWARFIndex m_fallback;
llvm::Optional<DIERef> ToDIERef(const DebugNames::Entry &entry);
- void Append(const DebugNames::Entry &entry, DIEArray &offsets);
+ bool ProcessEntry(const DebugNames::Entry &entry,
+ llvm::function_ref<bool(DWARFDIE die)> callback,
+ llvm::StringRef name);
static void MaybeLogLookupError(llvm::Error error,
const DebugNames::NameIndex &ni,
@@ -78,4 +91,4 @@ private:
} // namespace lldb_private
-#endif // LLDB_DEBUGNAMESDWARFINDEX_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DEBUGNAMESDWARFINDEX_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 88a29f4a2672..d36f2a8bccf7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -1,4 +1,4 @@
-//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===//
+//===-- HashedNameToDIE.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,91 +9,99 @@
#include "HashedNameToDIE.h"
#include "llvm/ADT/StringRef.h"
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
- DIEArray &die_offsets) {
+bool DWARFMappedHash::ExtractDIEArray(
+ const DIEInfoArray &die_info_array,
+ llvm::function_ref<bool(DIERef ref)> callback) {
const size_t count = die_info_array.size();
for (size_t i = 0; i < count; ++i)
- die_offsets.emplace_back(die_info_array[i]);
+ if (!callback(DIERef(die_info_array[i])))
+ return false;
+ return true;
}
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- DIEArray &die_offsets) {
+void DWARFMappedHash::ExtractDIEArray(
+ const DIEInfoArray &die_info_array, const dw_tag_t tag,
+ llvm::function_ref<bool(DIERef ref)> callback) {
if (tag == 0) {
- ExtractDIEArray(die_info_array, die_offsets);
- } else {
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches) {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches =
- tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i]);
+ ExtractDIEArray(die_info_array, callback);
+ return;
+ }
+
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches) {
+ if (!callback(DIERef(die_info_array[i])))
+ return;
}
}
}
-void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets) {
+void DWARFMappedHash::ExtractDIEArray(
+ const DIEInfoArray &die_info_array, const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ llvm::function_ref<bool(DIERef ref)> callback) {
if (tag == 0) {
- ExtractDIEArray(die_info_array, die_offsets);
- } else {
- const size_t count = die_info_array.size();
- for (size_t i = 0; i < count; ++i) {
- if (qualified_name_hash != die_info_array[i].qualified_name_hash)
- continue;
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches) {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches =
- tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i]);
+ ExtractDIEArray(die_info_array, callback);
+ return;
+ }
+
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+ continue;
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches) {
+ if (!callback(DIERef(die_info_array[i])))
+ return;
}
}
}
void DWARFMappedHash::ExtractClassOrStructDIEArray(
const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available, DIEArray &die_offsets) {
+ bool return_implementation_only_if_available,
+ llvm::function_ref<bool(DIERef ref)> callback) {
const size_t count = die_info_array.size();
for (size_t i = 0; i < count; ++i) {
const dw_tag_t die_tag = die_info_array[i].tag;
- if (die_tag == 0 || die_tag == DW_TAG_class_type ||
- die_tag == DW_TAG_structure_type) {
- if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) {
- if (return_implementation_only_if_available) {
- // We found the one true definition for this class, so only return
- // that
- die_offsets.clear();
- die_offsets.emplace_back(die_info_array[i]);
- return;
- } else {
- // Put the one true definition as the first entry so it matches first
- die_offsets.emplace(die_offsets.begin(), die_info_array[i]);
- }
- } else {
- die_offsets.emplace_back(die_info_array[i]);
- }
+ if (!(die_tag == 0 || die_tag == DW_TAG_class_type ||
+ die_tag == DW_TAG_structure_type))
+ continue;
+ bool is_implementation =
+ (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0;
+ if (is_implementation != return_implementation_only_if_available)
+ continue;
+ if (return_implementation_only_if_available) {
+ // We found the one true definition for this class, so only return
+ // that
+ callback(DIERef(die_info_array[i]));
+ return;
}
+ if (!callback(DIERef(die_info_array[i])))
+ return;
}
}
void DWARFMappedHash::ExtractTypesFromDIEArray(
const DIEInfoArray &die_info_array, uint32_t type_flag_mask,
- uint32_t type_flag_value, DIEArray &die_offsets) {
+ uint32_t type_flag_value, llvm::function_ref<bool(DIERef ref)> callback) {
const size_t count = die_info_array.size();
for (size_t i = 0; i < count; ++i) {
- if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
- die_offsets.emplace_back(die_info_array[i]);
+ if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) {
+ if (!callback(DIERef(die_info_array[i])))
+ return;
+ }
}
}
@@ -453,7 +461,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
}
}
-size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
+void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
const lldb_private::RegularExpression &regex,
DIEInfoArray &die_info_array) const {
const uint32_t hash_count = m_header.hashes_count;
@@ -482,10 +490,9 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
}
}
die_info_array.swap(pair.value);
- return die_info_array.size();
}
-size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
+void DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
const uint32_t die_offset_start, const uint32_t die_offset_end,
DIEInfoArray &die_info_array) const {
const uint32_t hash_count = m_header.hashes_count;
@@ -512,73 +519,74 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
}
}
}
- return die_info_array.size();
}
-size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
- DIEArray &die_offsets) {
+bool DWARFMappedHash::MemoryTable::FindByName(
+ llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback) {
if (name.empty())
- return 0;
+ return true;
DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets);
- return die_info_array.size();
+ FindByName(name, die_info_array);
+ return DWARFMappedHash::ExtractDIEArray(die_info_array, callback);
}
-size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(llvm::StringRef name,
- const dw_tag_t tag,
- DIEArray &die_offsets) {
+void DWARFMappedHash::MemoryTable::FindByNameAndTag(
+ llvm::StringRef name, const dw_tag_t tag,
+ llvm::function_ref<bool(DIERef ref)> callback) {
DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets);
- return die_info_array.size();
+ FindByName(name, die_info_array);
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback);
}
-size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
+void DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
llvm::StringRef name, const dw_tag_t tag,
- const uint32_t qualified_name_hash, DIEArray &die_offsets) {
+ const uint32_t qualified_name_hash,
+ llvm::function_ref<bool(DIERef ref)> callback) {
DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
- die_offsets);
- return die_info_array.size();
+ FindByName(name, die_info_array);
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
+ callback);
}
-size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
- llvm::StringRef name, DIEArray &die_offsets, bool must_be_implementation) {
+void DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
+ llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback,
+ bool must_be_implementation) {
DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array)) {
- if (must_be_implementation &&
- GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
- // If we have two atoms, then we have the DIE offset and the type flags
- // so we can find the objective C class efficiently.
- DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX,
- eTypeFlagClassIsImplementation,
- die_offsets);
- } else {
- // We don't only want the one true definition, so try and see what we can
- // find, and only return class or struct DIEs. If we do have the full
- // implementation, then return it alone, else return all possible
- // matches.
- const bool return_implementation_only_if_available = true;
- DWARFMappedHash::ExtractClassOrStructDIEArray(
- die_info_array, return_implementation_only_if_available, die_offsets);
- }
+ FindByName(name, die_info_array);
+ if (must_be_implementation &&
+ GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
+ // If we have two atoms, then we have the DIE offset and the type flags
+ // so we can find the objective C class efficiently.
+ DWARFMappedHash::ExtractTypesFromDIEArray(
+ die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback);
+ return;
}
- return die_offsets.size();
+ // We don't only want the one true definition, so try and see what we can
+ // find, and only return class or struct DIEs. If we do have the full
+ // implementation, then return it alone, else return all possible
+ // matches.
+ bool found_implementation = false;
+ DWARFMappedHash::ExtractClassOrStructDIEArray(
+ die_info_array, true /*return_implementation_only_if_available*/,
+ [&](DIERef ref) {
+ found_implementation = true;
+ // Here the return value does not matter as we are called at most once.
+ return callback(ref);
+ });
+ if (found_implementation)
+ return;
+ DWARFMappedHash::ExtractClassOrStructDIEArray(
+ die_info_array, false /*return_implementation_only_if_available*/,
+ callback);
}
-size_t DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
- DIEInfoArray &die_info_array) {
+void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name,
+ DIEInfoArray &die_info_array) {
if (name.empty())
- return 0;
+ return;
Pair kv_pair;
- size_t old_size = die_info_array.size();
- if (Find(name, kv_pair)) {
+ if (Find(name, kv_pair))
die_info_array.swap(kv_pair.value);
- return die_info_array.size() - old_size;
- }
- return 0;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index 56d9bc548877..ad178fc6a987 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_HashedNameToDIE_h_
-#define SymbolFileDWARF_HashedNameToDIE_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H
#include <vector>
@@ -132,33 +132,36 @@ public:
bool ReadHashData(uint32_t hash_data_offset,
HashData &hash_data) const override;
- size_t
+ void
AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression &regex,
DIEInfoArray &die_info_array) const;
- size_t AppendAllDIEsInRange(const uint32_t die_offset_start,
- const uint32_t die_offset_end,
- DIEInfoArray &die_info_array) const;
+ void AppendAllDIEsInRange(const uint32_t die_offset_start,
+ const uint32_t die_offset_end,
+ DIEInfoArray &die_info_array) const;
- size_t FindByName(llvm::StringRef name, DIEArray &die_offsets);
+ bool FindByName(llvm::StringRef name,
+ llvm::function_ref<bool(DIERef ref)> callback);
- size_t FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
- DIEArray &die_offsets);
+ void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag,
+ llvm::function_ref<bool(DIERef ref)> callback);
- size_t FindByNameAndTagAndQualifiedNameHash(
+ void FindByNameAndTagAndQualifiedNameHash(
llvm::StringRef name, const dw_tag_t tag,
- const uint32_t qualified_name_hash, DIEArray &die_offsets);
+ const uint32_t qualified_name_hash,
+ llvm::function_ref<bool(DIERef ref)> callback);
- size_t FindCompleteObjCClassByName(llvm::StringRef name,
- DIEArray &die_offsets,
- bool must_be_implementation);
+ void
+ FindCompleteObjCClassByName(llvm::StringRef name,
+ llvm::function_ref<bool(DIERef ref)> callback,
+ bool must_be_implementation);
protected:
Result AppendHashDataForRegularExpression(
const lldb_private::RegularExpression &regex,
lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
- size_t FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
+ void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array);
Result GetHashDataForName(llvm::StringRef name,
lldb::offset_t *hash_data_offset_ptr,
@@ -169,29 +172,30 @@ public:
std::string m_name;
};
- static void ExtractDIEArray(const DIEInfoArray &die_info_array,
- DIEArray &die_offsets);
+ static bool ExtractDIEArray(const DIEInfoArray &die_info_array,
+ llvm::function_ref<bool(DIERef ref)> callback);
protected:
static void ExtractDIEArray(const DIEInfoArray &die_info_array,
- const dw_tag_t tag, DIEArray &die_offsets);
+ const dw_tag_t tag,
+ llvm::function_ref<bool(DIERef ref)> callback);
static void ExtractDIEArray(const DIEInfoArray &die_info_array,
const dw_tag_t tag,
const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
+ llvm::function_ref<bool(DIERef ref)> callback);
static void
ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
bool return_implementation_only_if_available,
- DIEArray &die_offsets);
+ llvm::function_ref<bool(DIERef ref)> callback);
- static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
- uint32_t type_flag_mask,
- uint32_t type_flag_value,
- DIEArray &die_offsets);
+ static void
+ ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
+ uint32_t type_flag_mask, uint32_t type_flag_value,
+ llvm::function_ref<bool(DIERef ref)> callback);
static const char *GetAtomTypeName(uint16_t atom);
};
-#endif // SymbolFileDWARF_HashedNameToDIE_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
index 8495016d4280..3f1d6677bacf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -1,4 +1,4 @@
-//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===//
+//===-- LogChannelDWARF.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
index a89c686735d2..2fc23563ef93 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_LogChannelDWARF_h_
-#define SymbolFileDWARF_LogChannelDWARF_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
#include "lldb/Utility/Log.h"
@@ -32,4 +32,4 @@ public:
};
}
-#endif // SymbolFileDWARF_LogChannelDWARF_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 1e5927bd14f0..7bf4b52bc783 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -1,4 +1,4 @@
-//===-- ManualDWARFIndex.cpp -----------------------------------*- C++ -*-===//
+//===-- ManualDWARFIndex.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,31 +13,47 @@
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
#include "lldb/Core/Module.h"
-#include "lldb/Host/TaskPool.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/Support/ThreadPool.h"
using namespace lldb_private;
using namespace lldb;
void ManualDWARFIndex::Index() {
- if (!m_debug_info)
+ if (!m_dwarf)
return;
- DWARFDebugInfo &debug_info = *m_debug_info;
- m_debug_info = nullptr;
+ SymbolFileDWARF &main_dwarf = *m_dwarf;
+ m_dwarf = nullptr;
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));
+ Timer scoped_timer(func_cat, "%p", static_cast<void *>(&main_dwarf));
+
+ DWARFDebugInfo &main_info = main_dwarf.DebugInfo();
+ SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get();
+ DWARFDebugInfo *dwp_info = dwp_dwarf ? &dwp_dwarf->DebugInfo() : nullptr;
std::vector<DWARFUnit *> units_to_index;
- units_to_index.reserve(debug_info.GetNumUnits());
- for (size_t U = 0; U < debug_info.GetNumUnits(); ++U) {
- DWARFUnit *unit = debug_info.GetUnitAtIndex(U);
+ units_to_index.reserve(main_info.GetNumUnits() +
+ (dwp_info ? dwp_info->GetNumUnits() : 0));
+
+ // Process all units in the main file, as well as any type units in the dwp
+ // file. Type units in dwo files are handled when we reach the dwo file in
+ // IndexUnit.
+ for (size_t U = 0; U < main_info.GetNumUnits(); ++U) {
+ DWARFUnit *unit = main_info.GetUnitAtIndex(U);
if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0)
units_to_index.push_back(unit);
}
+ if (dwp_info && dwp_info->ContainsTypeUnits()) {
+ for (size_t U = 0; U < dwp_info->GetNumUnits(); ++U) {
+ if (auto *tu = llvm::dyn_cast<DWARFTypeUnit>(dwp_info->GetUnitAtIndex(U)))
+ units_to_index.push_back(tu);
+ }
+ }
+
if (units_to_index.empty())
return;
@@ -48,27 +64,34 @@ void ManualDWARFIndex::Index() {
std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies(
units_to_index.size());
auto parser_fn = [&](size_t cu_idx) {
- IndexUnit(*units_to_index[cu_idx], sets[cu_idx]);
+ IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]);
};
auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
};
+ // Share one thread pool across operations to avoid the overhead of
+ // recreating the threads.
+ llvm::ThreadPool pool;
+
// Create a task runner that extracts dies for each DWARF unit in a
- // separate thread
+ // separate thread.
// First figure out which units didn't have their DIEs already
// parsed and remember this. If no DIEs were parsed prior to this index
// function call, we are going to want to clear the CU dies after we are
// done indexing to make sure we don't pull in all DWARF dies, but we need
// to wait until all units have been indexed in case a DIE in one
// unit refers to another and the indexes accesses those DIEs.
- TaskMapOverInt(0, units_to_index.size(), extract_fn);
+ for (size_t i = 0; i < units_to_index.size(); ++i)
+ pool.async(extract_fn, i);
+ pool.wait();
// Now create a task runner that can index each DWARF unit in a
// separate thread so we can index quickly.
-
- TaskMapOverInt(0, units_to_index.size(), parser_fn);
+ for (size_t i = 0; i < units_to_index.size(); ++i)
+ pool.async(parser_fn, i);
+ pool.wait();
auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) {
NameToDIE &result = m_set.*index;
@@ -77,21 +100,19 @@ void ManualDWARFIndex::Index() {
result.Finalize();
};
- TaskPool::RunTasks([&]() { finalize_fn(&IndexSet::function_basenames); },
- [&]() { finalize_fn(&IndexSet::function_fullnames); },
- [&]() { finalize_fn(&IndexSet::function_methods); },
- [&]() { finalize_fn(&IndexSet::function_selectors); },
- [&]() { finalize_fn(&IndexSet::objc_class_selectors); },
- [&]() { finalize_fn(&IndexSet::globals); },
- [&]() { finalize_fn(&IndexSet::types); },
- [&]() { finalize_fn(&IndexSet::namespaces); });
+ pool.async(finalize_fn, &IndexSet::function_basenames);
+ pool.async(finalize_fn, &IndexSet::function_fullnames);
+ pool.async(finalize_fn, &IndexSet::function_methods);
+ pool.async(finalize_fn, &IndexSet::function_selectors);
+ pool.async(finalize_fn, &IndexSet::objc_class_selectors);
+ pool.async(finalize_fn, &IndexSet::globals);
+ pool.async(finalize_fn, &IndexSet::types);
+ pool.async(finalize_fn, &IndexSet::namespaces);
+ pool.wait();
}
-void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
- assert(
- !unit.GetSymbolFileDWARF().GetBaseCompileUnit() &&
- "DWARFUnit associated with .dwo or .dwp should not be indexed directly");
-
+void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
+ IndexSet &set) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
if (log) {
@@ -100,14 +121,21 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
unit.GetOffset());
}
- const LanguageType cu_language = unit.GetLanguageType();
+ const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit);
IndexUnitImpl(unit, cu_language, set);
if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) {
- DWARFDebugInfo &dwo_info = *dwo_symbol_file->DebugInfo();
- for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
- IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
+ // Type units in a dwp file are indexed separately, so we just need to
+ // process the split unit here. However, if the split unit is in a dwo file,
+ // then we need to process type units here.
+ if (dwo_symbol_file == dwp) {
+ IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set);
+ } else {
+ DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo();
+ for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
+ IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
+ }
}
}
@@ -165,12 +193,6 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
is_declaration = form_value.Unsigned() != 0;
break;
- // case DW_AT_artificial:
- // if (attributes.ExtractFormValueAtIndex(i,
- // form_value))
- // is_artificial = form_value.Unsigned() != 0;
- // break;
-
case DW_AT_MIPS_linkage_name:
case DW_AT_linkage_name:
if (attributes.ExtractFormValueAtIndex(i, form_value))
@@ -190,49 +212,8 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
case DW_AT_location:
case DW_AT_const_value:
has_location_or_const_value = true;
- if (tag == DW_TAG_variable) {
- const DWARFDebugInfoEntry *parent_die = die.GetParent();
- while (parent_die != nullptr) {
- switch (parent_die->Tag()) {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it. We
- // could theoretically add these if we wanted to by
- // introspecting into the DW_AT_location and seeing if the
- // location describes a hard coded address, but we don't want
- // the performance penalty of that right now.
- is_global_or_static_variable = false;
- // if (attributes.ExtractFormValueAtIndex(dwarf, i,
- // form_value)) {
- // // If we have valid block data, then we have location
- // // expression bytesthat are fixed (not a location list).
- // const uint8_t *block_data = form_value.BlockData();
- // if (block_data) {
- // uint32_t block_length = form_value.Unsigned();
- // if (block_length == 1 +
- // attributes.UnitAtIndex(i)->GetAddressByteSize()) {
- // if (block_data[0] == DW_OP_addr)
- // add_die = true;
- // }
- // }
- // }
- parent_die = nullptr; // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- case DW_TAG_partial_unit:
- is_global_or_static_variable = true;
- parent_die = nullptr; // Terminate the while loop.
- break;
-
- default:
- parent_die =
- parent_die->GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
+ is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable();
+
break;
case DW_AT_specification:
@@ -347,108 +328,118 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
}
}
-void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+void ManualDWARFIndex::GetGlobalVariables(
+ ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.globals.Find(basename, offsets);
+ m_set.globals.Find(basename,
+ DIERefCallback(callback, basename.GetStringRef()));
}
-void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetGlobalVariables(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.globals.Find(regex, offsets);
+ m_set.globals.Find(regex, DIERefCallback(callback, regex.GetText()));
}
-void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &unit,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetGlobalVariables(
+ const DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.globals.FindAllEntriesForUnit(unit, offsets);
+ m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback));
}
-void ManualDWARFIndex::GetObjCMethods(ConstString class_name,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetObjCMethods(
+ ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.objc_class_selectors.Find(class_name, offsets);
+ m_set.objc_class_selectors.Find(
+ class_name, DIERefCallback(callback, class_name.GetStringRef()));
}
-void ManualDWARFIndex::GetCompleteObjCClass(ConstString class_name,
- bool must_be_implementation,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.types.Find(class_name, offsets);
+ m_set.types.Find(class_name,
+ DIERefCallback(callback, class_name.GetStringRef()));
}
-void ManualDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
+void ManualDWARFIndex::GetTypes(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.types.Find(name, offsets);
+ m_set.types.Find(name, DIERefCallback(callback, name.GetStringRef()));
}
-void ManualDWARFIndex::GetTypes(const DWARFDeclContext &context,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetTypes(
+ const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.types.Find(ConstString(context[0].name), offsets);
+ auto name = context[0].name;
+ m_set.types.Find(ConstString(name),
+ DIERefCallback(callback, llvm::StringRef(name)));
}
-void ManualDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
+void ManualDWARFIndex::GetNamespaces(
+ ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.namespaces.Find(name, offsets);
+ m_set.namespaces.Find(name, DIERefCallback(callback, name.GetStringRef()));
}
-void ManualDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
- const CompilerDeclContext &parent_decl_ctx,
- uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) {
+void ManualDWARFIndex::GetFunctions(
+ ConstString name, SymbolFileDWARF &dwarf,
+ const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
if (name_type_mask & eFunctionNameTypeFull) {
- DIEArray offsets;
- m_set.function_fullnames.Find(name, offsets);
- for (const DIERef &die_ref: offsets) {
- DWARFDIE die = dwarf.GetDIE(die_ref);
- if (!die)
- continue;
- if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
- dies.push_back(die);
- }
+ if (!m_set.function_fullnames.Find(
+ name, DIERefCallback(
+ [&](DWARFDIE die) {
+ if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx,
+ die))
+ return true;
+ return callback(die);
+ },
+ name.GetStringRef())))
+ return;
}
if (name_type_mask & eFunctionNameTypeBase) {
- DIEArray offsets;
- m_set.function_basenames.Find(name, offsets);
- for (const DIERef &die_ref: offsets) {
- DWARFDIE die = dwarf.GetDIE(die_ref);
- if (!die)
- continue;
- if (SymbolFileDWARF::DIEInDeclContext(&parent_decl_ctx, die))
- dies.push_back(die);
- }
- offsets.clear();
+ if (!m_set.function_basenames.Find(
+ name, DIERefCallback(
+ [&](DWARFDIE die) {
+ if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx,
+ die))
+ return true;
+ return callback(die);
+ },
+ name.GetStringRef())))
+ return;
}
if (name_type_mask & eFunctionNameTypeMethod && !parent_decl_ctx.IsValid()) {
- DIEArray offsets;
- m_set.function_methods.Find(name, offsets);
- for (const DIERef &die_ref: offsets) {
- if (DWARFDIE die = dwarf.GetDIE(die_ref))
- dies.push_back(die);
- }
+ if (!m_set.function_methods.Find(
+ name, DIERefCallback(callback, name.GetStringRef())))
+ return;
}
if (name_type_mask & eFunctionNameTypeSelector &&
!parent_decl_ctx.IsValid()) {
- DIEArray offsets;
- m_set.function_selectors.Find(name, offsets);
- for (const DIERef &die_ref: offsets) {
- if (DWARFDIE die = dwarf.GetDIE(die_ref))
- dies.push_back(die);
- }
+ if (!m_set.function_selectors.Find(
+ name, DIERefCallback(callback, name.GetStringRef())))
+ return;
}
}
-void ManualDWARFIndex::GetFunctions(const RegularExpression &regex,
- DIEArray &offsets) {
+void ManualDWARFIndex::GetFunctions(
+ const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
Index();
- m_set.function_basenames.Find(regex, offsets);
- m_set.function_fullnames.Find(regex, offsets);
+ if (!m_set.function_basenames.Find(regex,
+ DIERefCallback(callback, regex.GetText())))
+ return;
+ if (!m_set.function_fullnames.Find(regex,
+ DIERefCallback(callback, regex.GetText())))
+ return;
}
void ManualDWARFIndex::Dump(Stream &s) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
index dd03b103c936..baff989eecca 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -6,42 +6,53 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_MANUALDWARFINDEX_H
-#define LLDB_MANUALDWARFINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
#include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/NameToDIE.h"
#include "llvm/ADT/DenseSet.h"
class DWARFDebugInfo;
+class SymbolFileDWARFDwo;
namespace lldb_private {
class ManualDWARFIndex : public DWARFIndex {
public:
- ManualDWARFIndex(Module &module, DWARFDebugInfo *debug_info,
+ ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf,
llvm::DenseSet<dw_offset_t> units_to_avoid = {})
- : DWARFIndex(module), m_debug_info(debug_info),
+ : DWARFIndex(module), m_dwarf(&dwarf),
m_units_to_avoid(std::move(units_to_avoid)) {}
void Preload() override { Index(); }
- void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
- void GetGlobalVariables(const RegularExpression &regex,
- DIEArray &offsets) override;
- void GetGlobalVariables(const DWARFUnit &unit, DIEArray &offsets) override;
- void GetObjCMethods(ConstString class_name, DIEArray &offsets) override;
- void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
- DIEArray &offsets) override;
- void GetTypes(ConstString name, DIEArray &offsets) override;
- void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
- void GetNamespaces(ConstString name, DIEArray &offsets) override;
+ void
+ GetGlobalVariables(ConstString basename,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void
+ GetGlobalVariables(const DWARFUnit &unit,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetObjCMethods(ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetCompleteObjCClass(
+ ConstString class_name, bool must_be_implementation,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetTypes(const DWARFDeclContext &context,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetNamespaces(ConstString name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
void GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
const CompilerDeclContext &parent_decl_ctx,
uint32_t name_type_mask,
- std::vector<DWARFDIE> &dies) override;
- void GetFunctions(const RegularExpression &regex, DIEArray &offsets) override;
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
+ void GetFunctions(const RegularExpression &regex,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
- void ReportInvalidDIERef(const DIERef &ref, llvm::StringRef name) override {}
void Dump(Stream &s) override;
private:
@@ -56,14 +67,15 @@ private:
NameToDIE namespaces;
};
void Index();
- void IndexUnit(DWARFUnit &unit, IndexSet &set);
+ void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
static void IndexUnitImpl(DWARFUnit &unit,
const lldb::LanguageType cu_language,
IndexSet &set);
- /// Non-null value means we haven't built the index yet.
- DWARFDebugInfo *m_debug_info;
+ /// The DWARF file which we are indexing. Set to nullptr after the index is
+ /// built.
+ SymbolFileDWARF *m_dwarf;
/// Which dwarf units should we skip while building the index.
llvm::DenseSet<dw_offset_t> m_units_to_avoid;
@@ -71,4 +83,4 @@ private:
};
} // namespace lldb_private
-#endif // LLDB_MANUALDWARFINDEX_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index 7d81afb1b226..42e96af84a96 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -1,4 +1,4 @@
-//===-- NameToDIE.cpp -------------------------------------------*- C++ -*-===//
+//===-- NameToDIE.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -26,28 +26,38 @@ void NameToDIE::Insert(ConstString name, const DIERef &die_ref) {
m_map.Append(name, die_ref);
}
-size_t NameToDIE::Find(ConstString name, DIEArray &info_array) const {
- return m_map.GetValues(name, info_array);
+bool NameToDIE::Find(ConstString name,
+ llvm::function_ref<bool(DIERef ref)> callback) const {
+ for (const auto &entry : m_map.equal_range(name))
+ if (!callback(entry.value))
+ return false;
+ return true;
}
-size_t NameToDIE::Find(const RegularExpression &regex,
- DIEArray &info_array) const {
- return m_map.GetValues(regex, info_array);
+bool NameToDIE::Find(const RegularExpression &regex,
+ llvm::function_ref<bool(DIERef ref)> callback) const {
+ for (const auto &entry : m_map)
+ if (regex.Execute(entry.cstring.GetCString())) {
+ if (!callback(entry.value))
+ return false;
+ }
+ return true;
}
-size_t NameToDIE::FindAllEntriesForUnit(const DWARFUnit &unit,
- DIEArray &info_array) const {
- const size_t initial_size = info_array.size();
+void NameToDIE::FindAllEntriesForUnit(
+ const DWARFUnit &unit,
+ llvm::function_ref<bool(DIERef ref)> callback) const {
const uint32_t size = m_map.GetSize();
for (uint32_t i = 0; i < size; ++i) {
const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() &&
unit.GetDebugSection() == die_ref.section() &&
unit.GetOffset() <= die_ref.die_offset() &&
- die_ref.die_offset() < unit.GetNextUnitOffset())
- info_array.push_back(die_ref);
+ die_ref.die_offset() < unit.GetNextUnitOffset()) {
+ if (!callback(die_ref))
+ return;
+ }
}
- return info_array.size() - initial_size;
}
void NameToDIE::Dump(Stream *s) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index b504f45e81b5..5aa841cf3d10 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_NameToDIE_h_
-#define SymbolFileDWARF_NameToDIE_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H
#include <functional>
@@ -32,14 +32,15 @@ public:
void Finalize();
- size_t Find(lldb_private::ConstString name,
- DIEArray &info_array) const;
+ bool Find(lldb_private::ConstString name,
+ llvm::function_ref<bool(DIERef ref)> callback) const;
- size_t Find(const lldb_private::RegularExpression &regex,
- DIEArray &info_array) const;
+ bool Find(const lldb_private::RegularExpression &regex,
+ llvm::function_ref<bool(DIERef ref)> callback) const;
- size_t FindAllEntriesForUnit(const DWARFUnit &unit,
- DIEArray &info_array) const;
+ void
+ FindAllEntriesForUnit(const DWARFUnit &unit,
+ llvm::function_ref<bool(DIERef ref)> callback) const;
void
ForEach(std::function<bool(lldb_private::ConstString name,
@@ -50,4 +51,4 @@ protected:
lldb_private::UniqueCStringMap<DIERef> m_map;
};
-#endif // SymbolFileDWARF_NameToDIE_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_NAMETODIE_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d45a8b56efe4..9f64e5255fd5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
+//===-- SymbolFileDWARF.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -34,9 +34,9 @@
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
@@ -70,7 +70,6 @@
#include "ManualDWARFIndex.h"
#include "SymbolFileDWARFDebugMap.h"
#include "SymbolFileDWARFDwo.h"
-#include "SymbolFileDWARFDwp.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/FileSystem.h"
@@ -94,6 +93,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(SymbolFileDWARF)
+
char SymbolFileDWARF::ID;
// static inline bool
@@ -135,14 +136,6 @@ public:
m_collection_sp->Initialize(g_symbolfiledwarf_properties);
}
- FileSpecList GetSymLinkPaths() {
- const OptionValueFileSpecList *option_value =
- m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
- nullptr, true, ePropertySymLinkPaths);
- assert(option_value);
- return option_value->GetCurrentValue();
- }
-
bool IgnoreFileIndexes() const {
return m_collection_sp->GetPropertyAtIndexAsBoolean(
nullptr, ePropertyIgnoreIndexes, false);
@@ -169,18 +162,46 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context,
llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
line.getOrParseLineTable(
data, line_offset, ctx, nullptr, [&](llvm::Error e) {
- LLDB_LOG_ERROR(log, std::move(e),
- "SymbolFileDWARF::ParseLineTable failed to parse");
+ LLDB_LOG_ERROR(
+ log, std::move(e),
+ "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
});
if (!line_table) {
LLDB_LOG_ERROR(log, line_table.takeError(),
- "SymbolFileDWARF::ParseLineTable failed to parse");
+ "SymbolFileDWARF::ParseLineTable failed to parse: {0}");
return nullptr;
}
return *line_table;
}
+static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context,
+ llvm::DWARFDebugLine::Prologue &prologue,
+ dw_offset_t line_offset,
+ dw_offset_t unit_offset) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ bool success = true;
+ llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = context.GetAsLLVM();
+ uint64_t offset = line_offset;
+ llvm::Error error = prologue.parse(
+ data, &offset,
+ [&](llvm::Error e) {
+ success = false;
+ LLDB_LOG_ERROR(log, std::move(e),
+ "SymbolFileDWARF::ParseSupportFiles failed to parse "
+ "line table prologue: {0}");
+ },
+ ctx, nullptr);
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "SymbolFileDWARF::ParseSupportFiles failed to parse line "
+ "table prologue: {0}");
+ return false;
+ }
+ return success;
+}
+
static llvm::Optional<std::string>
GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,
llvm::StringRef compile_dir, FileSpec::Style style) {
@@ -192,7 +213,7 @@ GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx,
// Otherwise ask for a relative path.
std::string rel_path;
- auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::Default;
+ auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::RawValue;
if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style))
return {};
return std::move(rel_path);
@@ -227,15 +248,12 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
return support_files;
}
-FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
- return GetGlobalPluginProperties()->GetSymLinkPaths();
-}
-
void SymbolFileDWARF::Initialize() {
LogChannelDWARF::Initialize();
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
DebuggerInitialize);
+ SymbolFileDWARFDebugMap::Initialize();
}
void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {
@@ -250,6 +268,7 @@ void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {
}
void SymbolFileDWARF::Terminate() {
+ SymbolFileDWARFDebugMap::Terminate();
PluginManager::UnregisterPlugin(CreateInstance);
LogChannelDWARF::Terminate();
}
@@ -333,10 +352,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
if (add_type) {
const bool assert_not_being_parsed = true;
Type *type = ResolveTypeUID(die, assert_not_being_parsed);
- if (type) {
- if (type_set.find(type) == type_set.end())
- type_set.insert(type);
- }
+ if (type)
+ type_set.insert(type);
}
}
@@ -366,15 +383,12 @@ void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
} else {
- DWARFDebugInfo *info = DebugInfo();
- if (info) {
- const size_t num_cus = info->GetNumUnits();
- for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
- dwarf_cu = info->GetUnitAtIndex(cu_idx);
- if (dwarf_cu) {
- GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
- }
- }
+ DWARFDebugInfo &info = DebugInfo();
+ const size_t num_cus = info.GetNumUnits();
+ for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
+ dwarf_cu = info.GetUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
}
}
@@ -418,9 +432,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
// contain the .o file index/ID
m_debug_map_module_wp(), m_debug_map_symfile(nullptr),
m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
- m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false),
- m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate),
- m_unique_ast_type_map() {}
+ m_fetched_external_modules(false),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
SymbolFileDWARF::~SymbolFileDWARF() {}
@@ -471,9 +484,9 @@ void SymbolFileDWARF::InitializeObject() {
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
- DebugNamesDWARFIndex::Create(
- *GetObjectFile()->GetModule(), debug_names,
- m_context.getOrLoadStrData(), DebugInfo());
+ DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
+ debug_names,
+ m_context.getOrLoadStrData(), *this);
if (index_or) {
m_index = std::move(*index_or);
return;
@@ -483,8 +496,8 @@ void SymbolFileDWARF::InitializeObject() {
}
}
- m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
- DebugInfo());
+ m_index =
+ std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@@ -573,15 +586,6 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
return abilities;
}
-const DWARFDataExtractor &
-SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
- DWARFDataSegment &data_segment) {
- llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] {
- this->LoadSectionData(sect_type, std::ref(data_segment.m_data));
- });
- return data_segment.m_data;
-}
-
void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
ModuleSP module_sp(m_objfile_sp->GetModule());
@@ -618,23 +622,14 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
return m_abbr.get();
}
-const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const {
- return m_abbr.get();
-}
-
-DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
- if (m_info == nullptr) {
+DWARFDebugInfo &SymbolFileDWARF::DebugInfo() {
+ llvm::call_once(m_info_once_flag, [&] {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
- if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
- m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
- }
- return m_info.get();
-}
-
-const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const {
- return m_info.get();
+ m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
+ });
+ return *m_info;
}
DWARFUnit *
@@ -642,15 +637,11 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
if (!comp_unit)
return nullptr;
- DWARFDebugInfo *info = DebugInfo();
- if (info) {
- // The compile unit ID is the index of the DWARF unit.
- DWARFUnit *dwarf_cu = info->GetUnitAtIndex(comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
- }
- return nullptr;
+ // The compile unit ID is the index of the DWARF unit.
+ DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
@@ -660,7 +651,7 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
static_cast<void *>(this));
if (m_context.getOrLoadRangesData().GetByteSize() > 0)
- m_ranges.reset(new DWARFDebugRanges());
+ m_ranges = std::make_unique<DWARFDebugRanges>();
if (m_ranges)
m_ranges->Extract(m_context);
@@ -668,6 +659,22 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
return m_ranges.get();
}
+/// Make an absolute path out of \p file_spec and remap it using the
+/// module's source remapping dictionary.
+static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu,
+ const ModuleSP &module_sp) {
+ if (!file_spec)
+ return;
+ // If we have a full path to the compile unit, we don't need to
+ // resolve the file. This can be expensive e.g. when the source
+ // files are NFS mounted.
+ file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
+
+ std::string remapped_file;
+ if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
+ file_spec.SetFile(remapped_file, FileSpec::Style::native);
+}
+
lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
CompUnitSP cu_sp;
CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
@@ -675,9 +682,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
// We already parsed this compile unit, had out a shared pointer to it
cu_sp = comp_unit->shared_from_this();
} else {
- if (&dwarf_cu.GetSymbolFileDWARF() != this) {
- return dwarf_cu.GetSymbolFileDWARF().ParseCompileUnit(dwarf_cu);
- } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) {
+ if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) {
// Let the debug map create the compile unit
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
dwarf_cu.SetUserData(cu_sp.get());
@@ -688,19 +693,9 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly();
if (cu_die) {
FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());
- if (cu_file_spec) {
- // If we have a full path to the compile unit, we don't need to
- // resolve the file. This can be expensive e.g. when the source
- // files are NFS mounted.
- cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
-
- std::string remapped_file;
- if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
- remapped_file))
- cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
- }
+ MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp);
- LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
+ LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF(
cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
bool is_optimized = dwarf_cu.GetNonSkeletonUnit().GetIsOptimized();
@@ -724,16 +719,13 @@ void SymbolFileDWARF::BuildCuTranslationTable() {
if (!m_lldb_cu_to_dwarf_unit.empty())
return;
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return;
-
- if (!info->ContainsTypeUnits()) {
+ DWARFDebugInfo &info = DebugInfo();
+ if (!info.ContainsTypeUnits()) {
// We can use a 1-to-1 mapping. No need to build a translation table.
return;
}
- for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) {
- if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info->GetUnitAtIndex(i))) {
+ for (uint32_t i = 0, num = info.GetNumUnits(); i < num; ++i) {
+ if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info.GetUnitAtIndex(i))) {
cu->SetID(m_lldb_cu_to_dwarf_unit.size());
m_lldb_cu_to_dwarf_unit.push_back(i);
}
@@ -750,23 +742,16 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
}
uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return 0;
BuildCuTranslationTable();
- return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits()
+ return m_lldb_cu_to_dwarf_unit.empty() ? DebugInfo().GetNumUnits()
: m_lldb_cu_to_dwarf_unit.size();
}
CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
ASSERT_MODULE_LOCK(this);
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return {};
-
if (llvm::Optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {
if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
- info->GetUnitAtIndex(*dwarf_idx)))
+ DebugInfo().GetUnitAtIndex(*dwarf_idx)))
return ParseCompileUnit(*dwarf_cu);
}
return {};
@@ -778,8 +763,7 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
if (!die.IsValid())
return nullptr;
- auto type_system_or_err =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
if (auto err = type_system_or_err.takeError()) {
LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
std::move(err), "Unable to parse function");
@@ -792,6 +776,13 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
}
+lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->LinkOSOFileAddress(this, file_addr);
+ return file_addr;
+}
+
bool SymbolFileDWARF::FixupAddress(Address &addr) {
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
@@ -804,11 +795,39 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
- return dwarf_cu->GetLanguageType();
+ return GetLanguage(*dwarf_cu);
else
return eLanguageTypeUnknown;
}
+XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+ if (!dwarf_cu)
+ return {};
+ const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly();
+ if (!cu_die)
+ return {};
+ const char *sdk = cu_die.GetAttributeValueAsString(DW_AT_APPLE_sdk, nullptr);
+ if (!sdk)
+ return {};
+ const char *sysroot =
+ cu_die.GetAttributeValueAsString(DW_AT_LLVM_sysroot, "");
+ // Register the sysroot path remapping with the module belonging to
+ // the CU as well as the one belonging to the symbol file. The two
+ // would be different if this is an OSO object and module is the
+ // corresponding debug map, in which case both should be updated.
+ ModuleSP module_sp = comp_unit.GetModule();
+ if (module_sp)
+ module_sp->RegisterXcodeSDK(sdk, sysroot);
+
+ ModuleSP local_module_sp = m_objfile_sp->GetModule();
+ if (local_module_sp && local_module_sp != module_sp)
+ local_module_sp->RegisterXcodeSDK(sdk, sysroot);
+
+ return {sdk};
+}
+
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::ParseFunctions");
@@ -863,8 +882,24 @@ bool SymbolFileDWARF::ForEachExternalModule(
bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
- if (!comp_unit.GetLineTable())
- ParseLineTable(comp_unit);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+ if (!dwarf_cu)
+ return false;
+
+ dw_offset_t offset = dwarf_cu->GetLineTableOffset();
+ if (offset == DW_INVALID_OFFSET)
+ return false;
+
+ llvm::DWARFDebugLine::Prologue prologue;
+ if (!ParseLLVMLineTablePrologue(m_context, prologue, offset,
+ dwarf_cu->GetOffset()))
+ return false;
+
+ comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
+ comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(),
+ dwarf_cu->GetCompilationDirectory().GetCString()));
+
return true;
}
@@ -898,12 +933,15 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM();
llvm::DWARFContext &ctx = m_context.GetAsLLVM();
llvm::DWARFDebugLine::Prologue prologue;
- llvm::Error error = prologue.parse(data, &line_table_offset, ctx);
- if (error) {
+ auto report = [](llvm::Error error) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
LLDB_LOG_ERROR(log, std::move(error),
"SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
"the line table prologue");
+ };
+ llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx);
+ if (error) {
+ report(std::move(error));
} else {
list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(),
prologue, tu.GetPathStyle());
@@ -961,9 +999,12 @@ bool SymbolFileDWARF::ParseImportedModules(
}
std::reverse(module.path.begin(), module.path.end());
if (const char *include_path = module_die.GetAttributeValueAsString(
- DW_AT_LLVM_include_path, nullptr))
- module.search_path = ConstString(include_path);
- if (const char *sysroot = module_die.GetAttributeValueAsString(
+ DW_AT_LLVM_include_path, nullptr)) {
+ FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
+ MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule());
+ module.search_path = ConstString(include_spec.GetPath());
+ }
+ if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
DW_AT_LLVM_sysroot, nullptr))
module.sysroot = ConstString(sysroot);
imported_modules.push_back(module);
@@ -981,18 +1022,13 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
if (!dwarf_cu)
return false;
- const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
- if (!dwarf_cu_die)
- return false;
-
- const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(
- DW_AT_stmt_list, DW_INVALID_OFFSET);
- if (cu_line_offset == DW_INVALID_OFFSET)
+ dw_offset_t offset = dwarf_cu->GetLineTableOffset();
+ if (offset == DW_INVALID_OFFSET)
return false;
llvm::DWARFDebugLine line;
- const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(
- m_context, line, cu_line_offset, dwarf_cu->GetOffset());
+ const llvm::DWARFDebugLine::LineTable *line_table =
+ ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset());
if (!line_table)
return false;
@@ -1000,20 +1036,23 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
// FIXME: Rather than parsing the whole line table and then copying it over
// into LLDB, we should explore using a callback to populate the line table
// while we parse to reduce memory usage.
- std::unique_ptr<LineTable> line_table_up =
- std::make_unique<LineTable>(&comp_unit);
- LineSequence *sequence = line_table_up->CreateLineSequenceContainer();
+ std::unique_ptr<LineSequence> sequence =
+ LineTable::CreateLineSequenceContainer();
+ std::vector<std::unique_ptr<LineSequence>> sequences;
for (auto &row : line_table->Rows) {
- line_table_up->AppendLineEntryToSequence(
- sequence, row.Address.Address, row.Line, row.Column, row.File,
+ LineTable::AppendLineEntryToSequence(
+ sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
row.EndSequence);
if (row.EndSequence) {
- line_table_up->InsertSequence(sequence);
- sequence = line_table_up->CreateLineSequenceContainer();
+ sequences.push_back(std::move(sequence));
+ sequence = LineTable::CreateLineSequenceContainer();
}
}
+ std::unique_ptr<LineTable> line_table_up =
+ std::make_unique<LineTable>(&comp_unit, std::move(sequences));
+
if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {
// We have an object file that has a line table with addresses that are not
// linked. We need to link the line table and convert the addresses that
@@ -1024,10 +1063,6 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
comp_unit.SetLineTable(line_table_up.release());
}
- comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
- comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(),
- dwarf_cu->GetCompilationDirectory().GetCString()));
-
return true;
}
@@ -1157,15 +1192,15 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
(name != nullptr || mangled_name != nullptr)) {
std::unique_ptr<Declaration> decl_up;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_up.reset(new Declaration(
+ decl_up = std::make_unique<Declaration>(
comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
+ decl_line, decl_column);
std::unique_ptr<Declaration> call_up;
if (call_file != 0 || call_line != 0 || call_column != 0)
- call_up.reset(new Declaration(
+ call_up = std::make_unique<Declaration>(
comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file),
- call_line, call_column));
+ call_line, call_column);
block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
call_up.get());
@@ -1289,7 +1324,7 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
// SymbolFileDWARF::GetDIE(). See comments inside the
// SymbolFileDWARF::GetDIE() for details.
if (DWARFDIE die = GetDIE(type_uid))
- return die.GetDecl();
+ return GetDecl(die);
return CompilerDecl();
}
@@ -1302,7 +1337,7 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
// SymbolFileDWARF::GetDIE(). See comments inside the
// SymbolFileDWARF::GetDIE() for details.
if (DWARFDIE die = GetDIE(type_uid))
- return die.GetDeclContext();
+ return GetDeclContext(die);
return CompilerDeclContext();
}
@@ -1313,7 +1348,7 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
// SymbolFileDWARF::GetDIE(). See comments inside the
// SymbolFileDWARF::GetDIE() for details.
if (DWARFDIE die = GetDIE(type_uid))
- return die.GetContainingDeclContext();
+ return GetContainingDeclContext(die);
return CompilerDeclContext();
}
@@ -1394,8 +1429,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType(
}
TypeSystem *type_system = compiler_type.GetTypeSystem();
- ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ TypeSystemClang *clang_type_system =
+ llvm::dyn_cast_or_null<TypeSystemClang>(type_system);
if (!clang_type_system)
return false;
DWARFASTParserClang *ast_parser =
@@ -1406,8 +1441,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType(
bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ TypeSystemClang *clang_type_system =
+ llvm::dyn_cast_or_null<TypeSystemClang>(compiler_type.GetTypeSystem());
if (clang_type_system) {
DWARFASTParserClang *ast_parser =
static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
@@ -1444,8 +1479,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
type->GetName().AsCString());
assert(compiler_type);
- DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
- if (dwarf_ast)
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
}
return false;
@@ -1473,20 +1507,25 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
CompileUnit *
SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {
+ if (dwarf_cu.IsDWOUnit()) {
+ DWARFCompileUnit *non_dwo_cu =
+ static_cast<DWARFCompileUnit *>(dwarf_cu.GetUserData());
+ assert(non_dwo_cu);
+ return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(
+ *non_dwo_cu);
+ }
// Check if the symbol vendor already knows about this compile unit?
if (dwarf_cu.GetUserData() == nullptr) {
// The symbol vendor doesn't know about this compile unit, we need to parse
// and add it to the symbol vendor object.
return ParseCompileUnit(dwarf_cu).get();
}
- return (CompileUnit *)dwarf_cu.GetUserData();
+ return static_cast<CompileUnit *>(dwarf_cu.GetUserData());
}
-size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
- DIEArray &method_die_offsets) {
- method_die_offsets.clear();
- m_index->GetObjCMethods(class_name, method_die_offsets);
- return method_die_offsets.size();
+void SymbolFileDWARF::GetObjCMethods(
+ ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) {
+ m_index->GetObjCMethods(class_name, callback);
}
bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
@@ -1522,17 +1561,15 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) {
DWARFDIE
SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
if (die_ref.dwo_num()) {
- return DebugInfo()
- ->GetUnitAtIndex(*die_ref.dwo_num())
- ->GetDwoSymbolFile()
- ->GetDIE(die_ref);
+ SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff
+ ? m_dwp_symfile.get()
+ : this->DebugInfo()
+ .GetUnitAtIndex(*die_ref.dwo_num())
+ ->GetDwoSymbolFile();
+ return dwarf->DebugInfo().GetDIE(die_ref);
}
- DWARFDebugInfo *debug_info = DebugInfo();
- if (debug_info)
- return debug_info->GetDIE(die_ref);
- else
- return DWARFDIE();
+ return DebugInfo().GetDIE(die_ref);
}
/// Return the DW_AT_(GNU_)dwo_name.
@@ -1569,7 +1606,7 @@ llvm::Optional<uint64_t> SymbolFileDWARF::GetDWOId() {
return {};
}
-std::unique_ptr<SymbolFileDWARFDwo>
+std::shared_ptr<SymbolFileDWARFDwo>
SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {
// If this is a Darwin-style debug map (non-.dSYM) symbol file,
@@ -1589,14 +1626,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (!dwo_name)
return nullptr;
- SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
- if (dwp_symfile) {
- uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die);
- std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
- dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id);
- if (dwo_symfile)
- return dwo_symfile;
- }
+ if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
+ return dwp_sp;
FileSpec dwo_file(dwo_name);
FileSystem::Instance().Resolve(dwo_file);
@@ -1624,20 +1655,21 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (dwo_obj_file == nullptr)
return nullptr;
- return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
+ return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file,
+ dwarf_cu->GetID());
}
void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
if (m_fetched_external_modules)
return;
m_fetched_external_modules = true;
- DWARFDebugInfo *debug_info = DebugInfo();
+ DWARFDebugInfo &debug_info = DebugInfo();
// Follow DWO skeleton unit breadcrumbs.
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
auto *dwarf_cu =
- llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(cu_idx));
+ llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(cu_idx));
if (!dwarf_cu)
continue;
@@ -1731,7 +1763,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
if (!m_global_aranges_up) {
- m_global_aranges_up.reset(new GlobalVariableMap());
+ m_global_aranges_up = std::make_unique<GlobalVariableMap>();
ModuleSP module_sp = GetObjectFile()->GetModule();
if (module_sp) {
@@ -1773,6 +1805,32 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
return *m_global_aranges_up;
}
+void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,
+ bool lookup_block,
+ SymbolContext &sc) {
+ assert(sc.comp_unit);
+ DWARFUnit &cu = GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit();
+ DWARFDIE function_die = cu.LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
+ if (sc.function == nullptr)
+ sc.function = ParseFunction(*sc.comp_unit, function_die);
+
+ if (sc.function && lookup_block)
+ block_die = function_die.LookupDeepestBlock(file_vm_addr);
+ }
+
+ if (!sc.function || ! lookup_block)
+ return;
+
+ Block &block = sc.function->GetBlock(true);
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else
+ sc.block = block.FindBlockByID(function_die.GetID());
+}
+
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
@@ -1791,123 +1849,99 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
eSymbolContextLineEntry | eSymbolContextVariable)) {
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
- DWARFDebugInfo *debug_info = DebugInfo();
- if (debug_info) {
- llvm::Expected<DWARFDebugAranges &> aranges =
- debug_info->GetCompileUnitAranges();
- if (!aranges) {
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- LLDB_LOG_ERROR(log, aranges.takeError(),
- "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
- "aranges. {0}");
- return 0;
- }
+ DWARFDebugInfo &debug_info = DebugInfo();
+ llvm::Expected<DWARFDebugAranges &> aranges =
+ debug_info.GetCompileUnitAranges();
+ if (!aranges) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, aranges.takeError(),
+ "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
+ "aranges. {0}");
+ return 0;
+ }
- const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
- if (cu_offset == DW_INVALID_OFFSET) {
- // Global variables are not in the compile unit address ranges. The
- // only way to currently find global variables is to iterate over the
- // .debug_pubnames or the __apple_names table and find all items in
- // there that point to DW_TAG_variable DIEs and then find the address
- // that matches.
- if (resolve_scope & eSymbolContextVariable) {
- GlobalVariableMap &map = GetGlobalAranges();
- const GlobalVariableMap::Entry *entry =
- map.FindEntryThatContains(file_vm_addr);
- if (entry && entry->data) {
- Variable *variable = entry->data;
- SymbolContextScope *scc = variable->GetSymbolContextScope();
- if (scc) {
- scc->CalculateSymbolContext(&sc);
- sc.variable = variable;
- }
- return sc.GetResolvedMask();
+ const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
+ if (cu_offset == DW_INVALID_OFFSET) {
+ // Global variables are not in the compile unit address ranges. The only
+ // way to currently find global variables is to iterate over the
+ // .debug_pubnames or the __apple_names table and find all items in there
+ // that point to DW_TAG_variable DIEs and then find the address that
+ // matches.
+ if (resolve_scope & eSymbolContextVariable) {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry =
+ map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data) {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc) {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
}
+ return sc.GetResolvedMask();
}
- } else {
- uint32_t cu_idx = DW_INVALID_INDEX;
- if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
- debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo,
- cu_offset, &cu_idx))) {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
- if (sc.comp_unit) {
- resolved |= eSymbolContextCompUnit;
-
- bool force_check_line_table = false;
- if (resolve_scope &
- (eSymbolContextFunction | eSymbolContextBlock)) {
- DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die) {
- sc.function =
- sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
- if (sc.function == nullptr)
- sc.function = ParseFunction(*sc.comp_unit, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die = function_die.LookupDeepestBlock(file_vm_addr);
- } else {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
- force_check_line_table = true;
- }
-
- if (sc.function != nullptr) {
- resolved |= eSymbolContextFunction;
-
- if (resolve_scope & eSymbolContextBlock) {
- Block &block = sc.function->GetBlock(true);
-
- if (block_die)
- sc.block = block.FindBlockByID(block_die.GetID());
- else
- sc.block = block.FindBlockByID(function_die.GetID());
- if (sc.block)
- resolved |= eSymbolContextBlock;
- }
- }
+ }
+ } else {
+ uint32_t cu_idx = DW_INVALID_INDEX;
+ if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
+ debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo, cu_offset,
+ &cu_idx))) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
+ if (sc.comp_unit) {
+ resolved |= eSymbolContextCompUnit;
+
+ bool force_check_line_table = false;
+ if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
+ ResolveFunctionAndBlock(file_vm_addr,
+ resolve_scope & eSymbolContextBlock, sc);
+ if (sc.function)
+ resolved |= eSymbolContextFunction;
+ else {
+ // We might have had a compile unit that had discontiguous address
+ // ranges where the gaps are symbols that don't have any debug
+ // info. Discontiguous compile unit address ranges should only
+ // happen when there aren't other functions from other compile
+ // units in these gaps. This helps keep the size of the aranges
+ // down.
+ force_check_line_table = true;
}
+ if (sc.block)
+ resolved |= eSymbolContextBlock;
+ }
- if ((resolve_scope & eSymbolContextLineEntry) ||
- force_check_line_table) {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != nullptr) {
- // And address that makes it into this function should be in
- // terms of this debug file if there is no debug map, or it
- // will be an address in the .o file which needs to be fixed up
- // to be in terms of the debug map executable. Either way,
- // calling FixupAddress() will work for us.
- Address exe_so_addr(so_addr);
- if (FixupAddress(exe_so_addr)) {
- if (line_table->FindLineEntryByAddress(exe_so_addr,
- sc.line_entry)) {
- resolved |= eSymbolContextLineEntry;
- }
+ if ((resolve_scope & eSymbolContextLineEntry) ||
+ force_check_line_table) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table != nullptr) {
+ // And address that makes it into this function should be in terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in
+ // terms of the debug map executable. Either way, calling
+ // FixupAddress() will work for us.
+ Address exe_so_addr(so_addr);
+ if (FixupAddress(exe_so_addr)) {
+ if (line_table->FindLineEntryByAddress(exe_so_addr,
+ sc.line_entry)) {
+ resolved |= eSymbolContextLineEntry;
}
}
}
+ }
- if (force_check_line_table &&
- !(resolved & eSymbolContextLineEntry)) {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have any
- // debug info. Discontiguous compile unit address ranges should
- // only happen when there aren't other functions from other
- // compile units in these gaps. This helps keep the size of the
- // aranges down.
- sc.comp_unit = nullptr;
- resolved &= ~eSymbolContextCompUnit;
- }
- } else {
- GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8x: compile unit %u failed to create a valid "
- "lldb_private::CompileUnit class.",
- cu_offset, cu_idx);
+ if (force_check_line_table && !(resolved & eSymbolContextLineEntry)) {
+ // We might have had a compile unit that had discontiguous address
+ // ranges where the gaps are symbols that don't have any debug info.
+ // Discontiguous compile unit address ranges should only happen when
+ // there aren't other functions from other compile units in these
+ // gaps. This helps keep the size of the aranges down.
+ sc.comp_unit = nullptr;
+ resolved &= ~eSymbolContextCompUnit;
}
+ } else {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8x: compile unit %u failed to create a valid "
+ "lldb_private::CompileUnit class.",
+ cu_offset, cu_idx);
}
}
}
@@ -1969,30 +2003,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
const lldb::addr_t file_vm_addr =
sc.line_entry.range.GetBaseAddress().GetFileAddress();
if (file_vm_addr != LLDB_INVALID_ADDRESS) {
- DWARFDIE function_die =
- GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die) {
- sc.function =
- sc.comp_unit->FindFunctionByUID(function_die.GetID())
- .get();
- if (sc.function == nullptr)
- sc.function =
- ParseFunction(*sc.comp_unit, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die =
- function_die.LookupDeepestBlock(file_vm_addr);
- }
-
- if (sc.function != nullptr) {
- Block &block = sc.function->GetBlock(true);
-
- if (block_die)
- sc.block = block.FindBlockByID(block_die.GetID());
- else if (function_die)
- sc.block = block.FindBlockByID(function_die.GetID());
- }
+ ResolveFunctionAndBlock(
+ file_vm_addr, resolve_scope & eSymbolContextBlock, sc);
}
}
@@ -2035,15 +2047,15 @@ std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const {
}
bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
- const lldb_private::CompilerDeclContext *decl_ctx) {
- if (decl_ctx == nullptr || !decl_ctx->IsValid()) {
+ const lldb_private::CompilerDeclContext &decl_ctx) {
+ if (!decl_ctx.IsValid()) {
// Invalid namespace decl which means we aren't matching only things in
// this symbol file, so return true to indicate it matches this symbol
// file.
return true;
}
- TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();
auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
if (auto err = type_system_or_err.takeError()) {
@@ -2067,7 +2079,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
}
void SymbolFileDWARF::FindGlobalVariables(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -2077,16 +2089,12 @@ void SymbolFileDWARF::FindGlobalVariables(
log,
"SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
"parent_decl_ctx=%p, max_matches=%u, variables)",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
max_matches);
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return;
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return;
-
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2098,69 +2106,46 @@ void SymbolFileDWARF::FindGlobalVariables(
context, basename))
basename = name.GetStringRef();
- DIEArray die_offsets;
- m_index->GetGlobalVariables(ConstString(basename), die_offsets);
- const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- SymbolContext sc;
- sc.module_sp = m_objfile_sp->GetModule();
- assert(sc.module_sp);
-
- // Loop invariant: Variables up to this index have been checked for context
- // matches.
- uint32_t pruned_idx = original_size;
+ // Loop invariant: Variables up to this index have been checked for context
+ // matches.
+ uint32_t pruned_idx = original_size;
- bool done = false;
- for (size_t i = 0; i < num_die_matches && !done; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
-
- if (die) {
- switch (die.Tag()) {
- default:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_try_block:
- case DW_TAG_catch_block:
- break;
+ SymbolContext sc;
+ m_index->GetGlobalVariables(ConstString(basename), [&](DWARFDIE die) {
+ if (!sc.module_sp)
+ sc.module_sp = m_objfile_sp->GetModule();
+ assert(sc.module_sp);
- case DW_TAG_variable: {
- auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
- if (!dwarf_cu)
- continue;
- sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
-
- if (parent_decl_ctx) {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast) {
- CompilerDeclContext actual_parent_decl_ctx =
- dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
- if (!actual_parent_decl_ctx ||
- actual_parent_decl_ctx != *parent_decl_ctx)
- continue;
- }
- }
+ if (die.Tag() != DW_TAG_variable)
+ return true;
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
- &variables);
- while (pruned_idx < variables.GetSize()) {
- VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
- if (name_is_mangled ||
- var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
- ++pruned_idx;
- else
- variables.RemoveVariableAtIndex(pruned_idx);
- }
+ auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+ if (!dwarf_cu)
+ return true;
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
- if (variables.GetSize() - original_size >= max_matches)
- done = true;
- } break;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
+ if (parent_decl_ctx) {
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
+ CompilerDeclContext actual_parent_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ if (!actual_parent_decl_ctx ||
+ actual_parent_decl_ctx != parent_decl_ctx)
+ return true;
}
}
- }
+
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
+ while (pruned_idx < variables.GetSize()) {
+ VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
+ if (name_is_mangled ||
+ var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
+ ++pruned_idx;
+ else
+ variables.RemoveVariableAtIndex(pruned_idx);
+ }
+
+ return variables.GetSize() - original_size < max_matches;
+ });
// Return the number of variable that were appended to the list
const uint32_t num_matches = variables.GetSize() - original_size;
@@ -2169,7 +2154,7 @@ void SymbolFileDWARF::FindGlobalVariables(
log,
"SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
"parent_decl_ctx=%p, max_matches=%u, variables) => %u",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
max_matches, num_matches);
}
}
@@ -2188,41 +2173,24 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
regex.GetText().str().c_str(), max_matches);
}
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return;
-
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
- DIEArray die_offsets;
- m_index->GetGlobalVariables(regex, die_offsets);
-
SymbolContext sc;
- sc.module_sp = m_objfile_sp->GetModule();
- assert(sc.module_sp);
-
- const size_t num_matches = die_offsets.size();
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
+ m_index->GetGlobalVariables(regex, [&](DWARFDIE die) {
+ if (!sc.module_sp)
+ sc.module_sp = m_objfile_sp->GetModule();
+ assert(sc.module_sp);
- if (die) {
- DWARFCompileUnit *dwarf_cu =
- llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
- if (!dwarf_cu)
- continue;
- sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
+ DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+ if (!dwarf_cu)
+ return true;
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
- if (variables.GetSize() - original_size >= max_matches)
- break;
- } else
- m_index->ReportInvalidDIERef(die_ref, regex.GetText());
- }
- }
+ return variables.GetSize() - original_size < max_matches;
+ });
}
bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
@@ -2281,28 +2249,26 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
return false;
}
-bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
+bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx,
const DWARFDIE &die) {
// If we have no parent decl context to match this DIE matches, and if the
// parent decl context isn't valid, we aren't trying to look for any
// particular decl context so any die matches.
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ if (!decl_ctx.IsValid())
return true;
if (die) {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast) {
- CompilerDeclContext actual_decl_ctx =
- dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
- if (actual_decl_ctx)
- return decl_ctx->IsContainedInLookup(actual_decl_ctx);
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
+ if (CompilerDeclContext actual_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
+ return decl_ctx.IsContainedInLookup(actual_decl_ctx);
}
}
return false;
}
void SymbolFileDWARF::FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
+ const CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask,
bool include_inlines,
SymbolContextList &sc_list) {
@@ -2337,17 +2303,13 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
const uint32_t original_size = sc_list.GetSize();
llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
- DIEArray offsets;
- CompilerDeclContext empty_decl_ctx;
- if (!parent_decl_ctx)
- parent_decl_ctx = &empty_decl_ctx;
-
- std::vector<DWARFDIE> dies;
- m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies);
- for (const DWARFDIE &die : dies) {
- if (resolved_dies.insert(die.GetDIE()).second)
- ResolveFunction(die, include_inlines, sc_list);
- }
+
+ m_index->GetFunctions(name, *this, parent_decl_ctx, name_type_mask,
+ [&](DWARFDIE die) {
+ if (resolved_dies.insert(die.GetDIE()).second)
+ ResolveFunction(die, include_inlines, sc_list);
+ return true;
+ });
// Return the number of variable that were appended to the list
const uint32_t num_matches = sc_list.GetSize() - original_size;
@@ -2378,35 +2340,21 @@ void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
regex.GetText().str().c_str());
}
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return;
-
- DIEArray offsets;
- m_index->GetFunctions(regex, offsets);
-
llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
- for (DIERef ref : offsets) {
- DWARFDIE die = info->GetDIE(ref);
- if (!die) {
- m_index->ReportInvalidDIERef(ref, regex.GetText());
- continue;
- }
+ m_index->GetFunctions(regex, [&](DWARFDIE die) {
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
- }
+ return true;
+ });
}
void SymbolFileDWARF::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) {
- DWARFDebugInfo *info = DebugInfo();
- uint32_t num_comp_units = 0;
- if (info)
- num_comp_units = info->GetNumUnits();
-
+ DWARFDebugInfo &info = DebugInfo();
+ uint32_t num_comp_units = info.GetNumUnits();
for (uint32_t i = 0; i < num_comp_units; i++) {
- DWARFUnit *cu = info->GetUnitAtIndex(i);
+ DWARFUnit *cu = info.GetUnitAtIndex(i);
if (cu == nullptr)
continue;
@@ -2415,15 +2363,15 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
}
- for (lldb::user_id_t uid :
+ for (DIERef die_ref :
m_function_scope_qualified_name_map.lookup(scope_qualified_name)) {
- DWARFDIE die = GetDIE(uid);
+ DWARFDIE die = GetDIE(die_ref);
mangled_names.push_back(ConstString(die.GetMangledName()));
}
}
void SymbolFileDWARF::FindTypes(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
@@ -2432,10 +2380,6 @@ void SymbolFileDWARF::FindTypes(
if (!searched_symbol_files.insert(this).second)
return;
- DWARFDebugInfo *info = DebugInfo();
- if (!info)
- return;
-
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2444,8 +2388,8 @@ void SymbolFileDWARF::FindTypes(
log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
"%p (\"%s\"), max_matches=%u, type_list)",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches);
+ name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
+ parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches);
else
GetObjectFile()->GetModule()->LogMessage(
log,
@@ -2457,38 +2401,28 @@ void SymbolFileDWARF::FindTypes(
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return;
- DIEArray die_offsets;
- m_index->GetTypes(name, die_offsets);
- const size_t num_die_matches = die_offsets.size();
+ m_index->GetTypes(name, [&](DWARFDIE die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ return true; // The containing decl contexts don't match
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- Type *matching_type = ResolveType(die, true, true);
- if (matching_type) {
- // We found a type pointer, now find the shared pointer form our type
- // list
- types.InsertUnique(matching_type->shared_from_this());
- if (types.GetSize() >= max_matches)
- break;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
- }
+ Type *matching_type = ResolveType(die, true, true);
+ if (!matching_type)
+ return true;
+
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ return types.GetSize() < max_matches;
+ });
// Next search through the reachable Clang modules. This only applies for
// DWARF objects compiled with -gmodules that haven't been processed by
// dsymutil.
- if (num_die_matches < max_matches) {
+ if (types.GetSize() < max_matches) {
UpdateExternalModuleListIfNeeded();
for (const auto &pair : m_external_type_modules)
- if (ModuleSP external_module_sp = pair.second)
+ if (ModuleSP external_module_sp = pair.second)
if (SymbolFile *sym_file = external_module_sp->GetSymbolFile())
sym_file->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
@@ -2500,8 +2434,8 @@ void SymbolFileDWARF::FindTypes(
log,
"SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
"= %p (\"%s\"), max_matches=%u, type_list) => %u",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches,
+ name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
+ parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches,
types.GetSize());
} else {
GetObjectFile()->GetModule()->LogMessage(
@@ -2529,32 +2463,22 @@ void SymbolFileDWARF::FindTypes(
if (!name)
return;
- DIEArray die_offsets;
- m_index->GetTypes(name, die_offsets);
- const size_t num_die_matches = die_offsets.size();
-
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
-
- if (!die) {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- continue;
- }
- if (!languages[die.GetCU()->GetLanguageType()])
- continue;
+ m_index->GetTypes(name, [&](DWARFDIE die) {
+ if (!languages[GetLanguage(*die.GetCU())])
+ return true;
llvm::SmallVector<CompilerContext, 4> die_context;
die.GetDeclContext(die_context);
if (!contextMatches(die_context, pattern))
- continue;
+ return true;
if (Type *matching_type = ResolveType(die, true, true)) {
// We found a type pointer, now find the shared pointer form our type
// list.
types.InsertUnique(matching_type->shared_from_this());
}
- }
+ return true;
+ });
// Next search through the reachable Clang modules. This only applies for
// DWARF objects compiled with -gmodules that haven't been processed by
@@ -2569,7 +2493,7 @@ void SymbolFileDWARF::FindTypes(
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx) {
+ const CompilerDeclContext &parent_decl_ctx) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -2584,32 +2508,18 @@ SymbolFileDWARF::FindNamespace(ConstString name,
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return namespace_decl_ctx;
- DWARFDebugInfo *info = DebugInfo();
- if (info) {
- DIEArray die_offsets;
- m_index->GetNamespaces(name, die_offsets);
- const size_t num_matches = die_offsets.size();
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
-
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast) {
- namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
- if (namespace_decl_ctx)
- break;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
- }
- }
- }
+ m_index->GetNamespaces(name, [&](DWARFDIE die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ return true; // The containing decl contexts don't match
+
+ DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());
+ if (!dwarf_ast)
+ return true;
+
+ namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
+ return !namespace_decl_ctx.IsValid();
+ });
+
if (log && namespace_decl_ctx) {
GetObjectFile()->GetModule()->LogMessage(
log,
@@ -2735,10 +2645,10 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
else {
- DWARFDebugInfo *debug_info = DebugInfo();
+ DWARFDebugInfo &debug_info = DebugInfo();
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
- DWARFUnit *dwarf_cu = debug_info->GetUnitAtIndex(cu_idx);
+ DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx);
if (dwarf_cu != cu &&
dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
@@ -2763,17 +2673,8 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
return type_sp;
- DIEArray die_offsets;
- m_index->GetCompleteObjCClass(type_name, must_be_implementation, die_offsets);
-
- const size_t num_matches = die_offsets.size();
-
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE(die_ref);
-
- if (type_die) {
+ m_index->GetCompleteObjCClass(
+ type_name, must_be_implementation, [&](DWARFDIE type_die) {
bool try_resolving_type = false;
// Don't try and resolve the DIE we are looking for with the DIE
@@ -2788,35 +2689,32 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
break;
}
}
+ if (!try_resolving_type)
+ return true;
- if (try_resolving_type) {
- if (must_be_implementation &&
- type_die.Supports_DW_AT_APPLE_objc_complete_type())
- try_resolving_type = type_die.GetAttributeValueAsUnsigned(
- DW_AT_APPLE_objc_complete_type, 0);
-
- if (try_resolving_type) {
- Type *resolved_type = ResolveType(type_die, false, true);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
- DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
- " (cu 0x%8.8" PRIx64 ")\n",
- die.GetID(),
- m_objfile_sp->GetFileSpec().GetFilename().AsCString(
- "<Unknown>"),
- type_die.GetID(), type_cu->GetID());
-
- if (die)
- GetDIEToType()[die.GetDIE()] = resolved_type;
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
- }
- }
- }
+ if (must_be_implementation &&
+ type_die.Supports_DW_AT_APPLE_objc_complete_type())
+ try_resolving_type = type_die.GetAttributeValueAsUnsigned(
+ DW_AT_APPLE_objc_complete_type, 0);
+ if (!try_resolving_type)
+ return true;
+
+ Type *resolved_type = ResolveType(type_die, false, true);
+ if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
+ return true;
+
+ DEBUG_PRINTF(
+ "resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
+ " (cu 0x%8.8" PRIx64 ")\n",
+ die.GetID(),
+ m_objfile_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"),
+ type_die.GetID(), type_cu->GetID());
+
+ if (die)
+ GetDIEToType()[die.GetDIE()] = resolved_type;
+ type_sp = resolved_type->shared_from_this();
+ return false;
+ });
return type_sp;
}
@@ -2930,10 +2828,6 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
dwarf_decl_ctx.GetQualifiedName());
}
- DIEArray die_offsets;
- m_index->GetTypes(dwarf_decl_ctx, die_offsets);
- const size_t num_matches = die_offsets.size();
-
// Get the type system that we are looking to find a type for. We will
// use this to ensure any matches we find are in a language that this
// type system supports
@@ -2950,91 +2844,85 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
type_system = &type_system_or_err.get();
}
}
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE(die_ref);
-
- if (type_die) {
- // Make sure type_die's langauge matches the type system we are
- // looking for. We don't want to find a "Foo" type from Java if we
- // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
- if (type_system &&
- !type_system->SupportsLanguage(type_die.GetLanguage()))
- continue;
- bool try_resolving_type = false;
-
- // Don't try and resolve the DIE we are looking for with the DIE
- // itself!
- const dw_tag_t type_tag = type_die.Tag();
- // Make sure the tags match
- if (type_tag == tag) {
- // The tags match, lets try resolving this type
- try_resolving_type = true;
- } else {
- // The tags don't match, but we need to watch our for a forward
- // declaration for a struct and ("struct foo") ends up being a
- // class ("class foo { ... };") or vice versa.
- switch (type_tag) {
- case DW_TAG_class_type:
- // We had a "class foo", see if we ended up with a "struct foo
- // { ... };"
- try_resolving_type = (tag == DW_TAG_structure_type);
- break;
- case DW_TAG_structure_type:
- // We had a "struct foo", see if we ended up with a "class foo
- // { ... };"
- try_resolving_type = (tag == DW_TAG_class_type);
- break;
- default:
- // Tags don't match, don't event try to resolve using this type
- // whose name matches....
- break;
- }
- }
- if (try_resolving_type) {
- DWARFDeclContext type_dwarf_decl_ctx;
- type_die.GetDWARFDeclContext(type_dwarf_decl_ctx);
-
- if (log) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') trying die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
- type_dwarf_decl_ctx.GetQualifiedName());
- }
+ m_index->GetTypes(dwarf_decl_ctx, [&](DWARFDIE type_die) {
+ // Make sure type_die's langauge matches the type system we are
+ // looking for. We don't want to find a "Foo" type from Java if we
+ // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
+ if (type_system &&
+ !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
+ return true;
+ bool try_resolving_type = false;
- // Make sure the decl contexts match all the way up
- if (dwarf_decl_ctx == type_dwarf_decl_ctx) {
- Type *resolved_type = ResolveType(type_die, false);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- } else {
- if (log) {
- std::string qualified_name;
- type_die.GetQualifiedName(qualified_name);
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') ignoring die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
- qualified_name.c_str());
- }
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, type_name.GetStringRef());
+ // Don't try and resolve the DIE we are looking for with the DIE
+ // itself!
+ const dw_tag_t type_tag = type_die.Tag();
+ // Make sure the tags match
+ if (type_tag == tag) {
+ // The tags match, lets try resolving this type
+ try_resolving_type = true;
+ } else {
+ // The tags don't match, but we need to watch our for a forward
+ // declaration for a struct and ("struct foo") ends up being a
+ // class ("class foo { ... };") or vice versa.
+ switch (type_tag) {
+ case DW_TAG_class_type:
+ // We had a "class foo", see if we ended up with a "struct foo
+ // { ... };"
+ try_resolving_type = (tag == DW_TAG_structure_type);
+ break;
+ case DW_TAG_structure_type:
+ // We had a "struct foo", see if we ended up with a "class foo
+ // { ... };"
+ try_resolving_type = (tag == DW_TAG_class_type);
+ break;
+ default:
+ // Tags don't match, don't event try to resolve using this type
+ // whose name matches....
+ break;
}
}
- }
+
+ if (!try_resolving_type) {
+ if (log) {
+ std::string qualified_name;
+ type_die.GetQualifiedName(qualified_name);
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') ignoring die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ qualified_name.c_str());
+ }
+ return true;
+ }
+
+ DWARFDeclContext type_dwarf_decl_ctx = GetDWARFDeclContext(type_die);
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') trying die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ type_dwarf_decl_ctx.GetQualifiedName());
+ }
+
+ // Make sure the decl contexts match all the way up
+ if (dwarf_decl_ctx != type_dwarf_decl_ctx)
+ return true;
+
+ Type *resolved_type = ResolveType(type_die, false);
+ if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
+ return true;
+
+ type_sp = resolved_type->shared_from_this();
+ return false;
+ });
}
}
return type_sp;
@@ -3045,8 +2933,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
if (!die)
return {};
- auto type_system_or_err =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
if (auto err = type_system_or_err.takeError()) {
LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
std::move(err), "Unable to parse type");
@@ -3067,7 +2954,7 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
.AsCString(""));
if (scope_qualified_name.size()) {
m_function_scope_qualified_name_map[scope_qualified_name].insert(
- die.GetID());
+ *die.GetDIERef());
}
}
}
@@ -3124,7 +3011,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
size_t functions_added = 0;
const dw_offset_t function_die_offset = func.GetID();
- DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset);
+ DWARFDIE function_die =
+ dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
if (function_die) {
ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die,
LLDB_INVALID_ADDRESS, 0);
@@ -3152,10 +3040,6 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (sc.comp_unit != nullptr) {
- DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
-
if (sc.function) {
DWARFDIE function_die = GetDIE(sc.function->GetID());
@@ -3170,7 +3054,7 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
return num_variables;
}
} else if (sc.comp_unit) {
- DWARFUnit *dwarf_cu = info->GetUnitAtIndex(sc.comp_unit->GetID());
+ DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(sc.comp_unit->GetID());
if (dwarf_cu == nullptr)
return 0;
@@ -3182,25 +3066,16 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
variables = std::make_shared<VariableList>();
sc.comp_unit->SetVariableList(variables);
- DIEArray die_offsets;
- m_index->GetGlobalVariables(dwarf_cu->GetNonSkeletonUnit(),
- die_offsets);
- const size_t num_matches = die_offsets.size();
- if (num_matches) {
- for (size_t i = 0; i < num_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
- if (die) {
+ m_index->GetGlobalVariables(
+ dwarf_cu->GetNonSkeletonUnit(), [&](DWARFDIE die) {
VariableSP var_sp(
ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
if (var_sp) {
variables->AddVariableIfUnique(var_sp);
++vars_added;
}
- } else
- m_index->ReportInvalidDIERef(die_ref, "");
- }
- }
+ return true;
+ });
}
return vars_added;
}
@@ -3412,12 +3287,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
// declaration context.
if ((parent_tag == DW_TAG_compile_unit ||
parent_tag == DW_TAG_partial_unit) &&
- Language::LanguageIsCPlusPlus(die.GetLanguage())) {
- DWARFDeclContext decl_ctx;
-
- die.GetDWARFDeclContext(decl_ctx);
- mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
- }
+ Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
+ mangled = GetDWARFDeclContext(die)
+ .GetQualifiedNameAsConstString()
+ .GetCString();
}
if (tag == DW_TAG_formal_parameter)
@@ -3524,7 +3397,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
}
} else {
- if (location_is_const_value_data)
+ if (location_is_const_value_data &&
+ die.GetDIE()->IsGlobalOrStaticScopeVariable())
scope = eValueTypeVariableStatic;
else {
scope = eValueTypeVariableLocal;
@@ -3603,7 +3477,7 @@ SymbolFileDWARF::FindBlockContainingSpecification(
// Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref),
+ return FindBlockContainingSpecification(DebugInfo().GetDIE(func_die_ref),
spec_block_die_offset);
}
@@ -3762,7 +3636,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
CallSiteParameterArray parameters;
for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid();
child = child.GetSibling()) {
- if (child.Tag() != DW_TAG_call_site_parameter)
+ if (child.Tag() != DW_TAG_call_site_parameter &&
+ child.Tag() != DW_TAG_GNU_call_site_parameter)
continue;
llvm::Optional<DWARFExpression> LocationInCallee;
@@ -3792,7 +3667,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
if (attr == DW_AT_location)
LocationInCallee = parse_simple_location(i);
- if (attr == DW_AT_call_value)
+ if (attr == DW_AT_call_value || attr == DW_AT_GNU_call_site_value)
LocationInCaller = parse_simple_location(i);
}
@@ -3805,12 +3680,13 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
}
/// Collect call graph edges present in a function DIE.
-static std::vector<std::unique_ptr<lldb_private::CallEdge>>
-CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
+std::vector<std::unique_ptr<lldb_private::CallEdge>>
+SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
// Check if the function has a supported call site-related attribute.
// TODO: In the future it may be worthwhile to support call_all_source_calls.
- uint64_t has_call_edges =
- function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0);
+ bool has_call_edges =
+ function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0) ||
+ function_die.GetAttributeValueAsUnsigned(DW_AT_GNU_all_call_sites, 0);
if (!has_call_edges)
return {};
@@ -3826,15 +3702,22 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
std::vector<std::unique_ptr<CallEdge>> call_edges;
for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid();
child = child.GetSibling()) {
- if (child.Tag() != DW_TAG_call_site)
+ if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
continue;
llvm::Optional<DWARFDIE> call_origin;
llvm::Optional<DWARFExpression> call_target;
addr_t return_pc = LLDB_INVALID_ADDRESS;
+ addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
+ addr_t low_pc = LLDB_INVALID_ADDRESS;
+ bool tail_call = false;
+ // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by
+ // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'.
+ // So do not inherit attributes from DW_AT_abstract_origin.
DWARFAttributes attributes;
- const size_t num_attributes = child.GetAttributes(attributes);
+ const size_t num_attributes =
+ child.GetAttributes(attributes, DWARFDIE::Recurse::no);
for (size_t i = 0; i < num_attributes; ++i) {
DWARFFormValue form_value;
if (!attributes.ExtractFormValueAtIndex(i, form_value)) {
@@ -3844,8 +3727,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attr == DW_AT_call_tail_call || attr == DW_AT_GNU_tail_call)
+ tail_call = form_value.Boolean();
+
// Extract DW_AT_call_origin (the call target's DIE).
- if (attr == DW_AT_call_origin) {
+ if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
call_origin = form_value.Reference();
if (!call_origin->IsValid()) {
LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
@@ -3854,15 +3740,24 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
}
}
+ if (attr == DW_AT_low_pc)
+ low_pc = form_value.Address();
+
// Extract DW_AT_call_return_pc (the PC the call returns to) if it's
// available. It should only ever be unavailable for tail call edges, in
// which case use LLDB_INVALID_ADDRESS.
if (attr == DW_AT_call_return_pc)
return_pc = form_value.Address();
+ // Extract DW_AT_call_pc (the PC at the call/branch instruction). It
+ // should only ever be unavailable for non-tail calls, in which case use
+ // LLDB_INVALID_ADDRESS.
+ if (attr == DW_AT_call_pc)
+ call_inst_pc = form_value.Address();
+
// Extract DW_AT_call_target (the location of the address of the indirect
// call).
- if (attr == DW_AT_call_target) {
+ if (attr == DW_AT_call_target || attr == DW_AT_GNU_call_site_target) {
if (!DWARFFormValue::IsBlockForm(form_value.Form())) {
LLDB_LOG(log,
"CollectCallEdges: AT_call_target does not have block form");
@@ -3882,16 +3777,39 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
continue;
}
+ addr_t caller_address;
+ CallEdge::AddrType caller_address_type;
+ if (return_pc != LLDB_INVALID_ADDRESS) {
+ caller_address = return_pc;
+ caller_address_type = CallEdge::AddrType::AfterCall;
+ } else if (low_pc != LLDB_INVALID_ADDRESS) {
+ caller_address = low_pc;
+ caller_address_type = CallEdge::AddrType::AfterCall;
+ } else if (call_inst_pc != LLDB_INVALID_ADDRESS) {
+ caller_address = call_inst_pc;
+ caller_address_type = CallEdge::AddrType::Call;
+ } else {
+ LLDB_LOG(log, "CollectCallEdges: No caller address");
+ continue;
+ }
+ // Adjust any PC forms. It needs to be fixed up if the main executable
+ // contains a debug map (i.e. pointers to object files), because we need a
+ // file address relative to the executable's text section.
+ caller_address = FixupAddress(caller_address);
+
// Extract call site parameters.
CallSiteParameterArray parameters =
CollectCallSiteParameters(module, child);
std::unique_ptr<CallEdge> edge;
if (call_origin) {
- LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
- call_origin->GetPubname(), return_pc);
- edge = std::make_unique<DirectCallEdge>(call_origin->GetMangledName(),
- return_pc, std::move(parameters));
+ LLDB_LOG(log,
+ "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
+ "(call-PC: {2:x})",
+ call_origin->GetPubname(), return_pc, call_inst_pc);
+ edge = std::make_unique<DirectCallEdge>(
+ call_origin->GetMangledName(), caller_address_type, caller_address,
+ tail_call, std::move(parameters));
} else {
if (log) {
StreamString call_target_desc;
@@ -3900,8 +3818,9 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}",
call_target_desc.GetString());
}
- edge = std::make_unique<IndirectCallEdge>(*call_target, return_pc,
- std::move(parameters));
+ edge = std::make_unique<IndirectCallEdge>(
+ *call_target, caller_address_type, caller_address, tail_call,
+ std::move(parameters));
}
if (log && parameters.size()) {
@@ -3925,6 +3844,11 @@ CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
std::vector<std::unique_ptr<lldb_private::CallEdge>>
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
+ // ParseCallEdgesInFunction must be called at the behest of an exclusively
+ // locked lldb::Function instance. Storage for parsed call edges is owned by
+ // the lldb::Function instance: locking at the SymbolFile level would be too
+ // late, because the act of storing results from ParseCallEdgesInFunction
+ // would be racy.
DWARFDIE func_die = GetDIE(func_id.GetID());
if (func_die.IsValid())
return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
@@ -3945,8 +3869,8 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) {
auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
if (!ts_or_err)
return;
- ClangASTContext *clang =
- llvm::dyn_cast_or_null<ClangASTContext>(&ts_or_err.get());
+ TypeSystemClang *clang =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get());
if (!clang)
return;
clang->Dump(s);
@@ -3957,26 +3881,93 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
m_debug_map_symfile =
- (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile();
+ static_cast<SymbolFileDWARFDebugMap *>(module_sp->GetSymbolFile());
}
}
return m_debug_map_symfile;
}
-SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
+const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
ModuleSpec module_spec;
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
module_spec.GetSymbolFileSpec() =
- FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp");
+ FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp");
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dwp_filespec =
Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
if (FileSystem::Instance().Exists(dwp_filespec)) {
- m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
- dwp_filespec);
+ DataBufferSP dwp_file_data_sp;
+ lldb::offset_t dwp_file_data_offset = 0;
+ ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
+ GetObjectFile()->GetModule(), &dwp_filespec, 0,
+ FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
+ dwp_file_data_offset);
+ if (!dwp_obj_file)
+ return;
+ m_dwp_symfile =
+ std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff);
}
});
- return m_dwp_symfile.get();
+ return m_dwp_symfile;
+}
+
+llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
+ return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit));
+}
+
+DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) {
+ auto type_system_or_err = GetTypeSystem(unit);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DWARFASTParser");
+ return nullptr;
+ }
+ return type_system_or_err->GetDWARFParser();
+}
+
+CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) {
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+ return dwarf_ast->GetDeclForUIDFromDWARF(die);
+ return CompilerDecl();
+}
+
+CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) {
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+ return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
+ return CompilerDeclContext();
+}
+
+CompilerDeclContext
+SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+ return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ return CompilerDeclContext();
+}
+
+DWARFDeclContext SymbolFileDWARF::GetDWARFDeclContext(const DWARFDIE &die) {
+ if (!die.IsValid())
+ return {};
+ DWARFDeclContext dwarf_decl_ctx =
+ die.GetDIE()->GetDWARFDeclContext(die.GetCU());
+ dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU()));
+ return dwarf_decl_ctx;
+}
+
+LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
+ // Note: user languages between lo_user and hi_user must be handled
+ // explicitly here.
+ switch (val) {
+ case DW_LANG_Mips_Assembler:
+ return eLanguageTypeMipsAssembler;
+ case DW_LANG_GOOGLE_RenderScript:
+ return eLanguageTypeExtRenderScript;
+ default:
+ return static_cast<LanguageType>(val);
+ }
+}
+
+LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) {
+ return LanguageTypeFromDWARF(unit.GetDWARFLanguageType());
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 23e26732453f..76ceb279c718 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -6,17 +6,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_SymbolFileDWARF_h_
-#define SymbolFileDWARF_SymbolFileDWARF_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
#include <list>
#include <map>
#include <mutex>
-#include <set>
#include <unordered_map>
#include <vector>
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/Support/Threading.h"
#include "lldb/Core/UniqueCStringMap.h"
@@ -90,8 +90,6 @@ public:
static lldb_private::SymbolFile *
CreateInstance(lldb::ObjectFileSP objfile_sp);
- static lldb_private::FileSpecList GetSymlinkPaths();
-
// Constructors and Destructors
SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,
@@ -108,6 +106,9 @@ public:
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
+ lldb_private::XcodeSDK
+ ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
@@ -168,7 +169,7 @@ public:
void
FindGlobalVariables(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
@@ -177,7 +178,7 @@ public:
lldb_private::VariableList &variables) override;
void FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines,
lldb_private::SymbolContextList &sc_list) override;
@@ -192,7 +193,7 @@ public:
void
FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
@@ -211,7 +212,7 @@ public:
lldb_private::CompilerDeclContext FindNamespace(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ const lldb_private::CompilerDeclContext &parent_decl_ctx) override;
void PreloadSymbols() override;
@@ -224,11 +225,7 @@ public:
DWARFDebugAbbrev *DebugAbbrev();
- const DWARFDebugAbbrev *DebugAbbrev() const;
-
- DWARFDebugInfo *DebugInfo();
-
- const DWARFDebugInfo *DebugInfo() const;
+ DWARFDebugInfo &DebugInfo();
DWARFDebugRanges *GetDebugRanges();
@@ -243,8 +240,8 @@ public:
lldb_private::CompileUnit *
GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
- virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
- DIEArray &method_die_offsets);
+ virtual void GetObjCMethods(lldb_private::ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback);
bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu);
@@ -252,8 +249,6 @@ public:
static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
- virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
-
lldb::ModuleSP GetExternalModule(lldb_private::ConstString name);
typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
@@ -278,22 +273,17 @@ public:
lldb::user_id_t GetUID(DIERef ref);
- std::unique_ptr<SymbolFileDWARFDwo>
+ std::shared_ptr<SymbolFileDWARFDwo>
GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
const DWARFDebugInfoEntry &cu_die);
- // For regular SymbolFileDWARF instances the method returns nullptr,
- // for the instances of the subclass SymbolFileDWARFDwo
- // the method returns a pointer to the base compile unit.
- virtual DWARFCompileUnit *GetBaseCompileUnit() { return nullptr; }
-
virtual llvm::Optional<uint32_t> GetDwoNum() { return llvm::None; }
/// If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
llvm::Optional<uint64_t> GetDWOId();
static bool
- DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx,
const DWARFDIE &die);
std::vector<std::unique_ptr<lldb_private::CallEdge>>
@@ -305,8 +295,30 @@ public:
lldb_private::DWARFContext &GetDWARFContext() { return m_context; }
+ const std::shared_ptr<SymbolFileDWARFDwo> &GetDwpSymbolFile();
+
lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
+ static llvm::Expected<lldb_private::TypeSystem &>
+ GetTypeSystem(DWARFUnit &unit);
+
+ static DWARFASTParser *GetDWARFParser(DWARFUnit &unit);
+
+ // CompilerDecl related functions
+
+ static lldb_private::CompilerDecl GetDecl(const DWARFDIE &die);
+
+ static lldb_private::CompilerDeclContext GetDeclContext(const DWARFDIE &die);
+
+ static lldb_private::CompilerDeclContext
+ GetContainingDeclContext(const DWARFDIE &die);
+
+ static DWARFDeclContext GetDWARFDeclContext(const DWARFDIE &die);
+
+ static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
+
+ static lldb::LanguageType GetLanguage(DWARFUnit &unit);
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -315,25 +327,16 @@ protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
lldb::opaque_compiler_type_t>
DIEToClangType;
- typedef llvm::DenseMap<lldb::opaque_compiler_type_t, lldb::user_id_t>
- ClangTypeToDIE;
+ typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
- struct DWARFDataSegment {
- llvm::once_flag m_flag;
- lldb_private::DWARFDataExtractor m_data;
- };
-
- DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF);
-
- const lldb_private::DWARFDataExtractor &
- GetCachedSectionData(lldb::SectionType sect_type,
- DWARFDataSegment &data_segment);
+ SymbolFileDWARF(const SymbolFileDWARF &) = delete;
+ const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete;
virtual void LoadSectionData(lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data);
bool DeclContextMatchesThisSymbolFile(
- const lldb_private::CompilerDeclContext *decl_ctx);
+ const lldb_private::CompilerDeclContext &decl_ctx);
uint32_t CalculateNumCompileUnits() override;
@@ -341,6 +344,8 @@ protected:
lldb_private::TypeList &GetTypeList() override;
+ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
+
virtual DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
@@ -383,6 +388,13 @@ protected:
bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
lldb_private::SymbolContextList &sc_list);
+ /// Resolve functions and (possibly) blocks for the given file address and a
+ /// compile unit. The compile unit comes from the sc argument and it must be
+ /// set. The results of the lookup (if any) are written back to the symbol
+ /// context.
+ void ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, bool lookup_block,
+ lldb_private::SymbolContext &sc);
+
virtual lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
@@ -417,9 +429,21 @@ protected:
bool ClassContainsSelector(const DWARFDIE &class_die,
lldb_private::ConstString selector);
+ /// Parse call site entries (DW_TAG_call_site), including any nested call site
+ /// parameters (DW_TAG_call_site_parameter).
+ std::vector<std::unique_ptr<lldb_private::CallEdge>>
+ CollectCallEdges(lldb::ModuleSP module, DWARFDIE function_die);
+
+ /// If this symbol file is linked to by a debug map (see
+ /// SymbolFileDWARFDebugMap), and \p file_addr is a file address relative to
+ /// an object file, adjust \p file_addr so that it is relative to the main
+ /// binary. Returns the adjusted address, or \p file_addr if no adjustment is
+ /// needed, on success and LLDB_INVALID_ADDRESS otherwise.
+ lldb::addr_t FixupAddress(lldb::addr_t file_addr);
+
bool FixupAddress(lldb_private::Address &addr);
- typedef std::set<lldb_private::Type *> TypeSet;
+ typedef llvm::SetVector<lldb_private::Type *> TypeSet;
void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
@@ -454,7 +478,7 @@ protected:
};
llvm::Optional<DecodedUID> DecodeUID(lldb::user_id_t uid);
- SymbolFileDWARFDwp *GetDwpSymbolFile();
+ void FindDwpSymbolFile();
const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
@@ -462,17 +486,14 @@ protected:
SymbolFileDWARFDebugMap *m_debug_map_symfile;
llvm::once_flag m_dwp_symfile_once_flag;
- std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile;
+ std::shared_ptr<SymbolFileDWARFDwo> m_dwp_symfile;
lldb_private::DWARFContext m_context;
- DWARFDataSegment m_data_debug_loc;
- DWARFDataSegment m_data_debug_loclists;
+ llvm::once_flag m_info_once_flag;
+ std::unique_ptr<DWARFDebugInfo> m_info;
- // The unique pointer items below are generated on demand if and when someone
- // accesses them through a non const version of this class.
std::unique_ptr<DWARFDebugAbbrev> m_abbr;
- std::unique_ptr<DWARFDebugInfo> m_info;
std::unique_ptr<GlobalVariableMap> m_global_aranges_up;
typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
@@ -484,7 +505,7 @@ protected:
bool m_fetched_external_modules : 1;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
- typedef std::set<lldb::user_id_t> DIERefSet;
+ typedef std::set<DIERef> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
std::unique_ptr<DWARFDebugRanges> m_ranges;
@@ -498,4 +519,4 @@ protected:
std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
};
-#endif // SymbolFileDWARF_SymbolFileDWARF_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index cce666a222d0..6515d78b8f23 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
+//===-- SymbolFileDWARFDebugMap.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -108,8 +108,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
// First we find the original symbol in the .o file's symbol table
Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
- exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled),
+ exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
if (oso_fun_symbol) {
// Add the inverse OSO file address to debug map entry mapping
@@ -139,8 +138,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
// in the .o file
Symbol *oso_gsym_symbol =
oso_symtab->FindFirstSymbolWithNameAndType(
- exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
- Mangled::ePreferMangled),
+ exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() &&
oso_gsym_symbol->ValueIsAddress()) {
@@ -416,6 +414,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
FileSpec oso_file(oso_path);
ConstString oso_object;
if (FileSystem::Instance().Exists(oso_file)) {
+ FileSystem::Instance().Collect(oso_file);
// The modification time returned by the FS can have a higher precision
// than the one from the CU.
auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
@@ -531,7 +530,7 @@ SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
if (sym_file &&
sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
- return (SymbolFileDWARF *)sym_file;
+ return static_cast<SymbolFileDWARF *>(sym_file);
return nullptr;
}
@@ -630,6 +629,14 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
return eLanguageTypeUnknown;
}
+XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
+ if (oso_dwarf)
+ return oso_dwarf->ParseXcodeSDK(comp_unit);
+ return {};
+}
+
size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
@@ -826,7 +833,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
}
void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
const std::vector<uint32_t>
&indexes, // Indexes into the symbol table that match "name"
uint32_t max_matches, VariableList &variables) {
@@ -848,7 +855,7 @@ void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
}
void SymbolFileDWARFDebugMap::FindGlobalVariables(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
@@ -1002,7 +1009,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
}
void SymbolFileDWARFDebugMap::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1172,7 +1179,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
}
void SymbolFileDWARFDebugMap::FindTypes(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
@@ -1209,7 +1216,7 @@ void SymbolFileDWARFDebugMap::FindTypes(
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
lldb_private::ConstString name,
- const CompilerDeclContext *parent_decl_ctx) {
+ const CompilerDeclContext &parent_decl_ctx) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompilerDeclContext matching_namespace;
@@ -1225,6 +1232,9 @@ CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
oso_dwarf->DumpClangAST(s);
+ // The underlying assumption is that DumpClangAST(...) will obtain the
+ // AST from the underlying TypeSystem and therefore we only need to do
+ // this once and can stop after the first iteration hence we return true.
return true;
});
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 035a902498be..06f0d48c04ca 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
-#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Utility/RangeMap.h"
@@ -57,11 +57,10 @@ public:
// Compile Unit function calls
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
-
+ lldb_private::XcodeSDK
+ ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
-
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
-
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
bool ForEachExternalModule(
@@ -105,14 +104,14 @@ public:
lldb_private::SymbolContextList &sc_list) override;
void
FindGlobalVariables(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
void FindGlobalVariables(const lldb_private::RegularExpression &regex,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
void FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines,
lldb_private::SymbolContextList &sc_list) override;
@@ -121,7 +120,7 @@ public:
lldb_private::SymbolContextList &sc_list) override;
void
FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
@@ -132,7 +131,7 @@ public:
lldb_private::TypeMap &types) override;
lldb_private::CompilerDeclContext FindNamespace(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ const lldb_private::CompilerDeclContext &parent_decl_ctx) override;
void GetTypes(lldb_private::SymbolContextScope *sc_scope,
lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
@@ -254,7 +253,7 @@ protected:
void PrivateFindGlobalVariables(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
lldb_private::VariableList &variables);
@@ -379,4 +378,4 @@ protected:
DWARFDebugAranges *debug_aranges);
};
-#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index f75f06f31e2d..3aaa7d330b84 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===//
+//===-- SymbolFileDWARFDwo.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -23,62 +23,52 @@ using namespace lldb_private;
char SymbolFileDWARFDwo::ID;
-SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
- DWARFCompileUnit &dwarf_cu)
+SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file,
+ ObjectFileSP objfile, uint32_t id)
: SymbolFileDWARF(objfile, objfile->GetSectionList(
/*update_module_section_list*/ false)),
- m_base_dwarf_cu(dwarf_cu) {
- SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
-}
-
-void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
- DWARFDataExtractor &data) {
- const SectionList *section_list =
- m_objfile_sp->GetSectionList(false /* update_module_section_list */);
- if (section_list) {
- SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
- if (section_sp) {
+ m_base_symbol_file(base_symbol_file) {
+ SetID(user_id_t(id) << 32);
- if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
- return;
+ // Parsing of the dwarf unit index is not thread-safe, so we need to prime it
+ // to enable subsequent concurrent lookups.
+ m_context.GetAsLLVM().getCUIndex();
+}
- data.Clear();
+DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
+ if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) {
+ if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) {
+ if (auto *unit_contrib = entry->getContribution())
+ return llvm::dyn_cast_or_null<DWARFCompileUnit>(
+ DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo,
+ unit_contrib->Offset));
}
+ return nullptr;
}
- SymbolFileDWARF::LoadSectionData(sect_type, data);
-}
-
-lldb::CompUnitSP
-SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
- assert(GetCompileUnit() == &dwarf_cu &&
- "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible "
- "compile unit");
- return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu);
-}
-
-DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() {
- if (!m_cu)
- m_cu = ComputeCompileUnit();
- return m_cu;
+ DWARFCompileUnit *cu = FindSingleCompileUnit();
+ if (!cu)
+ return nullptr;
+ if (hash !=
+ cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0))
+ return nullptr;
+ return cu;
}
-DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() {
- DWARFDebugInfo *debug_info = DebugInfo();
- if (!debug_info)
- return nullptr;
+DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() {
+ DWARFDebugInfo &debug_info = DebugInfo();
// Right now we only support dwo files with one compile unit. If we don't have
// type units, we can just check for the unit count.
- if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1)
- return llvm::cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(0));
+ if (!debug_info.ContainsTypeUnits() && debug_info.GetNumUnits() == 1)
+ return llvm::cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(0));
// Otherwise, we have to run through all units, and find the compile unit that
// way.
DWARFCompileUnit *cu = nullptr;
- for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) {
+ for (size_t i = 0; i < debug_info.GetNumUnits(); ++i) {
if (auto *candidate =
- llvm::dyn_cast<DWARFCompileUnit>(debug_info->GetUnitAtIndex(i))) {
+ llvm::dyn_cast<DWARFCompileUnit>(debug_info.GetUnitAtIndex(i))) {
if (cu)
return nullptr; // More that one CU found.
cu = candidate;
@@ -87,11 +77,6 @@ DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() {
return cu;
}
-DWARFUnit *
-SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
- return GetCompileUnit();
-}
-
SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
return GetBaseSymbolFile().GetDIEToType();
}
@@ -110,10 +95,10 @@ SymbolFileDWARFDwo::GetForwardDeclClangTypeToDie() {
return GetBaseSymbolFile().GetForwardDeclClangTypeToDie();
}
-size_t SymbolFileDWARFDwo::GetObjCMethodDIEOffsets(
- lldb_private::ConstString class_name, DIEArray &method_die_offsets) {
- return GetBaseSymbolFile().GetObjCMethodDIEOffsets(class_name,
- method_die_offsets);
+void SymbolFileDWARFDwo::GetObjCMethods(
+ lldb_private::ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) {
+ GetBaseSymbolFile().GetObjCMethods(class_name, callback);
}
UniqueDWARFASTTypeMap &SymbolFileDWARFDwo::GetUniqueDWARFASTTypeMap() {
@@ -133,10 +118,6 @@ lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
die, type_name, must_be_implementation);
}
-SymbolFileDWARF &SymbolFileDWARFDwo::GetBaseSymbolFile() {
- return m_base_dwarf_cu.GetSymbolFileDWARF();
-}
-
llvm::Expected<TypeSystem &>
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
@@ -144,7 +125,7 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
DWARFDIE
SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
- if (*die_ref.dwo_num() == GetDwoNum())
- return DebugInfo()->GetDIE(die_ref);
+ if (die_ref.dwo_num() == GetDwoNum())
+ return DebugInfo().GetDIE(die_ref);
return GetBaseSymbolFile().GetDIE(die_ref);
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 0855dba044e4..93538aac3c54 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
-#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H
#include "SymbolFileDWARF.h"
@@ -24,19 +24,15 @@ public:
static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
/// \}
- SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu);
+ SymbolFileDWARFDwo(SymbolFileDWARF &m_base_symbol_file,
+ lldb::ObjectFileSP objfile, uint32_t id);
~SymbolFileDWARFDwo() override = default;
- lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override;
+ DWARFCompileUnit *GetDWOCompileUnitForHash(uint64_t hash);
- DWARFCompileUnit *GetCompileUnit();
-
- DWARFUnit *
- GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
-
- size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
- DIEArray &method_die_offsets) override;
+ void GetObjCMethods(lldb_private::ConstString class_name,
+ llvm::function_ref<bool(DWARFDIE die)> callback) override;
llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
@@ -44,14 +40,9 @@ public:
DWARFDIE
GetDIE(const DIERef &die_ref) override;
- DWARFCompileUnit *GetBaseCompileUnit() override { return &m_base_dwarf_cu; }
-
llvm::Optional<uint32_t> GetDwoNum() override { return GetID() >> 32; }
protected:
- void LoadSectionData(lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data) override;
-
DIEToTypePtr &GetDIEToType() override;
DIEToVariableSP &GetDIEToVariable() override;
@@ -69,12 +60,13 @@ protected:
const DWARFDIE &die, lldb_private::ConstString type_name,
bool must_be_implementation) override;
- SymbolFileDWARF &GetBaseSymbolFile();
+ SymbolFileDWARF &GetBaseSymbolFile() { return m_base_symbol_file; }
- DWARFCompileUnit *ComputeCompileUnit();
+ /// If this file contains exactly one compile unit, this function will return
+ /// it. Otherwise it returns nullptr.
+ DWARFCompileUnit *FindSingleCompileUnit();
- DWARFCompileUnit &m_base_dwarf_cu;
- DWARFCompileUnit *m_cu = nullptr;
+ SymbolFileDWARF &m_base_symbol_file;
};
-#endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDWO_H
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
deleted file mode 100644
index 4288dcb5c9bd..000000000000
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolFileDWARFDwoDwp.h"
-
-#include "lldb/Core/Section.h"
-#include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/LLDBAssert.h"
-
-#include "DWARFUnit.h"
-#include "DWARFDebugInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-char SymbolFileDWARFDwoDwp::ID;
-
-SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
- ObjectFileSP objfile,
- DWARFCompileUnit &dwarf_cu,
- uint64_t dwo_id)
- : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
- m_dwo_id(dwo_id) {}
-
-void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type,
- DWARFDataExtractor &data) {
- if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data))
- return;
-
- SymbolFileDWARF::LoadSectionData(sect_type, data);
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
deleted file mode 100644
index a55795ba5950..000000000000
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
-#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
-
-#include "SymbolFileDWARFDwo.h"
-#include "SymbolFileDWARFDwp.h"
-
-class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
- /// LLVM RTTI support.
- static char ID;
-
-public:
- /// LLVM RTTI support.
- /// \{
- bool isA(const void *ClassID) const override {
- return ClassID == &ID || SymbolFileDWARFDwo::isA(ClassID);
- }
- static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
- /// \}
- SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
- lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu,
- uint64_t dwo_id);
-
-protected:
- void LoadSectionData(lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data) override;
-
- SymbolFileDWARFDwp *m_dwp_symfile;
- uint64_t m_dwo_id;
-};
-
-#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
deleted file mode 100644
index 08e6e1c8c2f3..000000000000
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolFileDWARFDwp.h"
-
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/ObjectFile.h"
-
-#include "SymbolFileDWARFDwoDwp.h"
-
-static llvm::DWARFSectionKind
-lldbSectTypeToLlvmSectionKind(lldb::SectionType type) {
- switch (type) {
- case lldb::eSectionTypeDWARFDebugInfo:
- return llvm::DW_SECT_INFO;
- // case lldb::eSectionTypeDWARFDebugTypes:
- // return llvm::DW_SECT_TYPES;
- case lldb::eSectionTypeDWARFDebugAbbrev:
- return llvm::DW_SECT_ABBREV;
- case lldb::eSectionTypeDWARFDebugLine:
- return llvm::DW_SECT_LINE;
- case lldb::eSectionTypeDWARFDebugLoc:
- return llvm::DW_SECT_LOC;
- case lldb::eSectionTypeDWARFDebugStrOffsets:
- return llvm::DW_SECT_STR_OFFSETS;
- // case lldb::eSectionTypeDWARFDebugMacinfo:
- // return llvm::DW_SECT_MACINFO;
- case lldb::eSectionTypeDWARFDebugMacro:
- return llvm::DW_SECT_MACRO;
- default:
- // Note: 0 is an invalid dwarf section kind.
- return llvm::DWARFSectionKind(0);
- }
-}
-
-std::unique_ptr<SymbolFileDWARFDwp>
-SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp,
- const lldb_private::FileSpec &file_spec) {
- const lldb::offset_t file_offset = 0;
- lldb::DataBufferSP file_data_sp;
- lldb::offset_t file_data_offset = 0;
- lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin(
- module_sp, &file_spec, file_offset,
- lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp,
- file_data_offset);
- if (obj_file == nullptr)
- return nullptr;
-
- std::unique_ptr<SymbolFileDWARFDwp> dwp_symfile(
- new SymbolFileDWARFDwp(module_sp, obj_file));
-
- lldb_private::DWARFDataExtractor debug_cu_index;
- if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex,
- debug_cu_index))
- return nullptr;
-
- llvm::DataExtractor llvm_debug_cu_index(
- llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()),
- debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle,
- debug_cu_index.GetAddressByteSize());
- if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index))
- return nullptr;
- dwp_symfile->InitDebugCUIndexMap();
- return dwp_symfile;
-}
-
-void SymbolFileDWARFDwp::InitDebugCUIndexMap() {
- m_debug_cu_index_map.clear();
- for (const auto &entry : m_debug_cu_index.getRows())
- m_debug_cu_index_map.emplace(entry.getSignature(), &entry);
-}
-
-SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
- lldb::ObjectFileSP obj_file)
- : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO)
-{}
-
-std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu,
- uint64_t dwo_id) {
- return std::unique_ptr<SymbolFileDWARFDwo>(
- new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
-}
-
-bool SymbolFileDWARFDwp::LoadSectionData(
- uint64_t dwo_id, lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data) {
- lldb_private::DWARFDataExtractor section_data;
- if (!LoadRawSectionData(sect_type, section_data))
- return false;
-
- auto it = m_debug_cu_index_map.find(dwo_id);
- if (it == m_debug_cu_index_map.end())
- return false;
-
- auto *offsets =
- it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type));
- if (offsets) {
- data.SetData(section_data, offsets->Offset, offsets->Length);
- } else {
- data.SetData(section_data, 0, section_data.GetByteSize());
- }
- return true;
-}
-
-bool SymbolFileDWARFDwp::LoadRawSectionData(
- lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) {
- std::lock_guard<std::mutex> lock(m_sections_mutex);
-
- auto it = m_sections.find(sect_type);
- if (it != m_sections.end()) {
- if (it->second.GetByteSize() == 0)
- return false;
-
- data = it->second;
- return true;
- }
-
- const lldb_private::SectionList *section_list =
- m_obj_file->GetSectionList(false /* update_module_section_list */);
- if (section_list) {
- lldb::SectionSP section_sp(
- section_list->FindSectionByType(sect_type, true));
- if (section_sp) {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) {
- m_sections[sect_type] = data;
- return true;
- }
- }
- }
- m_sections[sect_type].Clear();
- return false;
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
deleted file mode 100644
index ef06b9dca8bb..000000000000
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
-#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
-
-#include <memory>
-
-#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-
-#include "lldb/Core/Module.h"
-
-#include "DWARFDataExtractor.h"
-#include "SymbolFileDWARFDwo.h"
-
-class SymbolFileDWARFDwp {
-public:
- static std::unique_ptr<SymbolFileDWARFDwp>
- Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
-
- std::unique_ptr<SymbolFileDWARFDwo>
- GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id);
-
- bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data);
-
-private:
- explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
- lldb::ObjectFileSP obj_file);
-
- bool LoadRawSectionData(lldb::SectionType sect_type,
- lldb_private::DWARFDataExtractor &data);
-
- void InitDebugCUIndexMap();
-
- lldb::ObjectFileSP m_obj_file;
-
- std::mutex m_sections_mutex;
- std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections;
-
- llvm::DWARFUnitIndex m_debug_cu_index;
- std::map<uint64_t, const llvm::DWARFUnitIndex::Entry *> m_debug_cu_index_map;
-};
-
-#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
index ef6ae3498588..2f1ce88808b7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
@@ -1,10 +1,6 @@
include "../../../../include/lldb/Core/PropertiesBase.td"
let Definition = "symbolfiledwarf" in {
- def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">,
- Global,
- DefaultStringValue<"">,
- Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">;
def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">,
Global,
DefaultFalse,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 4862fea8d079..2181989cd37a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -1,4 +1,4 @@
-//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===//
+//===-- UniqueDWARFASTType.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index 1269dbac7126..a1b1a3009787 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_UniqueDWARFASTType_h_
-#define lldb_UniqueDWARFASTType_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H
#include <vector>
@@ -100,4 +100,4 @@ protected:
collection m_collection;
};
-#endif // lldb_UniqueDWARFASTType_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_UNIQUEDWARFASTTYPE_H
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
index 3834165c71c0..ca9ddcec287f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
@@ -1,4 +1,4 @@
-//===-- CodeViewRegisterMapping.cpp -----------------------------*- C++ -*-===//
+//===-- CodeViewRegisterMapping.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
index b1c31e0c1785..02c7495565b8 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_
-#define lldb_Plugins_SymbolFile_PDB_CodeViewRegisterMapping_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 830d78f81679..f25dc84fb342 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -1,4 +1,4 @@
-//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===//
+//===-- CompileUnitIndex.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -154,7 +154,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
// name until we find it, and we can cache that one since the memory is backed
// by a contiguous chunk inside the mapped PDB.
llvm::SmallString<64> main_file = GetMainSourceFile(*cci);
- std::string s = main_file.str();
+ std::string s = std::string(main_file.str());
llvm::sys::path::native(main_file);
uint32_t file_count = modules.getSourceFileCount(modi);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
index 44a1c8cdd9c2..088de970cbf3 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H
-#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_COMPILEUNITINDEX_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 6aaff06cc134..d0672352a58f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===//
+//===-- DWARFLocationExpression.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
index c37d715babdc..99da09b70fe1 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
@@ -6,14 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
-#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
#include "lldb/lldb-forward.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
namespace llvm {
class APSInt;
+class StringRef;
namespace codeview {
class TypeIndex;
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 4588c80aa1b1..0acc77d7c67f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -14,11 +14,11 @@
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/Demangle/MicrosoftDemangle.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -178,7 +178,7 @@ GetNestedTagDefinition(const NestedTypeRecord &Record,
// single component of a mangled name. So we can inject it into the parent's
// mangled name to see if it matches.
CVTagRecord child = CVTagRecord::create(cvt);
- std::string qname = parent.asTag().getUniqueName();
+ std::string qname = std::string(parent.asTag().getUniqueName());
if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
return llvm::None;
@@ -202,7 +202,7 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) {
return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang)
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang)
: m_index(index), m_clang(clang) {
BuildParentMap();
}
@@ -221,7 +221,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
StringView sv(record.UniqueName.begin(), record.UniqueName.size());
llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
if (demangler.Error)
- return {m_clang.GetTranslationUnitDecl(), record.UniqueName};
+ return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)};
llvm::ms_demangle::IdentifierNode *idn =
ttn->QualifiedName->getUnqualifiedIdentifier();
@@ -248,7 +248,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
// a NamespaceDecl and a CXXRecordDecl, so instead we create a class at
// global scope with the fully qualified name.
if (AnyScopesHaveTemplateParams(scopes))
- return {context, record.Name};
+ return {context, std::string(record.Name)};
for (llvm::ms_demangle::Node *scope : scopes) {
auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
@@ -507,7 +507,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
llvm::StringRef uname = specs.back().GetBaseName();
specs = specs.drop_back();
if (specs.empty())
- return {context, name};
+ return {context, std::string(name)};
llvm::StringRef scope_name = specs.back().GetFullName();
@@ -517,7 +517,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
clang::QualType qt = GetOrCreateType(types.back());
clang::TagDecl *tag = qt->getAsTagDecl();
if (tag)
- return {clang::TagDecl::castToDeclContext(tag), uname};
+ return {clang::TagDecl::castToDeclContext(tag), std::string(uname)};
types.pop_back();
}
@@ -526,7 +526,7 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
std::string ns_name = spec.GetBaseName().str();
context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
}
- return {context, uname};
+ return {context, std::string(uname)};
}
clang::DeclContext *
@@ -656,7 +656,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
lldbassert(IsTagRecord(type_id, m_index.tpi()));
clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag);
- ClangASTContext::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
+ TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
TypeIndex tag_ti = type_id.index;
CVType cvt = m_index.tpi().getType(tag_ti);
@@ -681,7 +681,7 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
// Visit all members of this class, then perform any finalization necessary
// to complete the class.
CompilerType ct = ToCompilerType(tag_qt);
- UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index.tpi());
+ UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index);
auto error =
llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer);
completer.complete();
@@ -776,12 +776,13 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
metadata.SetUserID(toOpaqueUid(id));
metadata.SetIsDynamicCXXType(false);
- CompilerType ct = m_clang.CreateRecordType(
- context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
+ CompilerType ct =
+ m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
+ ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
lldbassert(ct.IsValid());
- ClangASTContext::StartTagDeclarationDefinition(ct);
+ TypeSystemClang::StartTagDeclarationDefinition(ct);
// Even if it's possible, don't complete it at this point. Just mark it
// forward resolved, and if/when LLDB needs the full definition, it can
@@ -789,7 +790,7 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
clang::QualType result =
clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
- ClangASTContext::SetHasExternalStorage(result.getAsOpaquePtr(), true);
+ TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true);
return result;
}
@@ -804,7 +805,8 @@ clang::NamespaceDecl *
PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context) {
return m_clang.GetUniqueNamespaceDeclaration(
- IsAnonymousNamespaceName(name) ? nullptr : name, &context);
+ IsAnonymousNamespaceName(name) ? nullptr : name, &context,
+ OptionalClangModuleID());
}
clang::BlockDecl *
@@ -814,7 +816,8 @@ PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
clang::DeclContext *scope = GetParentDeclContext(block_id);
- clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
+ clang::BlockDecl *block_decl =
+ m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());
m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
DeclStatus status;
@@ -831,7 +834,7 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
clang::QualType qt = GetOrCreateType(var_info.type);
clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
- &scope, var_info.name.str().c_str(), qt);
+ &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);
m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
DeclStatus status;
@@ -876,10 +879,10 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
PdbTypeSymId real_type_id{udt.Type, false};
clang::QualType qt = GetOrCreateType(real_type_id);
- std::string uname = DropNameScope(udt.Name);
+ std::string uname = std::string(DropNameScope(udt.Name));
CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
- ToCompilerDeclContext(*scope));
+ ToCompilerDeclContext(*scope), 0);
clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
DeclStatus status;
status.resolved = true;
@@ -1012,7 +1015,8 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
proc_name.consume_front("::");
clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
- parent, proc_name.str().c_str(), func_ct, storage, false);
+ parent, OptionalClangModuleID(), proc_name.str().c_str(), func_ct,
+ storage, false);
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
@@ -1080,8 +1084,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
CompilerType param_type_ct = m_clang.GetType(qt);
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
- &function_decl, param_name.str().c_str(), param_type_ct,
- clang::SC_None, true);
+ &function_decl, OptionalClangModuleID(), param_name.str().c_str(),
+ param_type_ct, clang::SC_None, true);
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
@@ -1102,11 +1106,11 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
Declaration declaration;
CompilerType enum_ct = m_clang.CreateEnumerationType(
- uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
- er.isScoped());
+ uname.c_str(), decl_context, OptionalClangModuleID(), declaration,
+ ToCompilerType(underlying_type), er.isScoped());
- ClangASTContext::StartTagDeclarationDefinition(enum_ct);
- ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
+ TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
+ TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());
}
@@ -1334,7 +1338,7 @@ void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {
}
CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {
- return {&m_clang, &decl};
+ return m_clang.GetCompilerDecl(&decl);
}
CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {
@@ -1347,7 +1351,7 @@ PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
}
clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {
- return static_cast<clang::Decl *>(decl.GetOpaqueDecl());
+ return ClangUtil::GetDecl(decl);
}
clang::DeclContext *
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index a4242e90810d..7bb2584d19a3 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
-#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
#include "PdbIndex.h"
#include "PdbSymUid.h"
@@ -51,7 +51,7 @@ struct DeclStatus {
class PdbAstBuilder {
public:
// Constructors and Destructors
- PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
+ PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang);
lldb_private::CompilerDeclContext GetTranslationUnitDecl();
@@ -80,7 +80,7 @@ public:
clang::Decl *FromCompilerDecl(CompilerDecl decl);
clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
- ClangASTContext &clang() { return m_clang; }
+ TypeSystemClang &clang() { return m_clang; }
ClangASTImporter &importer() { return m_importer; }
void Dump(Stream &stream);
@@ -129,7 +129,7 @@ private:
clang::QualType CreateSimpleType(TypeIndex ti);
PdbIndex &m_index;
- ClangASTContext &m_clang;
+ TypeSystemClang &m_clang;
ClangASTImporter m_importer;
@@ -142,4 +142,4 @@ private:
} // namespace npdb
} // namespace lldb_private
-#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index a7bc23519710..ecae767e4469 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -1,4 +1,4 @@
-//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===//
+//===-- PdbFPOProgramToDWARFExpression.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h
index 107e26fb04cb..fb979b877143 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_
-#define lldb_Plugins_SymbolFile_PDB_PDBFPOProgramToDWARFExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
index ba9a95b16e18..6ac6cc2da29b 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
@@ -1,4 +1,4 @@
-//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===//
+//===-- PdbIndex.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
index b30e7870bbdb..ccc3cc2f4538 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H
-#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBINDEX_H
#include "lldb/lldb-types.h"
#include "llvm/ADT/IntervalMap.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
index e5ad23f813eb..67397d707110 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
@@ -1,4 +1,4 @@
-//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===//
+//===-- PdbSymUid.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
index 7252d63c1ab4..3accd38d710e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
@@ -14,8 +14,8 @@
// access to the compile unit's information.
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
-#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index fc047e25a2f4..b5a16447d9cf 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -1,4 +1,4 @@
-//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===//
+//===-- PdbUtil.cpp -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
index 6f675b56dca4..c309c5c8ea1c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
-#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Variable.h"
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 370c339fb74b..cce06473d92f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===//
+//===-- SymbolFileNativePDB.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -14,13 +14,13 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -129,17 +129,18 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
// If it doesn't have a debug directory, fail.
llvm::StringRef pdb_file;
- auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file);
- if (ec)
+ if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
+ consumeError(std::move(e));
return nullptr;
+ }
// if the file doesn't exist, is not a pdb, or doesn't have a matching guid,
// fail.
llvm::file_magic magic;
- ec = llvm::identify_magic(pdb_file, magic);
+ auto ec = llvm::identify_magic(pdb_file, magic);
if (ec || magic != llvm::file_magic::pdb)
return nullptr;
- std::unique_ptr<PDBFile> pdb = loadPDBFile(pdb_file, allocator);
+ std::unique_ptr<PDBFile> pdb = loadPDBFile(std::string(pdb_file), allocator);
if (!pdb)
return nullptr;
@@ -331,7 +332,7 @@ void SymbolFileNativePDB::InitializeObject() {
std::move(err), "Failed to initialize");
} else {
ts_or_err->SetSymbolFile(this);
- auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get());
+ auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
lldbassert(clang);
m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
}
@@ -452,7 +453,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
std::string name;
if (mr.ModifiedType.isSimple())
- name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind());
+ name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind()));
else
name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
Declaration decl;
@@ -532,14 +533,14 @@ static std::string GetUnqualifiedTypeName(const TagRecord &record) {
MSVCUndecoratedNameParser parser(record.Name);
llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
- return specs.back().GetBaseName();
+ return std::string(specs.back().GetBaseName());
}
llvm::ms_demangle::Demangler demangler;
StringView sv(record.UniqueName.begin(), record.UniqueName.size());
llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
if (demangler.Error)
- return record.Name;
+ return std::string(record.Name);
llvm::ms_demangle::IdentifierNode *idn =
ttn->QualifiedName->getUnqualifiedIdentifier();
@@ -1171,7 +1172,7 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
void SymbolFileNativePDB::FindGlobalVariables(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
@@ -1198,7 +1199,7 @@ void SymbolFileNativePDB::FindGlobalVariables(
}
void SymbolFileNativePDB::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1236,7 +1237,7 @@ void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
SymbolContextList &sc_list) {}
void SymbolFileNativePDB::FindTypes(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
TypeMap &types) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1563,7 +1564,7 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
CompilerDeclContext
SymbolFileNativePDB::FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx) {
+ const CompilerDeclContext &parent_decl_ctx) {
return {};
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index a37de0f58ef3..bf5718e11a19 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
-#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
#include "lldb/Symbol/SymbolFile.h"
@@ -100,7 +100,7 @@ public:
size_t ParseBlocksRecursive(Function &func) override;
void FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
+ const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
VariableList &variables) override;
@@ -129,14 +129,14 @@ public:
TypeList &type_list) override;
void FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
+ const CompilerDeclContext &parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines, SymbolContextList &sc_list) override;
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
- void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<SymbolFile *> &searched_symbol_files,
TypeMap &types) override;
@@ -150,7 +150,7 @@ public:
CompilerDeclContext
FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx) override;
+ const CompilerDeclContext &parent_decl_ctx) override;
ConstString GetPluginName() override;
@@ -246,4 +246,4 @@ private:
} // namespace npdb
} // namespace lldb_private
-#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index 7221144407c1..c8fb46c75034 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -5,15 +5,18 @@
#include "PdbSymUid.h"
#include "PdbUtil.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
@@ -29,10 +32,10 @@ UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
CompilerType &derived_ct,
clang::TagDecl &tag_decl,
PdbAstBuilder &ast_builder,
- TpiStream &tpi)
+ PdbIndex &index)
: m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
- m_ast_builder(ast_builder), m_tpi(tpi) {
- CVType cvt = m_tpi.getType(m_id.index);
+ m_ast_builder(ast_builder), m_index(index) {
+ CVType cvt = m_index.tpi().getType(m_id.index);
switch (cvt.kind()) {
case LF_ENUM:
llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
@@ -55,7 +58,7 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
PdbTypeSymId type_id(ti);
clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
- CVType udt_cvt = m_tpi.getType(ti);
+ CVType udt_cvt = m_index.tpi().getType(ti);
std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
m_ast_builder.clang().CreateBaseClassSpecifier(
@@ -128,9 +131,70 @@ Error UdtRecordCompleter::visitKnownMember(
lldb::AccessType access =
TranslateMemberAccess(static_data_member.getAccess());
- ClangASTContext::AddVariableToRecordType(
+ auto decl = TypeSystemClang::AddVariableToRecordType(
m_derived_ct, static_data_member.Name, member_ct, access);
+ // Static constant members may be a const[expr] declaration.
+ // Query the symbol's value as the variable initializer if valid.
+ if (member_ct.IsConst()) {
+ std::string qual_name = decl->getQualifiedNameAsString();
+
+ auto results =
+ m_index.globals().findRecordsByName(qual_name, m_index.symrecords());
+
+ for (const auto &result : results) {
+ if (result.second.kind() == SymbolKind::S_CONSTANT) {
+ ConstantSym constant(SymbolRecordKind::ConstantSym);
+ cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(result.second,
+ constant));
+
+ clang::QualType qual_type = decl->getType();
+ unsigned type_width = decl->getASTContext().getIntWidth(qual_type);
+ unsigned constant_width = constant.Value.getBitWidth();
+
+ if (qual_type->isIntegralOrEnumerationType()) {
+ if (type_width >= constant_width) {
+ TypeSystemClang::SetIntegerInitializerForVariable(
+ decl, constant.Value.extOrTrunc(type_width));
+ } else {
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),
+ "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+ "which resolves to a wider constant value ({4} bits). "
+ "Ignoring constant.",
+ m_derived_ct.GetTypeName(), static_data_member.Name,
+ member_ct.GetTypeName(), type_width, constant_width);
+ }
+ } else {
+ lldb::BasicType basic_type_enum = member_ct.GetBasicTypeEnumeration();
+ switch (basic_type_enum) {
+ case lldb::eBasicTypeFloat:
+ case lldb::eBasicTypeDouble:
+ case lldb::eBasicTypeLongDouble:
+ if (type_width == constant_width) {
+ TypeSystemClang::SetFloatingInitializerForVariable(
+ decl, basic_type_enum == lldb::eBasicTypeFloat
+ ? llvm::APFloat(constant.Value.bitsToFloat())
+ : llvm::APFloat(constant.Value.bitsToDouble()));
+ decl->setConstexpr(true);
+ } else {
+ LLDB_LOG(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),
+ "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+ "which resolves to a constant value of mismatched width "
+ "({4} bits). Ignoring constant.",
+ m_derived_ct.GetTypeName(), static_data_member.Name,
+ member_ct.GetTypeName(), type_width, constant_width);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
// FIXME: Add a PdbSymUid namespace for field list members and update
// the m_uid_to_decl map with this decl.
return Error::success();
@@ -149,7 +213,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
TypeIndex ti(data_member.Type);
if (!ti.isSimple()) {
- CVType cvt = m_tpi.getType(ti);
+ CVType cvt = m_index.tpi().getType(ti);
if (cvt.kind() == LF_BITFIELD) {
BitFieldRecord bfr;
llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr));
@@ -164,7 +228,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
lldb::AccessType access = TranslateMemberAccess(data_member.getAccess());
- clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType(
+ clang::FieldDecl *decl = TypeSystemClang::AddFieldToRecordType(
m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt),
access, bitfield_width);
// FIXME: Add a PdbSymUid namespace for field list members and update
@@ -187,7 +251,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
OverloadedMethodRecord &overloaded) {
TypeIndex method_list_idx = overloaded.MethodList;
- CVType method_list_type = m_tpi.getType(method_list_idx);
+ CVType method_list_type = m_index.tpi().getType(method_list_idx);
assert(method_list_type.kind() == LF_METHODLIST);
MethodOverloadListRecord method_list;
@@ -223,12 +287,12 @@ void UdtRecordCompleter::complete() {
for (auto &ib : m_bases)
bases.push_back(std::move(ib.second));
- ClangASTContext &clang = m_ast_builder.clang();
+ TypeSystemClang &clang = m_ast_builder.clang();
clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases));
clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType());
- ClangASTContext::BuildIndirectFields(m_derived_ct);
- ClangASTContext::CompleteTagDeclarationDefinition(m_derived_ct);
+ TypeSystemClang::BuildIndirectFields(m_derived_ct);
+ TypeSystemClang::CompleteTagDeclarationDefinition(m_derived_ct);
if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
m_ast_builder.importer().SetRecordLayout(record_decl, m_layout);
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index 55397582209b..ae7e47c82fe5 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
-#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
@@ -25,6 +25,7 @@ class TagDecl;
namespace llvm {
namespace pdb {
class TpiStream;
+class GlobalsStream;
}
} // namespace llvm
@@ -33,6 +34,7 @@ class Type;
class CompilerType;
namespace npdb {
class PdbAstBuilder;
+class PdbIndex;
class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
using IndexedBase =
@@ -49,14 +51,14 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
CompilerType &m_derived_ct;
clang::TagDecl &m_tag_decl;
PdbAstBuilder &m_ast_builder;
- llvm::pdb::TpiStream &m_tpi;
+ PdbIndex &m_index;
std::vector<IndexedBase> m_bases;
ClangASTImporter::LayoutInfo m_layout;
public:
UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct,
clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder,
- llvm::pdb::TpiStream &tpi);
+ PdbIndex &index);
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \
@@ -79,4 +81,4 @@ private:
} // namespace npdb
} // namespace lldb_private
-#endif // LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 6b2dbd9e1e5a..d87926a6588f 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -1,4 +1,4 @@
-//===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===//
+//===-- PDBASTParser.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -14,10 +14,10 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
@@ -100,7 +100,7 @@ static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
}
static CompilerType
-GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
+GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,
const PDBSymbolTypeBuiltin &pdb_type,
Encoding encoding, uint32_t width) {
clang::ASTContext &ast = clang_ast.getASTContext();
@@ -353,7 +353,7 @@ static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
}
}
-PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
+PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}
PDBASTParser::~PDBASTParser() {}
@@ -386,7 +386,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
return nullptr;
// Ignore unnamed-tag UDTs.
- std::string name = MSVCUndecoratedNameParser::DropScope(udt->getName());
+ std::string name =
+ std::string(MSVCUndecoratedNameParser::DropScope(udt->getName()));
if (name.empty())
return nullptr;
@@ -408,9 +409,9 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
metadata.SetUserID(type.getSymIndexId());
metadata.SetIsDynamicCXXType(false);
- clang_type =
- m_ast.CreateRecordType(decl_context, access, name, tag_type_kind,
- lldb::eLanguageTypeC_plus_plus, &metadata);
+ clang_type = m_ast.CreateRecordType(
+ decl_context, OptionalClangModuleID(), access, name, tag_type_kind,
+ lldb::eLanguageTypeC_plus_plus, &metadata);
assert(clang_type.IsValid());
auto record_decl =
@@ -422,15 +423,15 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
m_ast.getASTContext(), GetMSInheritance(*udt));
record_decl->addAttr(inheritance_attr);
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
auto children = udt->findAllChildren();
if (!children || children->getChildCount() == 0) {
// PDB does not have symbol of forwarder. We assume we get an udt w/o
// any fields. Just complete it at this point.
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
- ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
+ TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
false);
type_resolve_state = Type::ResolveState::Full;
@@ -439,7 +440,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
// an endless recursion in CompleteTypeFromUdt function.
m_forward_decl_to_uid[record_decl] = type.getSymIndexId();
- ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
+ TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
true);
type_resolve_state = Type::ResolveState::Forward;
@@ -465,7 +466,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
assert(enum_type);
std::string name =
- MSVCUndecoratedNameParser::DropScope(enum_type->getName());
+ std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName()));
auto decl_context = GetDeclContextContainingSymbol(type);
uint64_t bytes = enum_type->getLength();
@@ -496,10 +497,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
// Class). Set it false for now.
bool isScoped = false;
- ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl,
+ ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context,
+ OptionalClangModuleID(), decl,
builtin_type, isScoped);
- auto enum_decl = ClangASTContext::GetAsEnumDecl(ast_enum);
+ auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
assert(enum_decl);
m_uid_to_decl[type.getSymIndexId()] = enum_decl;
@@ -512,8 +514,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
}
}
- if (ClangASTContext::StartTagDeclarationDefinition(ast_enum))
- ClangASTContext::CompleteTagDeclarationDefinition(ast_enum);
+ if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum))
+ TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum);
}
if (enum_type->isConstType())
@@ -538,7 +540,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
return nullptr;
std::string name =
- MSVCUndecoratedNameParser::DropScope(type_def->getName());
+ std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName()));
auto decl_ctx = GetDeclContextContainingSymbol(type);
// Check if such a typedef already exists in the current context
@@ -549,11 +551,11 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
CompilerType target_ast_type = target_type->GetFullCompilerType();
ast_typedef = m_ast.CreateTypedefType(
- target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx));
+ target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
if (!ast_typedef)
return nullptr;
- auto typedef_decl = ClangASTContext::GetAsTypedefDecl(ast_typedef);
+ auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef);
assert(typedef_decl);
m_uid_to_decl[type.getSymIndexId()] = typedef_decl;
}
@@ -587,7 +589,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
return nullptr;
func_sig = sig.release();
// Function type is named.
- name = MSVCUndecoratedNameParser::DropScope(pdb_func->getName());
+ name = std::string(
+ MSVCUndecoratedNameParser::DropScope(pdb_func->getName()));
} else if (auto pdb_func_sig =
llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
@@ -660,10 +663,10 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
CompilerType element_ast_type = element_type->GetForwardCompilerType();
// If element type is UDT, it needs to be complete.
- if (ClangASTContext::IsCXXClassType(element_ast_type) &&
+ if (TypeSystemClang::IsCXXClassType(element_ast_type) &&
!element_ast_type.GetCompleteType()) {
- if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) {
+ TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type);
} else {
// We are not able to start defintion.
return nullptr;
@@ -721,7 +724,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
assert(class_parent_type);
CompilerType pointer_ast_type;
- pointer_ast_type = ClangASTContext::CreateMemberPointerType(
+ pointer_ast_type = TypeSystemClang::CreateMemberPointerType(
class_parent_type->GetLayoutCompilerType(),
pointee_type->GetForwardCompilerType());
assert(pointer_ast_type);
@@ -787,7 +790,7 @@ bool PDBASTParser::CompleteTypeFromPDB(
m_forward_decl_to_uid.erase(uid_it);
- ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
+ TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
false);
switch (symbol->getSymTag()) {
@@ -887,7 +890,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))
m_ast.GetCompleteDecl(parent_decl);
- std::string name = MSVCUndecoratedNameParser::DropScope(data->getName());
+ std::string name =
+ std::string(MSVCUndecoratedNameParser::DropScope(data->getName()));
// Check if the current context already contains the symbol with the name.
clang::Decl *decl =
@@ -898,7 +902,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
return nullptr;
decl = m_ast.CreateVariableDeclaration(
- decl_context, name.c_str(),
+ decl_context, OptionalClangModuleID(), name.c_str(),
ClangUtil::GetQualType(type->GetLayoutCompilerType()));
}
@@ -913,7 +917,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
auto decl_context = GetDeclContextContainingSymbol(symbol);
assert(decl_context);
- std::string name = MSVCUndecoratedNameParser::DropScope(func->getName());
+ std::string name =
+ std::string(MSVCUndecoratedNameParser::DropScope(func->getName()));
Type *type = symbol_file->ResolveTypeUID(sym_id);
if (!type)
@@ -923,8 +928,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
: clang::StorageClass::SC_None;
auto decl = m_ast.CreateFunctionDeclaration(
- decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
- func->hasInlineAttribute());
+ decl_context, OptionalClangModuleID(), name.c_str(),
+ type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
std::vector<clang::ParmVarDecl *> params;
if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
@@ -937,8 +942,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
continue;
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
- decl, nullptr, arg_type->GetForwardCompilerType(),
- clang::SC_None, true);
+ decl, OptionalClangModuleID(), nullptr,
+ arg_type->GetForwardCompilerType(), clang::SC_None, true);
if (param)
params.push_back(param);
}
@@ -1047,13 +1052,13 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
// or a type. We check it to avoid fake namespaces such as `__l2':
// `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'
if (!has_type_or_function_parent) {
- std::string namespace_name = specs[i].GetBaseName();
+ std::string namespace_name = std::string(specs[i].GetBaseName());
const char *namespace_name_c_str =
IsAnonymousNamespaceName(namespace_name) ? nullptr
: namespace_name.data();
clang::NamespaceDecl *namespace_decl =
- m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
- curr_context);
+ m_ast.GetUniqueNamespaceDeclaration(
+ namespace_name_c_str, curr_context, OptionalClangModuleID());
m_parent_to_namespaces[curr_context].insert(namespace_decl);
m_namespaces.insert(namespace_decl);
@@ -1119,7 +1124,8 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type,
const PDBSymbolData &enum_value) {
Declaration decl;
Variant v = enum_value.getValue();
- std::string name = MSVCUndecoratedNameParser::DropScope(enum_value.getName());
+ std::string name =
+ std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName()));
int64_t raw_value;
switch (v.Type) {
case PDB_VariantType::Int8:
@@ -1149,8 +1155,7 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type,
default:
return false;
}
- CompilerType underlying_type =
- m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+ CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);
uint32_t byte_size = m_ast.getASTContext().getTypeSize(
ClangUtil::GetQualType(underlying_type));
auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
@@ -1190,8 +1195,8 @@ bool PDBASTParser::CompleteTypeFromUDT(
AddRecordMethods(symbol_file, compiler_type, *methods_enum);
m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());
- ClangASTContext::BuildIndirectFields(compiler_type);
- ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ TypeSystemClang::BuildIndirectFields(compiler_type);
+ TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
clang::CXXRecordDecl *record_decl =
m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
@@ -1225,8 +1230,8 @@ void PDBASTParser::AddRecordMembers(
"which does not have a complete definition.",
record_type.GetTypeName().GetCString(), member_name.c_str(),
member_comp_type.GetTypeName().GetCString());
- if (ClangASTContext::StartTagDeclarationDefinition(member_comp_type))
- ClangASTContext::CompleteTagDeclarationDefinition(member_comp_type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type))
+ TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type);
}
auto access = TranslateMemberAccess(member->getAccess());
@@ -1239,7 +1244,7 @@ void PDBASTParser::AddRecordMembers(
if (location_type == PDB_LocType::ThisRel)
bit_size *= 8;
- auto decl = ClangASTContext::AddFieldToRecordType(
+ auto decl = TypeSystemClang::AddFieldToRecordType(
record_type, member_name.c_str(), member_comp_type, access, bit_size);
if (!decl)
continue;
@@ -1255,11 +1260,57 @@ void PDBASTParser::AddRecordMembers(
break;
}
case PDB_DataKind::StaticMember: {
- auto decl = ClangASTContext::AddVariableToRecordType(
+ auto decl = TypeSystemClang::AddVariableToRecordType(
record_type, member_name.c_str(), member_comp_type, access);
if (!decl)
continue;
+ // Static constant members may be a const[expr] declaration.
+ // Query the symbol's value as the variable initializer if valid.
+ if (member_comp_type.IsConst()) {
+ auto value = member->getValue();
+ clang::QualType qual_type = decl->getType();
+ unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type);
+ unsigned constant_width = value.getBitWidth();
+
+ if (qual_type->isIntegralOrEnumerationType()) {
+ if (type_width >= constant_width) {
+ TypeSystemClang::SetIntegerInitializerForVariable(
+ decl, value.toAPSInt().extOrTrunc(type_width));
+ } else {
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),
+ "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
+ "which resolves to a wider constant value ({4} bits). "
+ "Ignoring constant.",
+ record_type.GetTypeName(), member_name,
+ member_comp_type.GetTypeName(), type_width,
+ constant_width);
+ }
+ } else {
+ switch (member_comp_type.GetBasicTypeEnumeration()) {
+ case lldb::eBasicTypeFloat:
+ case lldb::eBasicTypeDouble:
+ case lldb::eBasicTypeLongDouble:
+ if (type_width == constant_width) {
+ TypeSystemClang::SetFloatingInitializerForVariable(
+ decl, value.toAPFloat());
+ decl->setConstexpr(true);
+ } else {
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST),
+ "Class '{0}' has a member '{1}' of type '{2}' ({3} "
+ "bits) which resolves to a constant value of mismatched "
+ "width ({4} bits). Ignoring constant.",
+ record_type.GetTypeName(), member_name,
+ member_comp_type.GetTypeName(), type_width,
+ constant_width);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
m_uid_to_decl[member->getSymIndexId()] = decl;
break;
@@ -1289,8 +1340,8 @@ void PDBASTParser::AddRecordBases(
"which does not have a complete definition.",
record_type.GetTypeName().GetCString(),
base_comp_type.GetTypeName().GetCString());
- if (ClangASTContext::StartTagDeclarationDefinition(base_comp_type))
- ClangASTContext::CompleteTagDeclarationDefinition(base_comp_type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type))
+ TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type);
}
auto access = TranslateMemberAccess(base->getAccess());
@@ -1333,7 +1384,8 @@ clang::CXXMethodDecl *
PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
lldb_private::CompilerType &record_type,
const llvm::pdb::PDBSymbolFunc &method) const {
- std::string name = MSVCUndecoratedNameParser::DropScope(method.getName());
+ std::string name =
+ std::string(MSVCUndecoratedNameParser::DropScope(method.getName()));
Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());
// MSVC specific __vecDelDtor.
@@ -1346,8 +1398,8 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
":: Class '%s' has a method '%s' whose type cannot be completed.",
record_type.GetTypeName().GetCString(),
method_comp_type.GetTypeName().GetCString());
- if (ClangASTContext::StartTagDeclarationDefinition(method_comp_type))
- ClangASTContext::CompleteTagDeclarationDefinition(method_comp_type);
+ if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type))
+ TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type);
}
AccessType access = TranslateMemberAccess(method.getAccess());
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
index 9221d42b2020..06f317f4c4d9 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
-#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
#include "lldb/lldb-forward.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
class SymbolFilePDB;
@@ -23,7 +23,7 @@ class RecordDecl;
} // namespace clang
namespace lldb_private {
-class ClangASTContext;
+class TypeSystemClang;
class CompilerType;
} // namespace lldb_private
@@ -42,7 +42,7 @@ class PDBSymbolTypeUDT;
class PDBASTParser {
public:
- PDBASTParser(lldb_private::ClangASTContext &ast);
+ PDBASTParser(lldb_private::TypeSystemClang &ast);
~PDBASTParser();
lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
@@ -103,7 +103,7 @@ private:
lldb_private::CompilerType &record_type,
const llvm::pdb::PDBSymbolFunc &method) const;
- lldb_private::ClangASTContext &m_ast;
+ lldb_private::TypeSystemClang &m_ast;
lldb_private::ClangASTImporter m_ast_importer;
CXXRecordDeclToUidMap m_forward_decl_to_uid;
@@ -113,4 +113,4 @@ private:
DeclContextToUidMap m_decl_context_to_uid;
};
-#endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 42bf1b34c956..330188e29f00 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -1,4 +1,4 @@
-//===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===//
+//===-- PDBLocationToDWARFExpression.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
index 2e9d1386d537..fd0fef03e2c8 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_
-#define lldb_Plugins_SymbolFile_PDB_PDBLocationToDWARFExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_PDBLOCATIONTODWARFEXPRESSION_H
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Variable.h"
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 917ab68af418..1001514edede 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
+//===-- SymbolFilePDB.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,9 +13,9 @@
#include "clang/Lex/Lexer.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -58,6 +58,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;
+LLDB_PLUGIN_DEFINE(SymbolFilePDB)
+
char SymbolFilePDB::ID;
namespace {
@@ -310,8 +312,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
return nullptr;
}
- ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_type_system =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
@@ -560,8 +562,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
return nullptr;
}
- ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_type_system =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
PDBASTParser *pdb = clang_type_system->GetPDBParser();
@@ -597,8 +599,8 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
return false;
}
- ClangASTContext *clang_ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_ctx)
return false;
@@ -619,8 +621,8 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
return CompilerDecl();
}
- ClangASTContext *clang_ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDecl();
@@ -636,7 +638,7 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
if (!decl)
return CompilerDecl();
- return CompilerDecl(clang_ast_ctx, decl);
+ return clang_ast_ctx->GetCompilerDecl(decl);
}
lldb_private::CompilerDeclContext
@@ -649,8 +651,8 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
return CompilerDeclContext();
}
- ClangASTContext *clang_ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -679,8 +681,8 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
return CompilerDeclContext();
}
- ClangASTContext *clang_ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -708,8 +710,8 @@ void SymbolFilePDB::ParseDeclsForContext(
return;
}
- ClangASTContext *clang_ast_ctx =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ TypeSystemClang *clang_ast_ctx =
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_ast_ctx)
return;
@@ -1096,8 +1098,7 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
}
void SymbolFilePDB::FindGlobalVariables(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
@@ -1129,8 +1130,8 @@ void SymbolFilePDB::FindGlobalVariables(
if (sc.comp_unit == nullptr)
continue;
- if (parent_decl_ctx && GetDeclContextContainingUID(
- result->getSymIndexId()) != *parent_decl_ctx)
+ if (parent_decl_ctx.IsValid() &&
+ GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
continue;
ParseVariables(sc, *pdb_data, &variables);
@@ -1225,7 +1226,7 @@ void SymbolFilePDB::CacheFunctionNames() {
// To search a method name, like NS::Class:MemberFunc, LLDB searches
// its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
- // not have inforamtion of this, we extract base names and cache them
+ // not have information of this, we extract base names and cache them
// by our own effort.
llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
if (!basename.empty())
@@ -1294,7 +1295,7 @@ void SymbolFilePDB::CacheFunctionNames() {
void SymbolFilePDB::FindFunctions(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask, bool include_inlines,
lldb_private::SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
@@ -1323,8 +1324,8 @@ void SymbolFilePDB::FindFunctions(
if (resolved_ids.find(id) != resolved_ids.end())
continue;
- if (parent_decl_ctx &&
- GetDeclContextContainingUID(id) != *parent_decl_ctx)
+ if (parent_decl_ctx.IsValid() &&
+ GetDeclContextContainingUID(id) != parent_decl_ctx)
continue;
if (ResolveFunction(id, include_inlines, sc_list))
@@ -1422,8 +1423,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
}
void SymbolFilePDB::FindTypes(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) {
@@ -1450,7 +1450,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) {
}
auto *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_type_system)
return;
clang_type_system->Dump(s);
@@ -1513,7 +1513,7 @@ void SymbolFilePDB::FindTypesByRegex(
void SymbolFilePDB::FindTypesByName(
llvm::StringRef name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, lldb_private::TypeMap &types) {
std::unique_ptr<IPDBEnumSymbols> results;
if (name.empty())
@@ -1548,8 +1548,8 @@ void SymbolFilePDB::FindTypesByName(
if (!ResolveTypeUID(result->getSymIndexId()))
continue;
- if (parent_decl_ctx && GetDeclContextContainingUID(
- result->getSymIndexId()) != *parent_decl_ctx)
+ if (parent_decl_ctx.IsValid() &&
+ GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
continue;
auto iter = m_types.find(result->getSymIndexId());
@@ -1663,17 +1663,16 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
}
auto *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
return clang_type_system->GetPDBParser();
}
-
-lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) {
+lldb_private::CompilerDeclContext
+SymbolFilePDB::FindNamespace(lldb_private::ConstString name,
+ const CompilerDeclContext &parent_decl_ctx) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
@@ -1685,7 +1684,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
}
auto *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
if (!clang_type_system)
return CompilerDeclContext();
@@ -1696,7 +1695,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
clang::DeclContext *decl_context = nullptr;
if (parent_decl_ctx)
decl_context = static_cast<clang::DeclContext *>(
- parent_decl_ctx->GetOpaqueDeclContext());
+ parent_decl_ctx.GetOpaqueDeclContext());
auto namespace_decl =
pdb->FindNamespaceDecl(decl_context, name.GetStringRef());
@@ -1817,7 +1816,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
prev_source_idx, false, false, false, false, true);
line_table->InsertSequence(sequence.release());
- sequence.reset(line_table->CreateLineSequenceContainer());
+ sequence = line_table->CreateLineSequenceContainer();
}
if (ShouldAddLine(match_line, lno, length)) {
@@ -1854,7 +1853,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
prev_source_idx, false, false, false, false, true);
}
- line_table->InsertSequence(sequence.release());
+ line_table->InsertSequence(sequence.get());
}
if (line_table->GetSize()) {
@@ -1940,18 +1939,17 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
mangled.SetMangledName(ConstString(func_decorated_name));
// For MSVC, format of C funciton's decorated name depends on calling
- // conventon. Unfortunately none of the format is recognized by current
+ // convention. Unfortunately none of the format is recognized by current
// LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
// `__purecall` is retrieved as both its decorated and undecorated name
// (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`
// string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).
// Mangled::GetDemangledName method will fail internally and caches an
- // empty string as its undecorated name. So we will face a contradition
+ // empty string as its undecorated name. So we will face a contradiction
// here for the same symbol:
// non-empty undecorated name from PDB
// empty undecorated name from LLDB
- if (!func_undecorated_name.empty() &&
- mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty())
+ if (!func_undecorated_name.empty() && mangled.GetDemangledName().IsEmpty())
mangled.SetDemangledName(ConstString(func_undecorated_name));
// LLDB uses several flags to control how a C++ decorated name is
@@ -1960,8 +1958,7 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
// PDB source unless we also apply same flags in getting undecorated
// name through PDBSymbolFunc::getUndecoratedNameEx method.
if (!func_undecorated_name.empty() &&
- mangled.GetDemangledName(mangled.GuessLanguage()) !=
- ConstString(func_undecorated_name))
+ mangled.GetDemangledName() != ConstString(func_undecorated_name))
mangled.SetDemangledName(ConstString(func_undecorated_name));
} else if (!func_undecorated_name.empty()) {
mangled.SetDemangledName(ConstString(func_undecorated_name));
@@ -1972,11 +1969,11 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
}
bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
- const lldb_private::CompilerDeclContext *decl_ctx) {
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ const lldb_private::CompilerDeclContext &decl_ctx) {
+ if (!decl_ctx.IsValid())
return true;
- TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();
if (!decl_ctx_type_system)
return false;
auto type_system_or_err = GetTypeSystemForLanguage(
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 7a4eee48771a..928cbffc5f63 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
-#define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -112,7 +112,7 @@ public:
void
FindGlobalVariables(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
@@ -121,7 +121,7 @@ public:
lldb_private::VariableList &variables) override;
void FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
lldb::FunctionNameType name_type_mask,
bool include_inlines,
lldb_private::SymbolContextList &sc_list) override;
@@ -138,7 +138,7 @@ public:
void
FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
@@ -160,7 +160,7 @@ public:
lldb_private::CompilerDeclContext FindNamespace(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ const lldb_private::CompilerDeclContext &parent_decl_ctx) override;
lldb_private::ConstString GetPluginName() override;
@@ -195,7 +195,7 @@ private:
llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
void FindTypesByName(llvm::StringRef name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const lldb_private::CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, lldb_private::TypeMap &types);
std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data);
@@ -242,7 +242,7 @@ private:
void CacheFunctionNames();
bool DeclContextMatchesThisSymbolFile(
- const lldb_private::CompilerDeclContext *decl_ctx);
+ const lldb_private::CompilerDeclContext &decl_ctx);
uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data);
@@ -262,4 +262,4 @@ private:
lldb_private::UniqueCStringMap<uint32_t> m_func_method_names;
};
-#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_PDB_SYMBOLFILEPDB_H
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 305efea1afab..c4a0e609aa22 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
+//===-- SymbolFileSymtab.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,6 +25,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(SymbolFileSymtab)
+
char SymbolFileSymtab::ID;
void SymbolFileSymtab::Initialize() {
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index 1fff8188433e..9557ebbcb272 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_SymbolFileSymtab_h_
-#define liblldb_SymbolFileSymtab_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H
#include <map>
#include <vector>
@@ -106,7 +106,8 @@ protected:
TypeMap m_objc_class_types;
private:
- DISALLOW_COPY_AND_ASSIGN(SymbolFileSymtab);
+ SymbolFileSymtab(const SymbolFileSymtab &) = delete;
+ const SymbolFileSymtab &operator=(const SymbolFileSymtab &) = delete;
};
-#endif // liblldb_SymbolFileSymtab_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H
diff --git a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index d4d7a8937c12..2e6fd4365021 100644
--- a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -1,4 +1,4 @@
-//===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===//
+//===-- SymbolVendorELF.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -25,6 +25,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(SymbolVendorELF)
+
// SymbolVendorELF constructor
SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
: SymbolVendor(module_sp) {}
diff --git a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
index 0cd740da5ce3..824906c04955 100644
--- a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
+++ b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_SymbolVendorELF_h_
-#define liblldb_SymbolVendorELF_h_
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/lldb-private.h"
@@ -38,7 +38,8 @@ public:
uint32_t GetPluginVersion() override;
private:
- DISALLOW_COPY_AND_ASSIGN(SymbolVendorELF);
+ SymbolVendorELF(const SymbolVendorELF &) = delete;
+ const SymbolVendorELF &operator=(const SymbolVendorELF &) = delete;
};
-#endif // liblldb_SymbolVendorELF_h_
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H
diff --git a/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
new file mode 100644
index 000000000000..1c09dabc5622
--- /dev/null
+++ b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -0,0 +1,147 @@
+//===-- SymbolVendorWasm.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolVendorWasm.h"
+
+#include <string.h>
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(SymbolVendorWasm)
+
+// SymbolVendorWasm constructor
+SymbolVendorWasm::SymbolVendorWasm(const lldb::ModuleSP &module_sp)
+ : SymbolVendor(module_sp) {}
+
+void SymbolVendorWasm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void SymbolVendorWasm::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString SymbolVendorWasm::GetPluginNameStatic() {
+ static ConstString g_name("WASM");
+ return g_name;
+}
+
+const char *SymbolVendorWasm::GetPluginDescriptionStatic() {
+ return "Symbol vendor for WASM that looks for dwo files that match "
+ "executables.";
+}
+
+// CreateInstance
+//
+// Platforms can register a callback to use when creating symbol vendors to
+// allow for complex debug information file setups, and to also allow for
+// finding separate debug information files.
+SymbolVendor *
+SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm) {
+ if (!module_sp)
+ return nullptr;
+
+ ObjectFileWasm *obj_file =
+ llvm::dyn_cast_or_null<ObjectFileWasm>(module_sp->GetObjectFile());
+ if (!obj_file)
+ return nullptr;
+
+ // If the main object file already contains debug info, then we are done.
+ if (obj_file->GetSectionList()->FindSectionByType(
+ lldb::eSectionTypeDWARFDebugInfo, true))
+ return nullptr;
+
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(func_cat, "SymbolVendorWasm::CreateInstance (module = %s)",
+ module_sp->GetFileSpec().GetPath().c_str());
+
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = obj_file->GetFileSpec();
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ module_spec.GetUUID() = obj_file->GetUUID();
+
+ // A Wasm module may have a custom section named "external_debug_info" whose
+ // content is the absolute or relative path of the Wasm module that contains
+ // debug symbols for this module.
+ llvm::Optional<FileSpec> symbol_file_spec =
+ obj_file->GetExternalDebugInfoFileSpec();
+ if (!symbol_file_spec)
+ return nullptr;
+ module_spec.GetSymbolFileSpec() = *symbol_file_spec;
+
+ FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+ FileSpec sym_fspec =
+ Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ if (!sym_fspec)
+ return nullptr;
+
+ DataBufferSP sym_file_data_sp;
+ lldb::offset_t sym_file_data_offset = 0;
+ ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin(
+ module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec),
+ sym_file_data_sp, sym_file_data_offset);
+ if (!sym_objfile_sp)
+ return nullptr;
+
+ // This objfile is for debugging purposes.
+ sym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+ SymbolVendorWasm *symbol_vendor = new SymbolVendorWasm(module_sp);
+
+ // Get the module unified section list and add our debug sections to
+ // that.
+ SectionList *module_section_list = module_sp->GetSectionList();
+ SectionList *objfile_section_list = sym_objfile_sp->GetSectionList();
+
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
+ eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr,
+ eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists,
+ eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro,
+ eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
+ eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugRngLists,
+ eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
+ eSectionTypeDWARFDebugTypes};
+ for (SectionType section_type : g_sections) {
+ if (SectionSP section_sp =
+ objfile_section_list->FindSectionByType(section_type, true)) {
+ if (SectionSP module_section_sp =
+ module_section_list->FindSectionByType(section_type, true))
+ module_section_list->ReplaceSection(module_section_sp->GetID(),
+ section_sp);
+ else
+ module_section_list->AddSection(section_sp);
+ }
+ }
+
+ symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp);
+ return symbol_vendor;
+}
+
+// PluginInterface protocol
+ConstString SymbolVendorWasm::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t SymbolVendorWasm::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
new file mode 100644
index 000000000000..96e737b1be96
--- /dev/null
+++ b/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
@@ -0,0 +1,45 @@
+//===-- SymbolVendorWasm.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H
+
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+namespace wasm {
+
+class SymbolVendorWasm : public lldb_private::SymbolVendor {
+public:
+ SymbolVendorWasm(const lldb::ModuleSP &module_sp);
+
+ static void Initialize();
+ static void Terminate();
+ static lldb_private::ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic();
+
+ static lldb_private::SymbolVendor *
+ CreateInstance(const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
+
+ /// PluginInterface protocol.
+ /// \{
+ lldb_private::ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+ /// \}
+
+private:
+ SymbolVendorWasm(const SymbolVendorWasm &) = delete;
+ const SymbolVendorWasm &operator=(const SymbolVendorWasm &) = delete;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_WASM_SYMBOLVENDORWASM_H
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
new file mode 100644
index 000000000000..bc06ea8164d4
--- /dev/null
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -0,0 +1,9587 @@
+//===-- TypeSystemClang.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TypeSystemClang.h"
+
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Mangle.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/VTableBuilder.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LangStandard.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/ModuleMap.h"
+#include "clang/Sema/Sema.h"
+
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Threading.h"
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
+#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
+#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Flags.h"
+
+#include "lldb/Core/DumpDataExtractor.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Scalar.h"
+
+#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
+#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
+
+#include <stdio.h>
+
+#include <mutex>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace clang;
+using llvm::StringSwitch;
+
+LLDB_PLUGIN_DEFINE(TypeSystemClang)
+
+namespace {
+static void VerifyDecl(clang::Decl *decl) {
+ assert(decl && "VerifyDecl called with nullptr?");
+#ifndef NDEBUG
+ // We don't care about the actual access value here but only want to trigger
+ // that Clang calls its internal Decl::AccessDeclContextSanity check.
+ decl->getAccess();
+#endif
+}
+
+static inline bool
+TypeSystemClangSupportsLanguage(lldb::LanguageType language) {
+ return language == eLanguageTypeUnknown || // Clang is the default type system
+ lldb_private::Language::LanguageIsC(language) ||
+ lldb_private::Language::LanguageIsCPlusPlus(language) ||
+ lldb_private::Language::LanguageIsObjC(language) ||
+ lldb_private::Language::LanguageIsPascal(language) ||
+ // Use Clang for Rust until there is a proper language plugin for it
+ language == eLanguageTypeRust ||
+ language == eLanguageTypeExtRenderScript ||
+ // Use Clang for D until there is a proper language plugin for it
+ language == eLanguageTypeD ||
+ // Open Dylan compiler debug info is designed to be Clang-compatible
+ language == eLanguageTypeDylan;
+}
+
+// Checks whether m1 is an overload of m2 (as opposed to an override). This is
+// called by addOverridesForMethod to distinguish overrides (which share a
+// vtable entry) from overloads (which require distinct entries).
+bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
+ // FIXME: This should detect covariant return types, but currently doesn't.
+ lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
+ "Methods should have the same AST context");
+ clang::ASTContext &context = m1->getASTContext();
+
+ const auto *m1Type = llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m1->getType()));
+
+ const auto *m2Type = llvm::cast<clang::FunctionProtoType>(
+ context.getCanonicalType(m2->getType()));
+
+ auto compareArgTypes = [&context](const clang::QualType &m1p,
+ const clang::QualType &m2p) {
+ return context.hasSameType(m1p.getUnqualifiedType(),
+ m2p.getUnqualifiedType());
+ };
+
+ // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
+ // as a fourth parameter to std::equal().
+ return (m1->getNumParams() != m2->getNumParams()) ||
+ !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
+ m2Type->param_type_begin(), compareArgTypes);
+}
+
+// If decl is a virtual method, walk the base classes looking for methods that
+// decl overrides. This table of overridden methods is used by IRGen to
+// determine the vtable layout for decl's parent class.
+void addOverridesForMethod(clang::CXXMethodDecl *decl) {
+ if (!decl->isVirtual())
+ return;
+
+ clang::CXXBasePaths paths;
+
+ auto find_overridden_methods =
+ [decl](const clang::CXXBaseSpecifier *specifier,
+ clang::CXXBasePath &path) {
+ if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
+ specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
+
+ clang::DeclarationName name = decl->getDeclName();
+
+ // If this is a destructor, check whether the base class destructor is
+ // virtual.
+ if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
+ if (auto *baseDtorDecl = base_record->getDestructor()) {
+ if (baseDtorDecl->isVirtual()) {
+ path.Decls = baseDtorDecl;
+ return true;
+ } else
+ return false;
+ }
+
+ // Otherwise, search for name in the base class.
+ for (path.Decls = base_record->lookup(name); !path.Decls.empty();
+ path.Decls = path.Decls.slice(1)) {
+ if (auto *method_decl =
+ llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+ if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
+ path.Decls = method_decl;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
+ for (auto *overridden_decl : paths.found_decls())
+ decl->addOverriddenMethod(
+ llvm::cast<clang::CXXMethodDecl>(overridden_decl));
+ }
+}
+}
+
+static lldb::addr_t GetVTableAddress(Process &process,
+ VTableContextBase &vtable_ctx,
+ ValueObject &valobj,
+ const ASTRecordLayout &record_layout) {
+ // Retrieve type info
+ CompilerType pointee_type;
+ CompilerType this_type(valobj.GetCompilerType());
+ uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
+ if (!type_info)
+ return LLDB_INVALID_ADDRESS;
+
+ // Check if it's a pointer or reference
+ bool ptr_or_ref = false;
+ if (type_info & (eTypeIsPointer | eTypeIsReference)) {
+ ptr_or_ref = true;
+ type_info = pointee_type.GetTypeInfo();
+ }
+
+ // We process only C++ classes
+ const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
+ if ((type_info & cpp_class) != cpp_class)
+ return LLDB_INVALID_ADDRESS;
+
+ // Calculate offset to VTable pointer
+ lldb::offset_t vbtable_ptr_offset =
+ vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity()
+ : 0;
+
+ if (ptr_or_ref) {
+ // We have a pointer / ref to object, so read
+ // VTable pointer from process memory
+
+ if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad)
+ return LLDB_INVALID_ADDRESS;
+
+ auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ vbtable_ptr_addr += vbtable_ptr_offset;
+
+ Status err;
+ return process.ReadPointerFromMemory(vbtable_ptr_addr, err);
+ }
+
+ // We have an object already read from process memory,
+ // so just extract VTable pointer from it
+
+ DataExtractor data;
+ Status err;
+ auto size = valobj.GetData(data, err);
+ if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size)
+ return LLDB_INVALID_ADDRESS;
+
+ return data.GetAddress(&vbtable_ptr_offset);
+}
+
+static int64_t ReadVBaseOffsetFromVTable(Process &process,
+ VTableContextBase &vtable_ctx,
+ lldb::addr_t vtable_ptr,
+ const CXXRecordDecl *cxx_record_decl,
+ const CXXRecordDecl *base_class_decl) {
+ if (vtable_ctx.isMicrosoft()) {
+ clang::MicrosoftVTableContext &msoft_vtable_ctx =
+ static_cast<clang::MicrosoftVTableContext &>(vtable_ctx);
+
+ // Get the index into the virtual base table. The
+ // index is the index in uint32_t from vbtable_ptr
+ const unsigned vbtable_index =
+ msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl);
+ const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4;
+ Status err;
+ return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX,
+ err);
+ }
+
+ clang::ItaniumVTableContext &itanium_vtable_ctx =
+ static_cast<clang::ItaniumVTableContext &>(vtable_ctx);
+
+ clang::CharUnits base_offset_offset =
+ itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl,
+ base_class_decl);
+ const lldb::addr_t base_offset_addr =
+ vtable_ptr + base_offset_offset.getQuantity();
+ const uint32_t base_offset_size = process.GetAddressByteSize();
+ Status err;
+ return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size,
+ INT64_MAX, err);
+}
+
+static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx,
+ ValueObject &valobj,
+ const ASTRecordLayout &record_layout,
+ const CXXRecordDecl *cxx_record_decl,
+ const CXXRecordDecl *base_class_decl,
+ int32_t &bit_offset) {
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return false;
+
+ lldb::addr_t vtable_ptr =
+ GetVTableAddress(*process, vtable_ctx, valobj, record_layout);
+ if (vtable_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ auto base_offset = ReadVBaseOffsetFromVTable(
+ *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl);
+ if (base_offset == INT64_MAX)
+ return false;
+
+ bit_offset = base_offset * 8;
+
+ return true;
+}
+
+typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, TypeSystemClang *>
+ ClangASTMap;
+
+static ClangASTMap &GetASTMap() {
+ static ClangASTMap *g_map_ptr = nullptr;
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
+ g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
+ });
+ return *g_map_ptr;
+}
+
+TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module,
+ bool is_complete_objc_class)
+ : m_payload(owning_module.GetValue()) {
+ SetIsCompleteObjCClass(is_complete_objc_class);
+}
+
+void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) {
+ assert(id.GetValue() < ObjCClassBit);
+ bool is_complete = IsCompleteObjCClass();
+ m_payload = id.GetValue();
+ SetIsCompleteObjCClass(is_complete);
+}
+
+static void SetMemberOwningModule(clang::Decl *member,
+ const clang::Decl *parent) {
+ if (!member || !parent)
+ return;
+
+ OptionalClangModuleID id(parent->getOwningModuleID());
+ if (!id.HasValue())
+ return;
+
+ member->setFromASTFile();
+ member->setOwningModuleID(id.GetValue());
+ member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+ if (llvm::isa<clang::NamedDecl>(member))
+ if (auto *dc = llvm::dyn_cast<clang::DeclContext>(parent)) {
+ dc->setHasExternalVisibleStorage(true);
+ // This triggers ExternalASTSource::FindExternalVisibleDeclsByName() to be
+ // called when searching for members.
+ dc->setHasExternalLexicalStorage(true);
+ }
+}
+
+char TypeSystemClang::ID;
+
+bool TypeSystemClang::IsOperator(llvm::StringRef name,
+ clang::OverloadedOperatorKind &op_kind) {
+ // All operators have to start with "operator".
+ if (!name.consume_front("operator"))
+ return false;
+
+ // Remember if there was a space after "operator". This is necessary to
+ // check for collisions with strangely named functions like "operatorint()".
+ bool space_after_operator = name.consume_front(" ");
+
+ op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
+ .Case("+", clang::OO_Plus)
+ .Case("+=", clang::OO_PlusEqual)
+ .Case("++", clang::OO_PlusPlus)
+ .Case("-", clang::OO_Minus)
+ .Case("-=", clang::OO_MinusEqual)
+ .Case("--", clang::OO_MinusMinus)
+ .Case("->", clang::OO_Arrow)
+ .Case("->*", clang::OO_ArrowStar)
+ .Case("*", clang::OO_Star)
+ .Case("*=", clang::OO_StarEqual)
+ .Case("/", clang::OO_Slash)
+ .Case("/=", clang::OO_SlashEqual)
+ .Case("%", clang::OO_Percent)
+ .Case("%=", clang::OO_PercentEqual)
+ .Case("^", clang::OO_Caret)
+ .Case("^=", clang::OO_CaretEqual)
+ .Case("&", clang::OO_Amp)
+ .Case("&=", clang::OO_AmpEqual)
+ .Case("&&", clang::OO_AmpAmp)
+ .Case("|", clang::OO_Pipe)
+ .Case("|=", clang::OO_PipeEqual)
+ .Case("||", clang::OO_PipePipe)
+ .Case("~", clang::OO_Tilde)
+ .Case("!", clang::OO_Exclaim)
+ .Case("!=", clang::OO_ExclaimEqual)
+ .Case("=", clang::OO_Equal)
+ .Case("==", clang::OO_EqualEqual)
+ .Case("<", clang::OO_Less)
+ .Case("<<", clang::OO_LessLess)
+ .Case("<<=", clang::OO_LessLessEqual)
+ .Case("<=", clang::OO_LessEqual)
+ .Case(">", clang::OO_Greater)
+ .Case(">>", clang::OO_GreaterGreater)
+ .Case(">>=", clang::OO_GreaterGreaterEqual)
+ .Case(">=", clang::OO_GreaterEqual)
+ .Case("()", clang::OO_Call)
+ .Case("[]", clang::OO_Subscript)
+ .Case(",", clang::OO_Comma)
+ .Default(clang::NUM_OVERLOADED_OPERATORS);
+
+ // We found a fitting operator, so we can exit now.
+ if (op_kind != clang::NUM_OVERLOADED_OPERATORS)
+ return true;
+
+ // After the "operator " or "operator" part is something unknown. This means
+ // it's either one of the named operators (new/delete), a conversion operator
+ // (e.g. operator bool) or a function which name starts with "operator"
+ // (e.g. void operatorbool).
+
+ // If it's a function that starts with operator it can't have a space after
+ // "operator" because identifiers can't contain spaces.
+ // E.g. "operator int" (conversion operator)
+ // vs. "operatorint" (function with colliding name).
+ if (!space_after_operator)
+ return false; // not an operator.
+
+ // Now the operator is either one of the named operators or a conversion
+ // operator.
+ op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
+ .Case("new", clang::OO_New)
+ .Case("new[]", clang::OO_Array_New)
+ .Case("delete", clang::OO_Delete)
+ .Case("delete[]", clang::OO_Array_Delete)
+ // conversion operators hit this case.
+ .Default(clang::NUM_OVERLOADED_OPERATORS);
+
+ return true;
+}
+
+clang::AccessSpecifier
+TypeSystemClang::ConvertAccessTypeToAccessSpecifier(AccessType access) {
+ switch (access) {
+ default:
+ break;
+ case eAccessNone:
+ return AS_none;
+ case eAccessPublic:
+ return AS_public;
+ case eAccessPrivate:
+ return AS_private;
+ case eAccessProtected:
+ return AS_protected;
+ }
+ return AS_none;
+}
+
+static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
+ // FIXME: Cleanup per-file based stuff.
+
+ // Set some properties which depend solely on the input kind; it would be
+ // nice to move these to the language standard, and have the driver resolve
+ // the input kind + language standard.
+ if (IK.getLanguage() == clang::Language::Asm) {
+ Opts.AsmPreprocessor = 1;
+ } else if (IK.isObjectiveC()) {
+ Opts.ObjC = 1;
+ }
+
+ LangStandard::Kind LangStd = LangStandard::lang_unspecified;
+
+ if (LangStd == LangStandard::lang_unspecified) {
+ // Based on the base language, pick one.
+ switch (IK.getLanguage()) {
+ case clang::Language::Unknown:
+ case clang::Language::LLVM_IR:
+ case clang::Language::RenderScript:
+ llvm_unreachable("Invalid input kind!");
+ case clang::Language::OpenCL:
+ LangStd = LangStandard::lang_opencl10;
+ break;
+ case clang::Language::CUDA:
+ LangStd = LangStandard::lang_cuda;
+ break;
+ case clang::Language::Asm:
+ case clang::Language::C:
+ case clang::Language::ObjC:
+ LangStd = LangStandard::lang_gnu99;
+ break;
+ case clang::Language::CXX:
+ case clang::Language::ObjCXX:
+ LangStd = LangStandard::lang_gnucxx98;
+ break;
+ case clang::Language::HIP:
+ LangStd = LangStandard::lang_hip;
+ break;
+ }
+ }
+
+ const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+ Opts.LineComment = Std.hasLineComments();
+ Opts.C99 = Std.isC99();
+ Opts.CPlusPlus = Std.isCPlusPlus();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
+ Opts.Digraphs = Std.hasDigraphs();
+ Opts.GNUMode = Std.isGNUMode();
+ Opts.GNUInline = !Std.isC99();
+ Opts.HexFloats = Std.hasHexFloats();
+ Opts.ImplicitInt = Std.hasImplicitInt();
+
+ Opts.WChar = true;
+
+ // OpenCL has some additional defaults.
+ if (LangStd == LangStandard::lang_opencl10) {
+ Opts.OpenCL = 1;
+ Opts.AltiVec = 1;
+ Opts.CXXOperatorNames = 1;
+ Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All);
+ }
+
+ // OpenCL and C++ both have bool, true, false keywords.
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+
+ Opts.setValueVisibilityMode(DefaultVisibility);
+
+ // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
+ // specified, or -std is set to a conforming mode.
+ Opts.Trigraphs = !Opts.GNUMode;
+ Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
+ Opts.OptimizeSize = 0;
+
+ // FIXME: Eliminate this dependency.
+ // unsigned Opt =
+ // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
+ // Opts.Optimize = Opt != 0;
+ unsigned Opt = 0;
+
+ // This is the __NO_INLINE__ define, which just depends on things like the
+ // optimization level and -fno-inline, not actually whether the backend has
+ // inlining enabled.
+ //
+ // FIXME: This is affected by other options (-fno-inline).
+ Opts.NoInlineDefine = !Opt;
+
+ // This is needed to allocate the extra space for the owning module
+ // on each decl.
+ Opts.ModulesLocalVisibility = 1;
+}
+
+TypeSystemClang::TypeSystemClang(llvm::StringRef name,
+ llvm::Triple target_triple) {
+ m_display_name = name.str();
+ if (!target_triple.str().empty())
+ SetTargetTriple(target_triple.str());
+ // The caller didn't pass an ASTContext so create a new one for this
+ // TypeSystemClang.
+ CreateASTContext();
+}
+
+TypeSystemClang::TypeSystemClang(llvm::StringRef name,
+ ASTContext &existing_ctxt) {
+ m_display_name = name.str();
+ SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str());
+
+ m_ast_up.reset(&existing_ctxt);
+ GetASTMap().Insert(&existing_ctxt, this);
+}
+
+// Destructor
+TypeSystemClang::~TypeSystemClang() { Finalize(); }
+
+ConstString TypeSystemClang::GetPluginNameStatic() {
+ return ConstString("clang");
+}
+
+ConstString TypeSystemClang::GetPluginName() {
+ return TypeSystemClang::GetPluginNameStatic();
+}
+
+uint32_t TypeSystemClang::GetPluginVersion() { return 1; }
+
+lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language,
+ lldb_private::Module *module,
+ Target *target) {
+ if (!TypeSystemClangSupportsLanguage(language))
+ return lldb::TypeSystemSP();
+ ArchSpec arch;
+ if (module)
+ arch = module->GetArchitecture();
+ else if (target)
+ arch = target->GetArchitecture();
+
+ if (!arch.IsValid())
+ return lldb::TypeSystemSP();
+
+ llvm::Triple triple = arch.GetTriple();
+ // LLVM wants this to be set to iOS or MacOSX; if we're working on
+ // a bare-boards type image, change the triple for llvm's benefit.
+ if (triple.getVendor() == llvm::Triple::Apple &&
+ triple.getOS() == llvm::Triple::UnknownOS) {
+ if (triple.getArch() == llvm::Triple::arm ||
+ triple.getArch() == llvm::Triple::aarch64 ||
+ triple.getArch() == llvm::Triple::aarch64_32 ||
+ triple.getArch() == llvm::Triple::thumb) {
+ triple.setOS(llvm::Triple::IOS);
+ } else {
+ triple.setOS(llvm::Triple::MacOSX);
+ }
+ }
+
+ if (module) {
+ std::string ast_name =
+ "ASTContext for '" + module->GetFileSpec().GetPath() + "'";
+ return std::make_shared<TypeSystemClang>(ast_name, triple);
+ } else if (target && target->IsValid())
+ return std::make_shared<TypeSystemClangForExpressions>(*target, triple);
+ return lldb::TypeSystemSP();
+}
+
+LanguageSet TypeSystemClang::GetSupportedLanguagesForTypes() {
+ LanguageSet languages;
+ languages.Insert(lldb::eLanguageTypeC89);
+ languages.Insert(lldb::eLanguageTypeC);
+ languages.Insert(lldb::eLanguageTypeC11);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus);
+ languages.Insert(lldb::eLanguageTypeC99);
+ languages.Insert(lldb::eLanguageTypeObjC);
+ languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
+ languages.Insert(lldb::eLanguageTypeC11);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
+ return languages;
+}
+
+LanguageSet TypeSystemClang::GetSupportedLanguagesForExpressions() {
+ LanguageSet languages;
+ languages.Insert(lldb::eLanguageTypeC_plus_plus);
+ languages.Insert(lldb::eLanguageTypeObjC_plus_plus);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_03);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_11);
+ languages.Insert(lldb::eLanguageTypeC_plus_plus_14);
+ return languages;
+}
+
+void TypeSystemClang::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance,
+ GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions());
+}
+
+void TypeSystemClang::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+void TypeSystemClang::Finalize() {
+ assert(m_ast_up);
+ GetASTMap().Erase(m_ast_up.get());
+ if (!m_ast_owned)
+ m_ast_up.release();
+
+ m_builtins_up.reset();
+ m_selector_table_up.reset();
+ m_identifier_table_up.reset();
+ m_target_info_up.reset();
+ m_target_options_rp.reset();
+ m_diagnostics_engine_up.reset();
+ m_source_manager_up.reset();
+ m_language_options_up.reset();
+}
+
+void TypeSystemClang::setSema(Sema *s) {
+ // Ensure that the new sema actually belongs to our ASTContext.
+ assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
+ m_sema = s;
+}
+
+const char *TypeSystemClang::GetTargetTriple() {
+ return m_target_triple.c_str();
+}
+
+void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) {
+ m_target_triple = target_triple.str();
+}
+
+void TypeSystemClang::SetExternalSource(
+ llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
+ ASTContext &ast = getASTContext();
+ ast.setExternalSource(ast_source_up);
+ ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+}
+
+ASTContext &TypeSystemClang::getASTContext() {
+ assert(m_ast_up);
+ return *m_ast_up;
+}
+
+class NullDiagnosticConsumer : public DiagnosticConsumer {
+public:
+ NullDiagnosticConsumer() {
+ m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ }
+
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &info) override {
+ if (m_log) {
+ llvm::SmallVector<char, 32> diag_str(10);
+ info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
+ }
+ }
+
+ DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+ return new NullDiagnosticConsumer();
+ }
+
+private:
+ Log *m_log;
+};
+
+void TypeSystemClang::CreateASTContext() {
+ assert(!m_ast_up);
+ m_ast_owned = true;
+
+ m_language_options_up = std::make_unique<LangOptions>();
+ ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
+ GetTargetTriple());
+
+ m_identifier_table_up =
+ std::make_unique<IdentifierTable>(*m_language_options_up, nullptr);
+ m_builtins_up = std::make_unique<Builtin::Context>();
+
+ m_selector_table_up = std::make_unique<SelectorTable>();
+
+ clang::FileSystemOptions file_system_options;
+ m_file_manager_up = std::make_unique<clang::FileManager>(
+ file_system_options, FileSystem::Instance().GetVirtualFileSystem());
+
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
+ m_diagnostics_engine_up =
+ std::make_unique<DiagnosticsEngine>(diag_id_sp, new DiagnosticOptions());
+
+ m_source_manager_up = std::make_unique<clang::SourceManager>(
+ *m_diagnostics_engine_up, *m_file_manager_up);
+ m_ast_up = std::make_unique<ASTContext>(
+ *m_language_options_up, *m_source_manager_up, *m_identifier_table_up,
+ *m_selector_table_up, *m_builtins_up);
+
+ m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>();
+ m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false);
+
+ // This can be NULL if we don't know anything about the architecture or if
+ // the target for an architecture isn't enabled in the llvm/clang that we
+ // built
+ TargetInfo *target_info = getTargetInfo();
+ if (target_info)
+ m_ast_up->InitBuiltinTypes(*target_info);
+
+ GetASTMap().Insert(m_ast_up.get(), this);
+
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
+ new ClangExternalASTSourceCallbacks(*this));
+ SetExternalSource(ast_source_up);
+}
+
+TypeSystemClang *TypeSystemClang::GetASTContext(clang::ASTContext *ast) {
+ TypeSystemClang *clang_ast = GetASTMap().Lookup(ast);
+ return clang_ast;
+}
+
+clang::MangleContext *TypeSystemClang::getMangleContext() {
+ if (m_mangle_ctx_up == nullptr)
+ m_mangle_ctx_up.reset(getASTContext().createMangleContext());
+ return m_mangle_ctx_up.get();
+}
+
+std::shared_ptr<clang::TargetOptions> &TypeSystemClang::getTargetOptions() {
+ if (m_target_options_rp == nullptr && !m_target_triple.empty()) {
+ m_target_options_rp = std::make_shared<clang::TargetOptions>();
+ if (m_target_options_rp != nullptr)
+ m_target_options_rp->Triple = m_target_triple;
+ }
+ return m_target_options_rp;
+}
+
+TargetInfo *TypeSystemClang::getTargetInfo() {
+ // target_triple should be something like "x86_64-apple-macosx"
+ if (m_target_info_up == nullptr && !m_target_triple.empty())
+ m_target_info_up.reset(TargetInfo::CreateTargetInfo(
+ getASTContext().getDiagnostics(), getTargetOptions()));
+ return m_target_info_up.get();
+}
+
+#pragma mark Basic Types
+
+static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
+ ASTContext &ast, QualType qual_type) {
+ uint64_t qual_type_bit_size = ast.getTypeSize(qual_type);
+ return qual_type_bit_size == bit_size;
+}
+
+CompilerType
+TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
+ size_t bit_size) {
+ ASTContext &ast = getASTContext();
+ switch (encoding) {
+ case eEncodingInvalid:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy))
+ return GetType(ast.VoidPtrTy);
+ break;
+
+ case eEncodingUint:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
+ return GetType(ast.UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
+ return GetType(ast.UnsignedLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy))
+ return GetType(ast.UnsignedLongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty))
+ return GetType(ast.UnsignedInt128Ty);
+ break;
+
+ case eEncodingSint:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy))
+ return GetType(ast.SignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
+ return GetType(ast.ShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
+ return GetType(ast.IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
+ return GetType(ast.LongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
+ return GetType(ast.LongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty))
+ return GetType(ast.Int128Ty);
+ break;
+
+ case eEncodingIEEE754:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
+ return GetType(ast.FloatTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
+ return GetType(ast.DoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
+ return GetType(ast.LongDoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy))
+ return GetType(ast.HalfTy);
+ break;
+
+ case eEncodingVector:
+ // Sanity check that bit_size is a multiple of 8's.
+ if (bit_size && !(bit_size & 0x7u))
+ return GetType(ast.getExtVectorType(ast.UnsignedCharTy, bit_size / 8));
+ break;
+ }
+
+ return CompilerType();
+}
+
+lldb::BasicType
+TypeSystemClang::GetBasicTypeEnumeration(ConstString name) {
+ if (name) {
+ typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+ static TypeNameToBasicTypeMap g_type_map;
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
+ // "void"
+ g_type_map.Append(ConstString("void"), eBasicTypeVoid);
+
+ // "char"
+ g_type_map.Append(ConstString("char"), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t"),
+ eBasicTypeUnsignedWChar);
+ // "short"
+ g_type_map.Append(ConstString("short"), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int"), eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int"),
+ eBasicTypeUnsignedShort);
+
+ // "int"
+ g_type_map.Append(ConstString("int"), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);
+
+ // "long"
+ g_type_map.Append(ConstString("long"), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int"), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int"),
+ eBasicTypeUnsignedLong);
+
+ // "long long"
+ g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long"),
+ eBasicTypeUnsignedLongLong);
+ g_type_map.Append(ConstString("unsigned long long int"),
+ eBasicTypeUnsignedLongLong);
+
+ // "int128"
+ g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);
+
+ // Miscellaneous
+ g_type_map.Append(ConstString("bool"), eBasicTypeBool);
+ g_type_map.Append(ConstString("float"), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double"), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
+ g_type_map.Sort();
+ });
+
+ return g_type_map.Find(name, eBasicTypeInvalid);
+ }
+ return eBasicTypeInvalid;
+}
+
+uint32_t TypeSystemClang::GetPointerByteSize() {
+ if (m_pointer_byte_size == 0)
+ if (auto size = GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType()
+ .GetByteSize(nullptr))
+ m_pointer_byte_size = *size;
+ return m_pointer_byte_size;
+}
+
+CompilerType TypeSystemClang::GetBasicType(lldb::BasicType basic_type) {
+ clang::ASTContext &ast = getASTContext();
+
+ lldb::opaque_compiler_type_t clang_type =
+ GetOpaqueCompilerType(&ast, basic_type);
+
+ if (clang_type)
+ return CompilerType(this, clang_type);
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
+ llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) {
+ ASTContext &ast = getASTContext();
+
+ switch (dw_ate) {
+ default:
+ break;
+
+ case DW_ATE_address:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy))
+ return GetType(ast.VoidPtrTy);
+ break;
+
+ case DW_ATE_boolean:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.BoolTy))
+ return GetType(ast.BoolTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
+ return GetType(ast.UnsignedIntTy);
+ break;
+
+ case DW_ATE_lo_user:
+ // This has been seen to mean DW_AT_complex_integer
+ if (type_name.contains("complex")) {
+ CompilerType complex_int_clang_type =
+ GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
+ bit_size / 2);
+ return GetType(
+ ast.getComplexType(ClangUtil::GetQualType(complex_int_clang_type)));
+ }
+ break;
+
+ case DW_ATE_complex_float:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatComplexTy))
+ return GetType(ast.FloatComplexTy);
+ else if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleComplexTy))
+ return GetType(ast.DoubleComplexTy);
+ else if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleComplexTy))
+ return GetType(ast.LongDoubleComplexTy);
+ else {
+ CompilerType complex_float_clang_type =
+ GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
+ bit_size / 2);
+ return GetType(
+ ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type)));
+ }
+ break;
+
+ case DW_ATE_float:
+ if (type_name == "float" &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
+ return GetType(ast.FloatTy);
+ if (type_name == "double" &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
+ return GetType(ast.DoubleTy);
+ if (type_name == "long double" &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
+ return GetType(ast.LongDoubleTy);
+ // Fall back to not requiring a name match
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
+ return GetType(ast.FloatTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy))
+ return GetType(ast.DoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
+ return GetType(ast.LongDoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy))
+ return GetType(ast.HalfTy);
+ break;
+
+ case DW_ATE_signed:
+ if (!type_name.empty()) {
+ if (type_name == "wchar_t" &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy) &&
+ (getTargetInfo() &&
+ TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
+ return GetType(ast.WCharTy);
+ if (type_name == "void" &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.VoidTy))
+ return GetType(ast.VoidTy);
+ if (type_name.contains("long long") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
+ return GetType(ast.LongLongTy);
+ if (type_name.contains("long") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
+ return GetType(ast.LongTy);
+ if (type_name.contains("short") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
+ return GetType(ast.ShortTy);
+ if (type_name.contains("char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy))
+ return GetType(ast.CharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy))
+ return GetType(ast.SignedCharTy);
+ }
+ if (type_name.contains("int")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
+ return GetType(ast.IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty))
+ return GetType(ast.Int128Ty);
+ }
+ }
+ // We weren't able to match up a type name, just search by size
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy))
+ return GetType(ast.CharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy))
+ return GetType(ast.ShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy))
+ return GetType(ast.IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy))
+ return GetType(ast.LongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy))
+ return GetType(ast.LongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty))
+ return GetType(ast.Int128Ty);
+ break;
+
+ case DW_ATE_signed_char:
+ if (ast.getLangOpts().CharIsSigned && type_name == "char") {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy))
+ return GetType(ast.CharTy);
+ }
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy))
+ return GetType(ast.SignedCharTy);
+ break;
+
+ case DW_ATE_unsigned:
+ if (!type_name.empty()) {
+ if (type_name == "wchar_t") {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy)) {
+ if (!(getTargetInfo() &&
+ TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
+ return GetType(ast.WCharTy);
+ }
+ }
+ if (type_name.contains("long long")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy))
+ return GetType(ast.UnsignedLongLongTy);
+ } else if (type_name.contains("long")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
+ return GetType(ast.UnsignedLongTy);
+ } else if (type_name.contains("short")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+ } else if (type_name.contains("char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+ } else if (type_name.contains("int")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
+ return GetType(ast.UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty))
+ return GetType(ast.UnsignedInt128Ty);
+ }
+ }
+ // We weren't able to match up a type name, just search by size
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy))
+ return GetType(ast.UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy))
+ return GetType(ast.UnsignedLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy))
+ return GetType(ast.UnsignedLongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty))
+ return GetType(ast.UnsignedInt128Ty);
+ break;
+
+ case DW_ATE_unsigned_char:
+ if (!ast.getLangOpts().CharIsSigned && type_name == "char") {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy))
+ return GetType(ast.CharTy);
+ }
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+ break;
+
+ case DW_ATE_imaginary_float:
+ break;
+
+ case DW_ATE_UTF:
+ switch (bit_size) {
+ case 8:
+ return GetType(ast.Char8Ty);
+ case 16:
+ return GetType(ast.Char16Ty);
+ case 32:
+ return GetType(ast.Char32Ty);
+ default:
+ if (!type_name.empty()) {
+ if (type_name == "char16_t")
+ return GetType(ast.Char16Ty);
+ if (type_name == "char32_t")
+ return GetType(ast.Char32Ty);
+ if (type_name == "char8_t")
+ return GetType(ast.Char8Ty);
+ }
+ }
+ break;
+ }
+ // This assert should fire for anything that we don't catch above so we know
+ // to fix any issues we run into.
+ if (!type_name.empty()) {
+ std::string type_name_str = type_name.str();
+ Host::SystemLog(Host::eSystemLogError,
+ "error: need to add support for DW_TAG_base_type '%s' "
+ "encoded with DW_ATE = 0x%x, bit_size = %u\n",
+ type_name_str.c_str(), dw_ate, bit_size);
+ } else {
+ Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
+ "DW_TAG_base_type encoded with "
+ "DW_ATE = 0x%x, bit_size = %u\n",
+ dw_ate, bit_size);
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetCStringType(bool is_const) {
+ ASTContext &ast = getASTContext();
+ QualType char_type(ast.CharTy);
+
+ if (is_const)
+ char_type.addConst();
+
+ return GetType(ast.getPointerType(char_type));
+}
+
+bool TypeSystemClang::AreTypesSame(CompilerType type1, CompilerType type2,
+ bool ignore_qualifiers) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(type1.GetTypeSystem());
+ if (!ast || ast != type2.GetTypeSystem())
+ return false;
+
+ if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
+ return true;
+
+ QualType type1_qual = ClangUtil::GetQualType(type1);
+ QualType type2_qual = ClangUtil::GetQualType(type2);
+
+ if (ignore_qualifiers) {
+ type1_qual = type1_qual.getUnqualifiedType();
+ type2_qual = type2_qual.getUnqualifiedType();
+ }
+
+ return ast->getASTContext().hasSameType(type1_qual, type2_qual);
+}
+
+CompilerType TypeSystemClang::GetTypeForDecl(void *opaque_decl) {
+ if (!opaque_decl)
+ return CompilerType();
+
+ clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl);
+ if (auto *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl))
+ return GetTypeForDecl(named_decl);
+ return CompilerType();
+}
+
+CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) {
+ // Check that the DeclContext actually belongs to this ASTContext.
+ assert(&ctx->getParentASTContext() == &getASTContext());
+ return CompilerDeclContext(this, ctx);
+}
+
+CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) {
+ if (clang::ObjCInterfaceDecl *interface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
+ return GetTypeForDecl(interface_decl);
+ if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
+ return GetTypeForDecl(tag_decl);
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetTypeForDecl(TagDecl *decl) {
+ return GetType(getASTContext().getTagDeclType(decl));
+}
+
+CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
+ return GetType(getASTContext().getObjCInterfaceType(decl));
+}
+
+#pragma mark Structure, Unions, Classes
+
+void TypeSystemClang::SetOwningModule(clang::Decl *decl,
+ OptionalClangModuleID owning_module) {
+ if (!decl || !owning_module.HasValue())
+ return;
+
+ decl->setFromASTFile();
+ decl->setOwningModuleID(owning_module.GetValue());
+ decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
+}
+
+OptionalClangModuleID
+TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
+ OptionalClangModuleID parent,
+ bool is_framework, bool is_explicit) {
+ // Get the external AST source which holds the modules.
+ auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getASTContext().getExternalSource());
+ assert(ast_source && "external ast source was lost");
+ if (!ast_source)
+ return {};
+
+ // Lazily initialize the module map.
+ if (!m_header_search_up) {
+ auto HSOpts = std::make_shared<clang::HeaderSearchOptions>();
+ m_header_search_up = std::make_unique<clang::HeaderSearch>(
+ HSOpts, *m_source_manager_up, *m_diagnostics_engine_up,
+ *m_language_options_up, m_target_info_up.get());
+ m_module_map_up = std::make_unique<clang::ModuleMap>(
+ *m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up,
+ m_target_info_up.get(), *m_header_search_up);
+ }
+
+ // Get or create the module context.
+ bool created;
+ clang::Module *module;
+ auto parent_desc = ast_source->getSourceDescriptor(parent.GetValue());
+ std::tie(module, created) = m_module_map_up->findOrCreateModule(
+ name, parent_desc ? parent_desc->getModuleOrNull() : nullptr,
+ is_framework, is_explicit);
+ if (!created)
+ return ast_source->GetIDForModule(module);
+
+ return ast_source->RegisterModule(module);
+}
+
+CompilerType TypeSystemClang::CreateRecordType(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ AccessType access_type, llvm::StringRef name, int kind,
+ LanguageType language, ClangASTMetadata *metadata, bool exports_symbols) {
+ ASTContext &ast = getASTContext();
+
+ if (decl_ctx == nullptr)
+ decl_ctx = ast.getTranslationUnitDecl();
+
+ if (language == eLanguageTypeObjC ||
+ language == eLanguageTypeObjC_plus_plus) {
+ bool isForwardDecl = true;
+ bool isInternal = false;
+ return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl,
+ isInternal, metadata);
+ }
+
+ // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
+ // we will need to update this code. I was told to currently always use the
+ // CXXRecordDecl class since we often don't know from debug information if
+ // something is struct or a class, so we default to always use the more
+ // complete definition just in case.
+
+ bool has_name = !name.empty();
+ CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(ast, 0);
+ decl->setTagKind(static_cast<TagDecl::TagKind>(kind));
+ decl->setDeclContext(decl_ctx);
+ if (has_name)
+ decl->setDeclName(&ast.Idents.get(name));
+ SetOwningModule(decl, owning_module);
+
+ if (!has_name) {
+ // In C++ a lambda is also represented as an unnamed class. This is
+ // different from an *anonymous class* that the user wrote:
+ //
+ // struct A {
+ // // anonymous class (GNU/MSVC extension)
+ // struct {
+ // int x;
+ // };
+ // // unnamed class within a class
+ // struct {
+ // int y;
+ // } B;
+ // };
+ //
+ // void f() {
+ // // unammed class outside of a class
+ // struct {
+ // int z;
+ // } C;
+ // }
+ //
+ // Anonymous classes is a GNU/MSVC extension that clang supports. It
+ // requires the anonymous class be embedded within a class. So the new
+ // heuristic verifies this condition.
+ if (isa<CXXRecordDecl>(decl_ctx) && exports_symbols)
+ decl->setAnonymousStructOrUnion(true);
+ }
+
+ if (decl) {
+ if (metadata)
+ SetMetadata(decl, *metadata);
+
+ if (access_type != eAccessNone)
+ decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
+
+ if (decl_ctx)
+ decl_ctx->addDecl(decl);
+
+ return GetType(ast.getTagDeclType(decl));
+ }
+ return CompilerType();
+}
+
+namespace {
+ bool IsValueParam(const clang::TemplateArgument &argument) {
+ return argument.getKind() == TemplateArgument::Integral;
+ }
+}
+
+static TemplateParameterList *CreateTemplateParameterList(
+ ASTContext &ast,
+ const TypeSystemClang::TemplateParameterInfos &template_param_infos,
+ llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
+ const bool parameter_pack = false;
+ const bool is_typename = false;
+ const unsigned depth = 0;
+ const size_t num_template_params = template_param_infos.args.size();
+ DeclContext *const decl_context =
+ ast.getTranslationUnitDecl(); // Is this the right decl context?,
+ for (size_t i = 0; i < num_template_params; ++i) {
+ const char *name = template_param_infos.names[i];
+
+ IdentifierInfo *identifier_info = nullptr;
+ if (name && name[0])
+ identifier_info = &ast.Idents.get(name);
+ if (IsValueParam(template_param_infos.args[i])) {
+ QualType template_param_type =
+ template_param_infos.args[i].getIntegralType();
+ template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
+ ast, decl_context, SourceLocation(), SourceLocation(), depth, i,
+ identifier_info, template_param_type, parameter_pack,
+ ast.getTrivialTypeSourceInfo(template_param_type)));
+ } else {
+ template_param_decls.push_back(TemplateTypeParmDecl::Create(
+ ast, decl_context, SourceLocation(), SourceLocation(), depth, i,
+ identifier_info, is_typename, parameter_pack));
+ }
+ }
+
+ if (template_param_infos.packed_args) {
+ IdentifierInfo *identifier_info = nullptr;
+ if (template_param_infos.pack_name && template_param_infos.pack_name[0])
+ identifier_info = &ast.Idents.get(template_param_infos.pack_name);
+ const bool parameter_pack_true = true;
+
+ if (!template_param_infos.packed_args->args.empty() &&
+ IsValueParam(template_param_infos.packed_args->args[0])) {
+ QualType template_param_type =
+ template_param_infos.packed_args->args[0].getIntegralType();
+ template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
+ ast, decl_context, SourceLocation(), SourceLocation(), depth,
+ num_template_params, identifier_info, template_param_type,
+ parameter_pack_true,
+ ast.getTrivialTypeSourceInfo(template_param_type)));
+ } else {
+ template_param_decls.push_back(TemplateTypeParmDecl::Create(
+ ast, decl_context, SourceLocation(), SourceLocation(), depth,
+ num_template_params, identifier_info, is_typename,
+ parameter_pack_true));
+ }
+ }
+ clang::Expr *const requires_clause = nullptr; // TODO: Concepts
+ TemplateParameterList *template_param_list = TemplateParameterList::Create(
+ ast, SourceLocation(), SourceLocation(), template_param_decls,
+ SourceLocation(), requires_clause);
+ return template_param_list;
+}
+
+clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ clang::FunctionDecl *func_decl, const char *name,
+ const TemplateParameterInfos &template_param_infos) {
+ // /// Create a function template node.
+ ASTContext &ast = getASTContext();
+
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+ FunctionTemplateDecl *func_tmpl_decl =
+ FunctionTemplateDecl::CreateDeserialized(ast, 0);
+ func_tmpl_decl->setDeclContext(decl_ctx);
+ func_tmpl_decl->setLocation(func_decl->getLocation());
+ func_tmpl_decl->setDeclName(func_decl->getDeclName());
+ func_tmpl_decl->init(func_decl, template_param_list);
+ SetOwningModule(func_tmpl_decl, owning_module);
+
+ for (size_t i = 0, template_param_decl_count = template_param_decls.size();
+ i < template_param_decl_count; ++i) {
+ // TODO: verify which decl context we should put template_param_decls into..
+ template_param_decls[i]->setDeclContext(func_decl);
+ }
+ // Function templates inside a record need to have an access specifier.
+ // It doesn't matter what access specifier we give the template as LLDB
+ // anyway allows accessing everything inside a record.
+ if (decl_ctx->isRecord())
+ func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public);
+
+ return func_tmpl_decl;
+}
+
+void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
+ FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
+ const TemplateParameterInfos &infos) {
+ TemplateArgumentList *template_args_ptr =
+ TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args);
+
+ func_decl->setFunctionTemplateSpecialization(func_tmpl_decl,
+ template_args_ptr, nullptr);
+}
+
+ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
+ DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ lldb::AccessType access_type, const char *class_name, int kind,
+ const TemplateParameterInfos &template_param_infos) {
+ ASTContext &ast = getASTContext();
+
+ ClassTemplateDecl *class_template_decl = nullptr;
+ if (decl_ctx == nullptr)
+ decl_ctx = ast.getTranslationUnitDecl();
+
+ IdentifierInfo &identifier_info = ast.Idents.get(class_name);
+ DeclarationName decl_name(&identifier_info);
+
+ clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+
+ for (NamedDecl *decl : result) {
+ class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
+ if (class_template_decl)
+ return class_template_decl;
+ }
+
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+
+ CXXRecordDecl *template_cxx_decl = CXXRecordDecl::CreateDeserialized(ast, 0);
+ template_cxx_decl->setTagKind(static_cast<TagDecl::TagKind>(kind));
+ // What decl context do we use here? TU? The actual decl context?
+ template_cxx_decl->setDeclContext(decl_ctx);
+ template_cxx_decl->setDeclName(decl_name);
+ SetOwningModule(template_cxx_decl, owning_module);
+
+ for (size_t i = 0, template_param_decl_count = template_param_decls.size();
+ i < template_param_decl_count; ++i) {
+ template_param_decls[i]->setDeclContext(template_cxx_decl);
+ }
+
+ // With templated classes, we say that a class is templated with
+ // specializations, but that the bare class has no functions.
+ // template_cxx_decl->startDefinition();
+ // template_cxx_decl->completeDefinition();
+
+ class_template_decl = ClassTemplateDecl::CreateDeserialized(ast, 0);
+ // What decl context do we use here? TU? The actual decl context?
+ class_template_decl->setDeclContext(decl_ctx);
+ class_template_decl->setDeclName(decl_name);
+ class_template_decl->init(template_cxx_decl, template_param_list);
+ template_cxx_decl->setDescribedClassTemplate(class_template_decl);
+ SetOwningModule(class_template_decl, owning_module);
+
+ if (class_template_decl) {
+ if (access_type != eAccessNone)
+ class_template_decl->setAccess(
+ ConvertAccessTypeToAccessSpecifier(access_type));
+
+ decl_ctx->addDecl(class_template_decl);
+
+ VerifyDecl(class_template_decl);
+ }
+
+ return class_template_decl;
+}
+
+TemplateTemplateParmDecl *
+TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) {
+ ASTContext &ast = getASTContext();
+
+ auto *decl_ctx = ast.getTranslationUnitDecl();
+
+ IdentifierInfo &identifier_info = ast.Idents.get(template_name);
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+ TypeSystemClang::TemplateParameterInfos template_param_infos;
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+
+ // LLDB needs to create those decls only to be able to display a
+ // type that includes a template template argument. Only the name matters for
+ // this purpose, so we use dummy values for the other characteristics of the
+ // type.
+ return TemplateTemplateParmDecl::Create(
+ ast, decl_ctx, SourceLocation(),
+ /*Depth*/ 0, /*Position*/ 0,
+ /*IsParameterPack*/ false, &identifier_info, template_param_list);
+}
+
+ClassTemplateSpecializationDecl *
+TypeSystemClang::CreateClassTemplateSpecializationDecl(
+ DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ ClassTemplateDecl *class_template_decl, int kind,
+ const TemplateParameterInfos &template_param_infos) {
+ ASTContext &ast = getASTContext();
+ llvm::SmallVector<clang::TemplateArgument, 2> args(
+ template_param_infos.args.size() +
+ (template_param_infos.packed_args ? 1 : 0));
+ std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
+ args.begin());
+ if (template_param_infos.packed_args) {
+ args[args.size() - 1] = TemplateArgument::CreatePackCopy(
+ ast, template_param_infos.packed_args->args);
+ }
+ ClassTemplateSpecializationDecl *class_template_specialization_decl =
+ ClassTemplateSpecializationDecl::CreateDeserialized(ast, 0);
+ class_template_specialization_decl->setTagKind(
+ static_cast<TagDecl::TagKind>(kind));
+ class_template_specialization_decl->setDeclContext(decl_ctx);
+ class_template_specialization_decl->setInstantiationOf(class_template_decl);
+ class_template_specialization_decl->setTemplateArgs(
+ TemplateArgumentList::CreateCopy(ast, args));
+ ast.getTypeDeclType(class_template_specialization_decl, nullptr);
+ class_template_specialization_decl->setDeclName(
+ class_template_decl->getDeclName());
+ SetOwningModule(class_template_specialization_decl, owning_module);
+ decl_ctx->addDecl(class_template_specialization_decl);
+
+ class_template_specialization_decl->setSpecializationKind(
+ TSK_ExplicitSpecialization);
+
+ return class_template_specialization_decl;
+}
+
+CompilerType TypeSystemClang::CreateClassTemplateSpecializationType(
+ ClassTemplateSpecializationDecl *class_template_specialization_decl) {
+ if (class_template_specialization_decl) {
+ ASTContext &ast = getASTContext();
+ return GetType(ast.getTagDeclType(class_template_specialization_decl));
+ }
+ return CompilerType();
+}
+
+static inline bool check_op_param(bool is_method,
+ clang::OverloadedOperatorKind op_kind,
+ bool unary, bool binary,
+ uint32_t num_params) {
+ // Special-case call since it can take any number of operands
+ if (op_kind == OO_Call)
+ return true;
+
+ // The parameter count doesn't include "this"
+ if (is_method)
+ ++num_params;
+ if (num_params == 1)
+ return unary;
+ if (num_params == 2)
+ return binary;
+ else
+ return false;
+}
+
+bool TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
+ bool is_method, clang::OverloadedOperatorKind op_kind,
+ uint32_t num_params) {
+ switch (op_kind) {
+ default:
+ break;
+ // C++ standard allows any number of arguments to new/delete
+ case OO_New:
+ case OO_Array_New:
+ case OO_Delete:
+ case OO_Array_Delete:
+ return true;
+ }
+
+#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
+ case OO_##Name: \
+ return check_op_param(is_method, op_kind, Unary, Binary, num_params);
+ switch (op_kind) {
+#include "clang/Basic/OperatorKinds.def"
+ default:
+ break;
+ }
+ return false;
+}
+
+clang::AccessSpecifier
+TypeSystemClang::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
+ clang::AccessSpecifier rhs) {
+ // Make the access equal to the stricter of the field and the nested field's
+ // access
+ if (lhs == AS_none || rhs == AS_none)
+ return AS_none;
+ if (lhs == AS_private || rhs == AS_private)
+ return AS_private;
+ if (lhs == AS_protected || rhs == AS_protected)
+ return AS_protected;
+ return AS_public;
+}
+
+bool TypeSystemClang::FieldIsBitfield(FieldDecl *field,
+ uint32_t &bitfield_bit_size) {
+ ASTContext &ast = getASTContext();
+ if (field == nullptr)
+ return false;
+
+ if (field->isBitField()) {
+ Expr *bit_width_expr = field->getBitWidth();
+ if (bit_width_expr) {
+ llvm::APSInt bit_width_apsint;
+ if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, ast)) {
+ bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
+ if (record_decl == nullptr)
+ return false;
+
+ if (!record_decl->field_empty())
+ return true;
+
+ // No fields, lets check this is a CXX record and check the base classes
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
+ base_class->getType()->getAs<RecordType>()->getDecl());
+ if (RecordHasFields(base_class_decl))
+ return true;
+ }
+ }
+ return false;
+}
+
+#pragma mark Objective-C Classes
+
+CompilerType TypeSystemClang::CreateObjCClass(
+ llvm::StringRef name, clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module, bool isForwardDecl, bool isInternal,
+ ClangASTMetadata *metadata) {
+ ASTContext &ast = getASTContext();
+ assert(!name.empty());
+ if (!decl_ctx)
+ decl_ctx = ast.getTranslationUnitDecl();
+
+ ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0);
+ decl->setDeclContext(decl_ctx);
+ decl->setDeclName(&ast.Idents.get(name));
+ /*isForwardDecl,*/
+ decl->setImplicit(isInternal);
+ SetOwningModule(decl, owning_module);
+
+ if (decl && metadata)
+ SetMetadata(decl, *metadata);
+
+ return GetType(ast.getObjCInterfaceType(decl));
+}
+
+static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
+ return !TypeSystemClang::RecordHasFields(b->getType()->getAsCXXRecordDecl());
+}
+
+uint32_t
+TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
+ bool omit_empty_base_classes) {
+ uint32_t num_bases = 0;
+ if (cxx_record_decl) {
+ if (omit_empty_base_classes) {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ // Skip empty base classes
+ if (BaseSpecifierIsEmpty(base_class))
+ continue;
+ ++num_bases;
+ }
+ } else
+ num_bases = cxx_record_decl->getNumBases();
+ }
+ return num_bases;
+}
+
+#pragma mark Namespace Declarations
+
+NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
+ const char *name, clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module, bool is_inline) {
+ NamespaceDecl *namespace_decl = nullptr;
+ ASTContext &ast = getASTContext();
+ TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl();
+ if (!decl_ctx)
+ decl_ctx = translation_unit_decl;
+
+ if (name) {
+ IdentifierInfo &identifier_info = ast.Idents.get(name);
+ DeclarationName decl_name(&identifier_info);
+ clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+ for (NamedDecl *decl : result) {
+ namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
+ if (namespace_decl)
+ return namespace_decl;
+ }
+
+ namespace_decl =
+ NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(),
+ SourceLocation(), &identifier_info, nullptr);
+
+ decl_ctx->addDecl(namespace_decl);
+ } else {
+ if (decl_ctx == translation_unit_decl) {
+ namespace_decl = translation_unit_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+
+ namespace_decl =
+ NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
+ translation_unit_decl->setAnonymousNamespace(namespace_decl);
+ translation_unit_decl->addDecl(namespace_decl);
+ assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
+ } else {
+ NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
+ if (parent_namespace_decl) {
+ namespace_decl = parent_namespace_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+ namespace_decl =
+ NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
+ parent_namespace_decl->setAnonymousNamespace(namespace_decl);
+ parent_namespace_decl->addDecl(namespace_decl);
+ assert(namespace_decl ==
+ parent_namespace_decl->getAnonymousNamespace());
+ } else {
+ assert(false && "GetUniqueNamespaceDeclaration called with no name and "
+ "no namespace as decl_ctx");
+ }
+ }
+ }
+ // Note: namespaces can span multiple modules, so perhaps this isn't a good
+ // idea.
+ SetOwningModule(namespace_decl, owning_module);
+
+ VerifyDecl(namespace_decl);
+ return namespace_decl;
+}
+
+clang::BlockDecl *
+TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx,
+ OptionalClangModuleID owning_module) {
+ if (ctx) {
+ clang::BlockDecl *decl =
+ clang::BlockDecl::CreateDeserialized(getASTContext(), 0);
+ decl->setDeclContext(ctx);
+ ctx->addDecl(decl);
+ SetOwningModule(decl, owning_module);
+ return decl;
+ }
+ return nullptr;
+}
+
+clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
+ clang::DeclContext *right,
+ clang::DeclContext *root) {
+ if (root == nullptr)
+ return nullptr;
+
+ std::set<clang::DeclContext *> path_left;
+ for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
+ path_left.insert(d);
+
+ for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
+ if (path_left.find(d) != path_left.end())
+ return d;
+
+ return nullptr;
+}
+
+clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ clang::NamespaceDecl *ns_decl) {
+ if (decl_ctx && ns_decl) {
+ auto *translation_unit = getASTContext().getTranslationUnitDecl();
+ clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
+ getASTContext(), decl_ctx, clang::SourceLocation(),
+ clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
+ clang::SourceLocation(), ns_decl,
+ FindLCABetweenDecls(decl_ctx, ns_decl,
+ translation_unit));
+ decl_ctx->addDecl(using_decl);
+ SetOwningModule(using_decl, owning_module);
+ return using_decl;
+ }
+ return nullptr;
+}
+
+clang::UsingDecl *
+TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+ OptionalClangModuleID owning_module,
+ clang::NamedDecl *target) {
+ if (current_decl_ctx && target) {
+ clang::UsingDecl *using_decl = clang::UsingDecl::Create(
+ getASTContext(), current_decl_ctx, clang::SourceLocation(),
+ clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
+ SetOwningModule(using_decl, owning_module);
+ clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
+ getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
+ target);
+ SetOwningModule(shadow_decl, owning_module);
+ using_decl->addShadowDecl(shadow_decl);
+ current_decl_ctx->addDecl(using_decl);
+ return using_decl;
+ }
+ return nullptr;
+}
+
+clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
+ clang::DeclContext *decl_context, OptionalClangModuleID owning_module,
+ const char *name, clang::QualType type) {
+ if (decl_context) {
+ clang::VarDecl *var_decl =
+ clang::VarDecl::CreateDeserialized(getASTContext(), 0);
+ var_decl->setDeclContext(decl_context);
+ if (name && name[0])
+ var_decl->setDeclName(&getASTContext().Idents.getOwn(name));
+ var_decl->setType(type);
+ SetOwningModule(var_decl, owning_module);
+ var_decl->setAccess(clang::AS_public);
+ decl_context->addDecl(var_decl);
+ return var_decl;
+ }
+ return nullptr;
+}
+
+lldb::opaque_compiler_type_t
+TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast,
+ lldb::BasicType basic_type) {
+ switch (basic_type) {
+ case eBasicTypeVoid:
+ return ast->VoidTy.getAsOpaquePtr();
+ case eBasicTypeChar:
+ return ast->CharTy.getAsOpaquePtr();
+ case eBasicTypeSignedChar:
+ return ast->SignedCharTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedChar:
+ return ast->UnsignedCharTy.getAsOpaquePtr();
+ case eBasicTypeWChar:
+ return ast->getWCharType().getAsOpaquePtr();
+ case eBasicTypeSignedWChar:
+ return ast->getSignedWCharType().getAsOpaquePtr();
+ case eBasicTypeUnsignedWChar:
+ return ast->getUnsignedWCharType().getAsOpaquePtr();
+ case eBasicTypeChar16:
+ return ast->Char16Ty.getAsOpaquePtr();
+ case eBasicTypeChar32:
+ return ast->Char32Ty.getAsOpaquePtr();
+ case eBasicTypeShort:
+ return ast->ShortTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedShort:
+ return ast->UnsignedShortTy.getAsOpaquePtr();
+ case eBasicTypeInt:
+ return ast->IntTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt:
+ return ast->UnsignedIntTy.getAsOpaquePtr();
+ case eBasicTypeLong:
+ return ast->LongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLong:
+ return ast->UnsignedLongTy.getAsOpaquePtr();
+ case eBasicTypeLongLong:
+ return ast->LongLongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLongLong:
+ return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ case eBasicTypeInt128:
+ return ast->Int128Ty.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt128:
+ return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ case eBasicTypeBool:
+ return ast->BoolTy.getAsOpaquePtr();
+ case eBasicTypeHalf:
+ return ast->HalfTy.getAsOpaquePtr();
+ case eBasicTypeFloat:
+ return ast->FloatTy.getAsOpaquePtr();
+ case eBasicTypeDouble:
+ return ast->DoubleTy.getAsOpaquePtr();
+ case eBasicTypeLongDouble:
+ return ast->LongDoubleTy.getAsOpaquePtr();
+ case eBasicTypeFloatComplex:
+ return ast->FloatComplexTy.getAsOpaquePtr();
+ case eBasicTypeDoubleComplex:
+ return ast->DoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeLongDoubleComplex:
+ return ast->LongDoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeObjCID:
+ return ast->getObjCIdType().getAsOpaquePtr();
+ case eBasicTypeObjCClass:
+ return ast->getObjCClassType().getAsOpaquePtr();
+ case eBasicTypeObjCSel:
+ return ast->getObjCSelType().getAsOpaquePtr();
+ case eBasicTypeNullPtr:
+ return ast->NullPtrTy.getAsOpaquePtr();
+ default:
+ return nullptr;
+ }
+}
+
+#pragma mark Function Types
+
+clang::DeclarationName
+TypeSystemClang::GetDeclarationName(const char *name,
+ const CompilerType &function_clang_type) {
+ if (!name || !name[0])
+ return clang::DeclarationName();
+
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+ if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
+ return DeclarationName(&getASTContext().Idents.get(
+ name)); // Not operator, but a regular function.
+
+ // Check the number of operator parameters. Sometimes we have seen bad DWARF
+ // that doesn't correctly describe operators and if we try to create a method
+ // and add it to the class, clang will assert and crash, so we need to make
+ // sure things are acceptable.
+ clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
+ const clang::FunctionProtoType *function_type =
+ llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
+ if (function_type == nullptr)
+ return clang::DeclarationName();
+
+ const bool is_method = false;
+ const unsigned int num_params = function_type->getNumParams();
+ if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
+ is_method, op_kind, num_params))
+ return clang::DeclarationName();
+
+ return getASTContext().DeclarationNames.getCXXOperatorName(op_kind);
+}
+
+FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ const char *name, const CompilerType &function_clang_type, int storage,
+ bool is_inline) {
+ FunctionDecl *func_decl = nullptr;
+ ASTContext &ast = getASTContext();
+ if (!decl_ctx)
+ decl_ctx = ast.getTranslationUnitDecl();
+
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
+
+ clang::DeclarationName declarationName =
+ GetDeclarationName(name, function_clang_type);
+ func_decl = FunctionDecl::CreateDeserialized(ast, 0);
+ func_decl->setDeclContext(decl_ctx);
+ func_decl->setDeclName(declarationName);
+ func_decl->setType(ClangUtil::GetQualType(function_clang_type));
+ func_decl->setStorageClass(static_cast<clang::StorageClass>(storage));
+ func_decl->setInlineSpecified(is_inline);
+ func_decl->setHasWrittenPrototype(hasWrittenPrototype);
+ func_decl->setConstexprKind(isConstexprSpecified ? CSK_constexpr
+ : CSK_unspecified);
+ SetOwningModule(func_decl, owning_module);
+ if (func_decl)
+ decl_ctx->addDecl(func_decl);
+
+ VerifyDecl(func_decl);
+
+ return func_decl;
+}
+
+CompilerType
+TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
+ const CompilerType *args, unsigned num_args,
+ bool is_variadic, unsigned type_quals,
+ clang::CallingConv cc) {
+ if (!result_type || !ClangUtil::IsClangType(result_type))
+ return CompilerType(); // invalid return type
+
+ std::vector<QualType> qual_type_args;
+ if (num_args > 0 && args == nullptr)
+ return CompilerType(); // invalid argument array passed in
+
+ // Verify that all arguments are valid and the right type
+ for (unsigned i = 0; i < num_args; ++i) {
+ if (args[i]) {
+ // Make sure we have a clang type in args[i] and not a type from another
+ // language whose name might match
+ const bool is_clang_type = ClangUtil::IsClangType(args[i]);
+ lldbassert(is_clang_type);
+ if (is_clang_type)
+ qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
+ else
+ return CompilerType(); // invalid argument type (must be a clang type)
+ } else
+ return CompilerType(); // invalid argument type (empty)
+ }
+
+ // TODO: Detect calling convention in DWARF?
+ FunctionProtoType::ExtProtoInfo proto_info;
+ proto_info.ExtInfo = cc;
+ proto_info.Variadic = is_variadic;
+ proto_info.ExceptionSpec = EST_None;
+ proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
+ proto_info.RefQualifier = RQ_None;
+
+ return GetType(getASTContext().getFunctionType(
+ ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
+}
+
+ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ const char *name, const CompilerType &param_type, int storage,
+ bool add_decl) {
+ ASTContext &ast = getASTContext();
+ auto *decl = ParmVarDecl::CreateDeserialized(ast, 0);
+ decl->setDeclContext(decl_ctx);
+ if (name && name[0])
+ decl->setDeclName(&ast.Idents.get(name));
+ decl->setType(ClangUtil::GetQualType(param_type));
+ decl->setStorageClass(static_cast<clang::StorageClass>(storage));
+ SetOwningModule(decl, owning_module);
+ if (add_decl)
+ decl_ctx->addDecl(decl);
+
+ return decl;
+}
+
+void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl,
+ ParmVarDecl **params,
+ unsigned num_params) {
+ if (function_decl)
+ function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
+}
+
+CompilerType
+TypeSystemClang::CreateBlockPointerType(const CompilerType &function_type) {
+ QualType block_type = m_ast_up->getBlockPointerType(
+ clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
+
+ return GetType(block_type);
+}
+
+#pragma mark Array Types
+
+CompilerType TypeSystemClang::CreateArrayType(const CompilerType &element_type,
+ size_t element_count,
+ bool is_vector) {
+ if (element_type.IsValid()) {
+ ASTContext &ast = getASTContext();
+
+ if (is_vector) {
+ return GetType(ast.getExtVectorType(ClangUtil::GetQualType(element_type),
+ element_count));
+ } else {
+
+ llvm::APInt ap_element_count(64, element_count);
+ if (element_count == 0) {
+ return GetType(ast.getIncompleteArrayType(
+ ClangUtil::GetQualType(element_type), clang::ArrayType::Normal, 0));
+ } else {
+ return GetType(ast.getConstantArrayType(
+ ClangUtil::GetQualType(element_type), ap_element_count, nullptr,
+ clang::ArrayType::Normal, 0));
+ }
+ }
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::CreateStructForIdentifier(
+ ConstString type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed) {
+ CompilerType type;
+ if (!type_name.IsEmpty() &&
+ (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
+ .IsValid()) {
+ lldbassert(0 && "Trying to create a type for an existing name");
+ return type;
+ }
+
+ type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
+ type_name.GetCString(), clang::TTK_Struct,
+ lldb::eLanguageTypeC);
+ StartTagDeclarationDefinition(type);
+ for (const auto &field : type_fields)
+ AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
+ 0);
+ if (packed)
+ SetIsPacked(type);
+ CompleteTagDeclarationDefinition(type);
+ return type;
+}
+
+CompilerType TypeSystemClang::GetOrCreateStructForIdentifier(
+ ConstString type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed) {
+ CompilerType type;
+ if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ return type;
+
+ return CreateStructForIdentifier(type_name, type_fields, packed);
+}
+
+#pragma mark Enumeration Types
+
+CompilerType TypeSystemClang::CreateEnumerationType(
+ const char *name, clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module, const Declaration &decl,
+ const CompilerType &integer_clang_type, bool is_scoped) {
+ // TODO: Do something intelligent with the Declaration object passed in
+ // like maybe filling in the SourceLocation with it...
+ ASTContext &ast = getASTContext();
+
+ // TODO: ask about these...
+ // const bool IsFixed = false;
+ EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, 0);
+ enum_decl->setDeclContext(decl_ctx);
+ if (name && name[0])
+ enum_decl->setDeclName(&ast.Idents.get(name));
+ enum_decl->setScoped(is_scoped);
+ enum_decl->setScopedUsingClassTag(is_scoped);
+ enum_decl->setFixed(false);
+ SetOwningModule(enum_decl, owning_module);
+ if (enum_decl) {
+ if (decl_ctx)
+ decl_ctx->addDecl(enum_decl);
+
+ // TODO: check if we should be setting the promotion type too?
+ enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
+
+ enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
+
+ return GetType(ast.getTagDeclType(enum_decl));
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
+ bool is_signed) {
+ clang::ASTContext &ast = getASTContext();
+
+ if (is_signed) {
+ if (bit_size == ast.getTypeSize(ast.SignedCharTy))
+ return GetType(ast.SignedCharTy);
+
+ if (bit_size == ast.getTypeSize(ast.ShortTy))
+ return GetType(ast.ShortTy);
+
+ if (bit_size == ast.getTypeSize(ast.IntTy))
+ return GetType(ast.IntTy);
+
+ if (bit_size == ast.getTypeSize(ast.LongTy))
+ return GetType(ast.LongTy);
+
+ if (bit_size == ast.getTypeSize(ast.LongLongTy))
+ return GetType(ast.LongLongTy);
+
+ if (bit_size == ast.getTypeSize(ast.Int128Ty))
+ return GetType(ast.Int128Ty);
+ } else {
+ if (bit_size == ast.getTypeSize(ast.UnsignedCharTy))
+ return GetType(ast.UnsignedCharTy);
+
+ if (bit_size == ast.getTypeSize(ast.UnsignedShortTy))
+ return GetType(ast.UnsignedShortTy);
+
+ if (bit_size == ast.getTypeSize(ast.UnsignedIntTy))
+ return GetType(ast.UnsignedIntTy);
+
+ if (bit_size == ast.getTypeSize(ast.UnsignedLongTy))
+ return GetType(ast.UnsignedLongTy);
+
+ if (bit_size == ast.getTypeSize(ast.UnsignedLongLongTy))
+ return GetType(ast.UnsignedLongLongTy);
+
+ if (bit_size == ast.getTypeSize(ast.UnsignedInt128Ty))
+ return GetType(ast.UnsignedInt128Ty);
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) {
+ return GetIntTypeFromBitSize(
+ getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed);
+}
+
+void TypeSystemClang::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
+ if (decl_ctx) {
+ DumpDeclContextHiearchy(decl_ctx->getParent());
+
+ clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
+ if (named_decl) {
+ printf("%20s: %s\n", decl_ctx->getDeclKindName(),
+ named_decl->getDeclName().getAsString().c_str());
+ } else {
+ printf("%20s\n", decl_ctx->getDeclKindName());
+ }
+ }
+}
+
+void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) {
+ if (decl == nullptr)
+ return;
+ DumpDeclContextHiearchy(decl->getDeclContext());
+
+ clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
+ if (record_decl) {
+ printf("%20s: %s%s\n", decl->getDeclKindName(),
+ record_decl->getDeclName().getAsString().c_str(),
+ record_decl->isInjectedClassName() ? " (injected class name)" : "");
+
+ } else {
+ clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
+ if (named_decl) {
+ printf("%20s: %s\n", decl->getDeclKindName(),
+ named_decl->getDeclName().getAsString().c_str());
+ } else {
+ printf("%20s\n", decl->getDeclKindName());
+ }
+ }
+}
+
+bool TypeSystemClang::DeclsAreEquivalent(clang::Decl *lhs_decl,
+ clang::Decl *rhs_decl) {
+ if (lhs_decl && rhs_decl) {
+ // Make sure the decl kinds match first
+ const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
+ const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
+
+ if (lhs_decl_kind == rhs_decl_kind) {
+ // Now check that the decl contexts kinds are all equivalent before we
+ // have to check any names of the decl contexts...
+ clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
+ clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
+ if (lhs_decl_ctx && rhs_decl_ctx) {
+ while (true) {
+ if (lhs_decl_ctx && rhs_decl_ctx) {
+ const clang::Decl::Kind lhs_decl_ctx_kind =
+ lhs_decl_ctx->getDeclKind();
+ const clang::Decl::Kind rhs_decl_ctx_kind =
+ rhs_decl_ctx->getDeclKind();
+ if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
+ lhs_decl_ctx = lhs_decl_ctx->getParent();
+ rhs_decl_ctx = rhs_decl_ctx->getParent();
+
+ if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
+ break;
+ } else
+ return false;
+ } else
+ return false;
+ }
+
+ // Now make sure the name of the decls match
+ clang::NamedDecl *lhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
+ clang::NamedDecl *rhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
+ if (lhs_named_decl && rhs_named_decl) {
+ clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
+ clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
+ if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
+ if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+ return false;
+ } else
+ return false;
+ } else
+ return false;
+
+ // We know that the decl context kinds all match, so now we need to
+ // make sure the names match as well
+ lhs_decl_ctx = lhs_decl->getDeclContext();
+ rhs_decl_ctx = rhs_decl->getDeclContext();
+ while (true) {
+ switch (lhs_decl_ctx->getDeclKind()) {
+ case clang::Decl::TranslationUnit:
+ // We don't care about the translation unit names
+ return true;
+ default: {
+ clang::NamedDecl *lhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
+ clang::NamedDecl *rhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
+ if (lhs_named_decl && rhs_named_decl) {
+ clang::DeclarationName lhs_decl_name =
+ lhs_named_decl->getDeclName();
+ clang::DeclarationName rhs_decl_name =
+ rhs_named_decl->getDeclName();
+ if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
+ if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+ return false;
+ } else
+ return false;
+ } else
+ return false;
+ } break;
+ }
+ lhs_decl_ctx = lhs_decl_ctx->getParent();
+ rhs_decl_ctx = rhs_decl_ctx->getParent();
+ }
+ }
+ }
+ }
+ return false;
+}
+bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast,
+ clang::Decl *decl) {
+ if (!decl)
+ return false;
+
+ ExternalASTSource *ast_source = ast->getExternalSource();
+
+ if (!ast_source)
+ return false;
+
+ if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
+ if (tag_decl->isCompleteDefinition())
+ return true;
+
+ if (!tag_decl->hasExternalLexicalStorage())
+ return false;
+
+ ast_source->CompleteType(tag_decl);
+
+ return !tag_decl->getTypeForDecl()->isIncompleteType();
+ } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
+ if (objc_interface_decl->getDefinition())
+ return true;
+
+ if (!objc_interface_decl->hasExternalLexicalStorage())
+ return false;
+
+ ast_source->CompleteType(objc_interface_decl);
+
+ return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
+ } else {
+ return false;
+ }
+}
+
+void TypeSystemClang::SetMetadataAsUserID(const clang::Decl *decl,
+ user_id_t user_id) {
+ ClangASTMetadata meta_data;
+ meta_data.SetUserID(user_id);
+ SetMetadata(decl, meta_data);
+}
+
+void TypeSystemClang::SetMetadataAsUserID(const clang::Type *type,
+ user_id_t user_id) {
+ ClangASTMetadata meta_data;
+ meta_data.SetUserID(user_id);
+ SetMetadata(type, meta_data);
+}
+
+void TypeSystemClang::SetMetadata(const clang::Decl *object,
+ ClangASTMetadata &metadata) {
+ m_decl_metadata[object] = metadata;
+}
+
+void TypeSystemClang::SetMetadata(const clang::Type *object,
+ ClangASTMetadata &metadata) {
+ m_type_metadata[object] = metadata;
+}
+
+ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Decl *object) {
+ auto It = m_decl_metadata.find(object);
+ if (It != m_decl_metadata.end())
+ return &It->second;
+ return nullptr;
+}
+
+ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) {
+ auto It = m_type_metadata.find(object);
+ if (It != m_type_metadata.end())
+ return &It->second;
+ return nullptr;
+}
+
+bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type,
+ int kind) const {
+ const clang::Type *clang_type = tag_qual_type.getTypePtr();
+ if (clang_type) {
+ const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
+ if (tag_type) {
+ clang::TagDecl *tag_decl =
+ llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
+ if (tag_decl) {
+ tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::SetDefaultAccessForRecordFields(
+ clang::RecordDecl *record_decl, int default_accessibility,
+ int *assigned_accessibilities, size_t num_assigned_accessibilities) {
+ if (record_decl) {
+ uint32_t field_idx;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end(), field_idx = 0;
+ field != field_end; ++field, ++field_idx) {
+ // If no accessibility was assigned, assign the correct one
+ if (field_idx < num_assigned_accessibilities &&
+ assigned_accessibilities[field_idx] == clang::AS_none)
+ field->setAccess((clang::AccessSpecifier)default_accessibility);
+ }
+ return true;
+ }
+ return false;
+}
+
+clang::DeclContext *
+TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
+ return GetDeclContextForType(ClangUtil::GetQualType(type));
+}
+
+/// Aggressively desugar the provided type, skipping past various kinds of
+/// syntactic sugar and other constructs one typically wants to ignore.
+/// The \p mask argument allows one to skip certain kinds of simplifications,
+/// when one wishes to handle a certain kind of type directly.
+static QualType
+RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
+ while (true) {
+ if (find(mask, type->getTypeClass()) != mask.end())
+ return type;
+ switch (type->getTypeClass()) {
+ // This is not fully correct as _Atomic is more than sugar, but it is
+ // sufficient for the purposes we care about.
+ case clang::Type::Atomic:
+ type = cast<clang::AtomicType>(type)->getValueType();
+ break;
+ case clang::Type::Auto:
+ case clang::Type::Decltype:
+ case clang::Type::Elaborated:
+ case clang::Type::Paren:
+ case clang::Type::Typedef:
+ case clang::Type::TypeOf:
+ case clang::Type::TypeOfExpr:
+ type = type->getLocallyUnqualifiedSingleStepDesugaredType();
+ break;
+ default:
+ return type;
+ }
+ }
+}
+
+clang::DeclContext *
+TypeSystemClang::GetDeclContextForType(clang::QualType type) {
+ if (type.isNull())
+ return nullptr;
+
+ clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ObjCInterface:
+ return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
+ ->getInterface();
+ case clang::Type::ObjCObjectPointer:
+ return GetDeclContextForType(
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ case clang::Type::Record:
+ return llvm::cast<clang::RecordType>(qual_type)->getDecl();
+ case clang::Type::Enum:
+ return llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ default:
+ break;
+ }
+ // No DeclContext in this type...
+ return nullptr;
+}
+
+static bool GetCompleteQualType(clang::ASTContext *ast,
+ clang::QualType qual_type,
+ bool allow_completion = true) {
+ qual_type = RemoveWrappingTypes(qual_type);
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray: {
+ const clang::ArrayType *array_type =
+ llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
+
+ if (array_type)
+ return GetCompleteQualType(ast, array_type->getElementType(),
+ allow_completion);
+ } break;
+ case clang::Type::Record: {
+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (cxx_record_decl->hasExternalLexicalStorage()) {
+ const bool is_complete = cxx_record_decl->isCompleteDefinition();
+ const bool fields_loaded =
+ cxx_record_decl->hasLoadedFieldsFromExternalStorage();
+ if (is_complete && fields_loaded)
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ // Call the field_begin() accessor to for it to use the external source
+ // to load the fields...
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(cxx_record_decl);
+ if (cxx_record_decl->isCompleteDefinition()) {
+ cxx_record_decl->field_begin();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+ }
+ }
+ }
+ }
+ const clang::TagType *tag_type =
+ llvm::cast<clang::TagType>(qual_type.getTypePtr());
+ return !tag_type->isIncompleteType();
+ } break;
+
+ case clang::Type::Enum: {
+ const clang::TagType *tag_type =
+ llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl) {
+ if (tag_decl->getDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (tag_decl->hasExternalLexicalStorage()) {
+ if (ast) {
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(tag_decl);
+ return !tag_type->isIncompleteType();
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ } break;
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (class_interface_decl->getDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (class_interface_decl->hasExternalLexicalStorage()) {
+ if (ast) {
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(class_interface_decl);
+ return !objc_class_type->isIncompleteType();
+ }
+ }
+ }
+ return false;
+ }
+ }
+ } break;
+
+ case clang::Type::Attributed:
+ return GetCompleteQualType(
+ ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
+ allow_completion);
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+static clang::ObjCIvarDecl::AccessControl
+ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
+ switch (access) {
+ case eAccessNone:
+ return clang::ObjCIvarDecl::None;
+ case eAccessPublic:
+ return clang::ObjCIvarDecl::Public;
+ case eAccessPrivate:
+ return clang::ObjCIvarDecl::Private;
+ case eAccessProtected:
+ return clang::ObjCIvarDecl::Protected;
+ case eAccessPackage:
+ return clang::ObjCIvarDecl::Package;
+ }
+ return clang::ObjCIvarDecl::None;
+}
+
+// Tests
+
+#ifndef NDEBUG
+bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) {
+ return !type || llvm::isa<clang::Type>(GetQualType(type).getTypePtr());
+}
+#endif
+
+bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) {
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ case clang::Type::ConstantArray:
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ case clang::Type::Record:
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return true;
+ default:
+ break;
+ }
+ // The clang type does have a value
+ return false;
+}
+
+bool TypeSystemClang::IsAnonymousType(lldb::opaque_compiler_type_t type) {
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ if (const clang::RecordType *record_type =
+ llvm::dyn_cast_or_null<clang::RecordType>(
+ qual_type.getTypePtrOrNull())) {
+ if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
+ return record_decl->isAnonymousStructOrUnion();
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ // The clang type does have a value
+ return false;
+}
+
+bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type_ptr,
+ uint64_t *size, bool *is_incomplete) {
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+
+ case clang::Type::ConstantArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ this, llvm::cast<clang::ConstantArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
+ if (size)
+ *size = llvm::cast<clang::ConstantArrayType>(qual_type)
+ ->getSize()
+ .getLimitedValue(ULLONG_MAX);
+ if (is_incomplete)
+ *is_incomplete = false;
+ return true;
+
+ case clang::Type::IncompleteArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ this, llvm::cast<clang::IncompleteArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
+ return true;
+
+ case clang::Type::VariableArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ this, llvm::cast<clang::VariableArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return true;
+
+ case clang::Type::DependentSizedArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ this, llvm::cast<clang::DependentSizedArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return true;
+ }
+ if (element_type_ptr)
+ element_type_ptr->Clear();
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return false;
+}
+
+bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type, uint64_t *size) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Vector: {
+ const clang::VectorType *vector_type =
+ qual_type->getAs<clang::VectorType>();
+ if (vector_type) {
+ if (size)
+ *size = vector_type->getNumElements();
+ if (element_type)
+ *element_type = GetType(vector_type->getElementType());
+ }
+ return true;
+ } break;
+ case clang::Type::ExtVector: {
+ const clang::ExtVectorType *ext_vector_type =
+ qual_type->getAs<clang::ExtVectorType>();
+ if (ext_vector_type) {
+ if (size)
+ *size = ext_vector_type->getNumElements();
+ if (element_type)
+ *element_type =
+ CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr());
+ }
+ return true;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsRuntimeGeneratedType(
+ lldb::opaque_compiler_type_t type) {
+ clang::DeclContext *decl_ctx = GetDeclContextForType(GetQualType(type));
+ if (!decl_ctx)
+ return false;
+
+ if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
+ return false;
+
+ clang::ObjCInterfaceDecl *result_iface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
+
+ ClangASTMetadata *ast_metadata = GetMetadata(result_iface_decl);
+ if (!ast_metadata)
+ return false;
+ return (ast_metadata->GetISAPtr() != 0);
+}
+
+bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) {
+ return GetQualType(type).getUnqualifiedType()->isCharType();
+}
+
+bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) {
+ const bool allow_completion = false;
+ return GetCompleteQualType(&getASTContext(), GetQualType(type),
+ allow_completion);
+}
+
+bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) {
+ return GetQualType(type).isConstQualified();
+}
+
+bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
+ uint32_t &length) {
+ CompilerType pointee_or_element_clang_type;
+ length = 0;
+ Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));
+
+ if (!pointee_or_element_clang_type.IsValid())
+ return false;
+
+ if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
+ if (pointee_or_element_clang_type.IsCharType()) {
+ if (type_flags.Test(eTypeIsArray)) {
+ // We know the size of the array and it could be a C string since it is
+ // an array of characters
+ length = llvm::cast<clang::ConstantArrayType>(
+ GetCanonicalQualType(type).getTypePtr())
+ ->getSize()
+ .getLimitedValue();
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type,
+ bool *is_variadic_ptr) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ if (qual_type->isFunctionType()) {
+ if (is_variadic_ptr) {
+ const clang::FunctionProtoType *function_proto_type =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (function_proto_type)
+ *is_variadic_ptr = function_proto_type->isVariadic();
+ else
+ *is_variadic_ptr = false;
+ }
+ return true;
+ }
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
+ nullptr);
+ } break;
+ }
+ }
+ return false;
+}
+
+// Used to detect "Homogeneous Floating-point Aggregates"
+uint32_t
+TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
+ CompilerType *base_type_ptr) {
+ if (!type)
+ return 0;
+
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
+ return 0;
+ }
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ if (record_type) {
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ // We are looking for a structure that contains only floating point
+ // types
+ clang::RecordDecl::field_iterator field_pos,
+ field_end = record_decl->field_end();
+ uint32_t num_fields = 0;
+ bool is_hva = false;
+ bool is_hfa = false;
+ clang::QualType base_qual_type;
+ uint64_t base_bitwidth = 0;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end;
+ ++field_pos) {
+ clang::QualType field_qual_type = field_pos->getType();
+ uint64_t field_bitwidth = getASTContext().getTypeSize(qual_type);
+ if (field_qual_type->isFloatingType()) {
+ if (field_qual_type->isComplexType())
+ return 0;
+ else {
+ if (num_fields == 0)
+ base_qual_type = field_qual_type;
+ else {
+ if (is_hva)
+ return 0;
+ is_hfa = true;
+ if (field_qual_type.getTypePtr() !=
+ base_qual_type.getTypePtr())
+ return 0;
+ }
+ }
+ } else if (field_qual_type->isVectorType() ||
+ field_qual_type->isExtVectorType()) {
+ if (num_fields == 0) {
+ base_qual_type = field_qual_type;
+ base_bitwidth = field_bitwidth;
+ } else {
+ if (is_hfa)
+ return 0;
+ is_hva = true;
+ if (base_bitwidth != field_bitwidth)
+ return 0;
+ if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+ return 0;
+ }
+ } else
+ return 0;
+ ++num_fields;
+ }
+ if (base_type_ptr)
+ *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr());
+ return num_fields;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+size_t TypeSystemClang::GetNumberOfFunctionArguments(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return func->getNumParams();
+ }
+ return 0;
+}
+
+CompilerType
+TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
+ const size_t index) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func) {
+ if (index < func->getNumParams())
+ return CompilerType(this, func->getParamType(index).getAsOpaquePtr());
+ }
+ }
+ return CompilerType();
+}
+
+bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ if (qual_type->isFunctionPointerType())
+ return true;
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsFunctionPointerType(
+ reference_type->getPointeeType().getAsOpaquePtr());
+ } break;
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsBlockPointerType(
+ lldb::opaque_compiler_type_t type,
+ CompilerType *function_pointer_type_ptr) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ if (qual_type->isBlockPointerType()) {
+ if (function_pointer_type_ptr) {
+ const clang::BlockPointerType *block_pointer_type =
+ qual_type->getAs<clang::BlockPointerType>();
+ QualType pointee_type = block_pointer_type->getPointeeType();
+ QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
+ *function_pointer_type_ptr =
+ CompilerType(this, function_pointer_type.getAsOpaquePtr());
+ }
+ return true;
+ }
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsBlockPointerType(
+ reference_type->getPointeeType().getAsOpaquePtr(),
+ function_pointer_type_ptr);
+ } break;
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) {
+ if (!type)
+ return false;
+
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::BuiltinType *builtin_type =
+ llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ if (builtin_type) {
+ if (builtin_type->isInteger()) {
+ is_signed = builtin_type->isSignedInteger();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) {
+ if (type) {
+ const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
+ GetCanonicalQualType(type)->getCanonicalTypeInternal());
+
+ if (enum_type) {
+ IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
+ is_signed);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::BlockPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(this,
+ llvm::cast<clang::PointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::MemberPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ default:
+ break;
+ }
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool TypeSystemClang::IsPointerOrReferenceType(
+ lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType().getAsOpaquePtr());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::BlockPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(this,
+ llvm::cast<clang::PointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::MemberPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::LValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::RValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
+ return true;
+ default:
+ break;
+ }
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type,
+ bool *is_rvalue) {
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ switch (type_class) {
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::LValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
+ if (is_rvalue)
+ *is_rvalue = false;
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ this, llvm::cast<clang::RValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
+ if (is_rvalue)
+ *is_rvalue = true;
+ return true;
+
+ default:
+ break;
+ }
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
+}
+
+bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type,
+ uint32_t &count, bool &is_complex) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
+ qual_type->getCanonicalTypeInternal())) {
+ clang::BuiltinType::Kind kind = BT->getKind();
+ if (kind >= clang::BuiltinType::Float &&
+ kind <= clang::BuiltinType::LongDouble) {
+ count = 1;
+ is_complex = false;
+ return true;
+ }
+ } else if (const clang::ComplexType *CT =
+ llvm::dyn_cast<clang::ComplexType>(
+ qual_type->getCanonicalTypeInternal())) {
+ if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
+ is_complex)) {
+ count = 2;
+ is_complex = true;
+ return true;
+ }
+ } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
+ qual_type->getCanonicalTypeInternal())) {
+ if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
+ is_complex)) {
+ count = VT->getNumElements();
+ is_complex = false;
+ return true;
+ }
+ }
+ }
+ count = 0;
+ is_complex = false;
+ return false;
+}
+
+bool TypeSystemClang::IsDefined(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+
+ clang::QualType qual_type(GetQualType(type));
+ const clang::TagType *tag_type =
+ llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ return tag_decl->isCompleteDefinition();
+ return false;
+ } else {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl)
+ return class_interface_decl->getDefinition() != nullptr;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TypeSystemClang::IsObjCClassType(const CompilerType &type) {
+ if (ClangUtil::IsClangType(type)) {
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
+ const clang::ObjCObjectPointerType *obj_pointer_type =
+ llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+
+ if (obj_pointer_type)
+ return obj_pointer_type->isObjCClassType();
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsObjCObjectOrInterfaceType(const CompilerType &type) {
+ if (ClangUtil::IsClangType(type))
+ return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+ return false;
+}
+
+bool TypeSystemClang::IsClassType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Record);
+}
+
+bool TypeSystemClang::IsEnumType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Enum);
+}
+
+bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ return cxx_record_decl->isPolymorphic();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
+ CompilerType *dynamic_pointee_type,
+ bool check_cplusplus,
+ bool check_objc) {
+ clang::QualType pointee_qual_type;
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ bool success = false;
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ if (check_objc &&
+ llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
+ clang::BuiltinType::ObjCId) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(this, type);
+ return true;
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (check_objc) {
+ if (const auto *objc_pointee_type =
+ qual_type->getPointeeType().getTypePtrOrNull()) {
+ if (const auto *objc_object_type =
+ llvm::dyn_cast_or_null<clang::ObjCObjectType>(
+ objc_pointee_type)) {
+ if (objc_object_type->isObjCClass())
+ return false;
+ }
+ }
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return true;
+ }
+ break;
+
+ case clang::Type::Pointer:
+ pointee_qual_type =
+ llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ pointee_qual_type =
+ llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (success) {
+ // Check to make sure what we are pointing too is a possible dynamic C++
+ // type We currently accept any "void *" (in case we have a class that
+ // has been watered down to an opaque pointer) and virtual C++ classes.
+ const clang::Type::TypeClass pointee_type_class =
+ pointee_qual_type.getCanonicalType()->getTypeClass();
+ switch (pointee_type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case clang::Type::Record:
+ if (check_cplusplus) {
+ clang::CXXRecordDecl *cxx_record_decl =
+ pointee_qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ bool is_complete = cxx_record_decl->isCompleteDefinition();
+
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else {
+ ClangASTMetadata *metadata = GetMetadata(cxx_record_decl);
+ if (metadata)
+ success = metadata->GetIsDynamicCXXType();
+ else {
+ is_complete = GetType(pointee_qual_type).GetCompleteType();
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else
+ success = false;
+ }
+ }
+
+ if (success) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (check_objc) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->Clear();
+ return false;
+}
+
+bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+
+ return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
+}
+
+bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})
+ ->getTypeClass() == clang::Type::Typedef;
+}
+
+bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ return GetCanonicalQualType(type)->isVoidType();
+}
+
+bool TypeSystemClang::CanPassInRegisters(const CompilerType &type) {
+ if (auto *record_decl =
+ TypeSystemClang::GetAsRecordDecl(type)) {
+ return record_decl->canPassInRegisters();
+ }
+ return false;
+}
+
+bool TypeSystemClang::SupportsLanguage(lldb::LanguageType language) {
+ return TypeSystemClangSupportsLanguage(language);
+}
+
+Optional<std::string>
+TypeSystemClang::GetCXXClassName(const CompilerType &type) {
+ if (!type)
+ return llvm::None;
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ if (qual_type.isNull())
+ return llvm::None;
+
+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (!cxx_record_decl)
+ return llvm::None;
+
+ return std::string(cxx_record_decl->getIdentifier()->getNameStart());
+}
+
+bool TypeSystemClang::IsCXXClassType(const CompilerType &type) {
+ if (!type)
+ return false;
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr;
+}
+
+bool TypeSystemClang::IsBeingDefined(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
+ if (tag_type)
+ return tag_type->isBeingDefined();
+ return false;
+}
+
+bool TypeSystemClang::IsObjCObjectPointerType(const CompilerType &type,
+ CompilerType *class_type_ptr) {
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+
+ if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
+ if (class_type_ptr) {
+ if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
+ const clang::ObjCObjectPointerType *obj_pointer_type =
+ llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+ if (obj_pointer_type == nullptr)
+ class_type_ptr->Clear();
+ else
+ class_type_ptr->SetCompilerType(
+ type.GetTypeSystem(),
+ clang::QualType(obj_pointer_type->getInterfaceType(), 0)
+ .getAsOpaquePtr());
+ }
+ }
+ return true;
+ }
+ if (class_type_ptr)
+ class_type_ptr->Clear();
+ return false;
+}
+
+// Type Completion
+
+bool TypeSystemClang::GetCompleteType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ const bool allow_completion = true;
+ return GetCompleteQualType(&getASTContext(), GetQualType(type),
+ allow_completion);
+}
+
+ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return ConstString();
+
+ clang::QualType qual_type(GetQualType(type));
+
+ // For a typedef just return the qualified name.
+ if (const auto *typedef_type = qual_type->getAs<clang::TypedefType>()) {
+ const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+ return ConstString(typedef_decl->getQualifiedNameAsString());
+ }
+
+ clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
+ printing_policy.SuppressTagKeyword = true;
+ return ConstString(qual_type.getAsString(printing_policy));
+}
+
+ConstString
+TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return ConstString();
+
+ clang::QualType qual_type(GetQualType(type));
+ clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
+ printing_policy.SuppressTagKeyword = true;
+ printing_policy.SuppressScope = false;
+ printing_policy.SuppressUnwrittenScope = true;
+ return ConstString(qual_type.getAsString(printing_policy));
+}
+
+uint32_t
+TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_or_element_clang_type) {
+ if (!type)
+ return 0;
+
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->Clear();
+
+ clang::QualType qual_type =
+ RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Attributed:
+ return GetTypeInfo(
+ qual_type->getAs<clang::AttributedType>()
+ ->getModifiedType().getAsOpaquePtr(),
+ pointee_or_element_clang_type);
+ case clang::Type::Builtin: {
+ const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
+ qual_type->getCanonicalTypeInternal());
+
+ uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+ switch (builtin_type->getKind()) {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr());
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::ObjCSel:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, getASTContext().CharTy.getAsOpaquePtr());
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ builtin_type_flags |= eTypeIsScalar;
+ if (builtin_type->isInteger()) {
+ builtin_type_flags |= eTypeIsInteger;
+ if (builtin_type->isSignedInteger())
+ builtin_type_flags |= eTypeIsSigned;
+ } else if (builtin_type->isFloatingPoint())
+ builtin_type_flags |= eTypeIsFloat;
+ break;
+ default:
+ break;
+ }
+ return builtin_type_flags;
+ }
+
+ case clang::Type::BlockPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, qual_type->getPointeeType().getAsOpaquePtr());
+ return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+
+ case clang::Type::Complex: {
+ uint32_t complex_type_flags =
+ eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+ const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
+ qual_type->getCanonicalTypeInternal());
+ if (complex_type) {
+ clang::QualType complex_element_type(complex_type->getElementType());
+ if (complex_element_type->isIntegerType())
+ complex_type_flags |= eTypeIsFloat;
+ else if (complex_element_type->isFloatingType())
+ complex_type_flags |= eTypeIsInteger;
+ }
+ return complex_type_flags;
+ } break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::DependentSizedArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
+ ->getElementType()
+ .getAsOpaquePtr());
+ return eTypeHasChildren | eTypeIsArray;
+
+ case clang::Type::DependentName:
+ return 0;
+ case clang::Type::DependentSizedExtVector:
+ return eTypeHasChildren | eTypeIsVector;
+ case clang::Type::DependentTemplateSpecialization:
+ return eTypeIsTemplate;
+
+ case clang::Type::Enum:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, llvm::cast<clang::EnumType>(qual_type)
+ ->getDecl()
+ ->getIntegerType()
+ .getAsOpaquePtr());
+ return eTypeIsEnumeration | eTypeHasValue;
+
+ case clang::Type::FunctionProto:
+ return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::FunctionNoProto:
+ return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::InjectedClassName:
+ return 0;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
+ ->getPointeeType()
+ .getAsOpaquePtr());
+ return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
+
+ case clang::Type::MemberPointer:
+ return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
+
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, qual_type->getPointeeType().getAsOpaquePtr());
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
+ eTypeHasValue;
+
+ case clang::Type::ObjCObject:
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+ case clang::Type::ObjCInterface:
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+
+ case clang::Type::Pointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ this, qual_type->getPointeeType().getAsOpaquePtr());
+ return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
+
+ case clang::Type::Record:
+ if (qual_type->getAsCXXRecordDecl())
+ return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
+ else
+ return eTypeHasChildren | eTypeIsStructUnion;
+ break;
+ case clang::Type::SubstTemplateTypeParm:
+ return eTypeIsTemplate;
+ case clang::Type::TemplateTypeParm:
+ return eTypeIsTemplate;
+ case clang::Type::TemplateSpecialization:
+ return eTypeIsTemplate;
+
+ case clang::Type::Typedef:
+ return eTypeIsTypedef | GetType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetTypeInfo(pointee_or_element_clang_type);
+ case clang::Type::UnresolvedUsing:
+ return 0;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector: {
+ uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+ const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
+ qual_type->getCanonicalTypeInternal());
+ if (vector_type) {
+ if (vector_type->isIntegerType())
+ vector_type_flags |= eTypeIsFloat;
+ else if (vector_type->isFloatingType())
+ vector_type_flags |= eTypeIsInteger;
+ }
+ return vector_type_flags;
+ }
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+lldb::LanguageType
+TypeSystemClang::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return lldb::eLanguageTypeC;
+
+ // If the type is a reference, then resolve it to what it refers to first:
+ clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
+ if (qual_type->isAnyPointerType()) {
+ if (qual_type->isObjCObjectPointerType())
+ return lldb::eLanguageTypeObjC;
+ if (qual_type->getPointeeCXXRecordDecl())
+ return lldb::eLanguageTypeC_plus_plus;
+
+ clang::QualType pointee_type(qual_type->getPointeeType());
+ if (pointee_type->getPointeeCXXRecordDecl())
+ return lldb::eLanguageTypeC_plus_plus;
+ if (pointee_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type->isObjCClassType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type.getTypePtr() ==
+ getASTContext().ObjCBuiltinIdTy.getTypePtr())
+ return lldb::eLanguageTypeObjC;
+ } else {
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (qual_type->getAsCXXRecordDecl())
+ return lldb::eLanguageTypeC_plus_plus;
+ switch (qual_type->getTypeClass()) {
+ default:
+ break;
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ break;
+
+ case clang::BuiltinType::NullPtr:
+ return eLanguageTypeC_plus_plus;
+
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ return eLanguageTypeObjC;
+
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::UnknownAny:
+ break;
+ }
+ break;
+ case clang::Type::Typedef:
+ return GetType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetMinimumLanguage();
+ }
+ }
+ return lldb::eLanguageTypeC;
+}
+
+lldb::TypeClass
+TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return lldb::eTypeClassInvalid;
+
+ clang::QualType qual_type =
+ RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Atomic:
+ case clang::Type::Auto:
+ case clang::Type::Decltype:
+ case clang::Type::Elaborated:
+ case clang::Type::Paren:
+ case clang::Type::TypeOf:
+ case clang::Type::TypeOfExpr:
+ llvm_unreachable("Handled in RemoveWrappingTypes!");
+ case clang::Type::UnaryTransform:
+ break;
+ case clang::Type::FunctionNoProto:
+ return lldb::eTypeClassFunction;
+ case clang::Type::FunctionProto:
+ return lldb::eTypeClassFunction;
+ case clang::Type::IncompleteArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::VariableArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::ConstantArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::DependentSizedArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::DependentSizedExtVector:
+ return lldb::eTypeClassVector;
+ case clang::Type::DependentVector:
+ return lldb::eTypeClassVector;
+ case clang::Type::ExtVector:
+ return lldb::eTypeClassVector;
+ case clang::Type::Vector:
+ return lldb::eTypeClassVector;
+ case clang::Type::Builtin:
+ // Ext-Int is just an integer type.
+ case clang::Type::ExtInt:
+ case clang::Type::DependentExtInt:
+ return lldb::eTypeClassBuiltin;
+ case clang::Type::ObjCObjectPointer:
+ return lldb::eTypeClassObjCObjectPointer;
+ case clang::Type::BlockPointer:
+ return lldb::eTypeClassBlockPointer;
+ case clang::Type::Pointer:
+ return lldb::eTypeClassPointer;
+ case clang::Type::LValueReference:
+ return lldb::eTypeClassReference;
+ case clang::Type::RValueReference:
+ return lldb::eTypeClassReference;
+ case clang::Type::MemberPointer:
+ return lldb::eTypeClassMemberPointer;
+ case clang::Type::Complex:
+ if (qual_type->isComplexType())
+ return lldb::eTypeClassComplexFloat;
+ else
+ return lldb::eTypeClassComplexInteger;
+ case clang::Type::ObjCObject:
+ return lldb::eTypeClassObjCObject;
+ case clang::Type::ObjCInterface:
+ return lldb::eTypeClassObjCInterface;
+ case clang::Type::Record: {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl->isUnion())
+ return lldb::eTypeClassUnion;
+ else if (record_decl->isStruct())
+ return lldb::eTypeClassStruct;
+ else
+ return lldb::eTypeClassClass;
+ } break;
+ case clang::Type::Enum:
+ return lldb::eTypeClassEnumeration;
+ case clang::Type::Typedef:
+ return lldb::eTypeClassTypedef;
+ case clang::Type::UnresolvedUsing:
+ break;
+
+ case clang::Type::Attributed:
+ break;
+ case clang::Type::TemplateTypeParm:
+ break;
+ case clang::Type::SubstTemplateTypeParm:
+ break;
+ case clang::Type::SubstTemplateTypeParmPack:
+ break;
+ case clang::Type::InjectedClassName:
+ break;
+ case clang::Type::DependentName:
+ break;
+ case clang::Type::DependentTemplateSpecialization:
+ break;
+ case clang::Type::PackExpansion:
+ break;
+
+ case clang::Type::TemplateSpecialization:
+ break;
+ case clang::Type::DeducedTemplateSpecialization:
+ break;
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::Adjusted:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
+ case clang::Type::MacroQualified:
+ break;
+
+ // Matrix types that we're not sure how to display at the moment.
+ case clang::Type::ConstantMatrix:
+ case clang::Type::DependentSizedMatrix:
+ break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eTypeClassOther;
+}
+
+unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetQualType(type).getQualifiers().getCVRQualifiers();
+ return 0;
+}
+
+// Creating related types
+
+CompilerType
+TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type,
+ uint64_t *stride) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+
+ const clang::Type *array_eletype =
+ qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
+
+ if (!array_eletype)
+ return CompilerType();
+
+ CompilerType element_type = GetType(clang::QualType(array_eletype, 0));
+
+ // TODO: the real stride will be >= this value.. find the real one!
+ if (stride)
+ if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
+ *stride = *size;
+
+ return element_type;
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type,
+ uint64_t size) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ clang::ASTContext &ast_ctx = getASTContext();
+ if (size != 0)
+ return GetType(ast_ctx.getConstantArrayType(
+ qual_type, llvm::APInt(64, size), nullptr,
+ clang::ArrayType::ArraySizeModifier::Normal, 0));
+ else
+ return GetType(ast_ctx.getIncompleteArrayType(
+ qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
+ }
+
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetCanonicalType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetType(GetCanonicalQualType(type));
+ return CompilerType();
+}
+
+static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
+ clang::QualType qual_type) {
+ if (qual_type->isPointerType())
+ qual_type = ast->getPointerType(
+ GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
+ else
+ qual_type = qual_type.getUnqualifiedType();
+ qual_type.removeLocalConst();
+ qual_type.removeLocalRestrict();
+ qual_type.removeLocalVolatile();
+ return qual_type;
+}
+
+CompilerType
+TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetType(
+ GetFullyUnqualifiedType_Impl(&getASTContext(), GetQualType(type)));
+ return CompilerType();
+}
+
+int TypeSystemClang::GetFunctionArgumentCount(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
+ if (func)
+ return func->getNumParams();
+ }
+ return -1;
+}
+
+CompilerType TypeSystemClang::GetFunctionArgumentTypeAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx) {
+ if (type) {
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
+ if (func) {
+ const uint32_t num_args = func->getNumParams();
+ if (idx < num_args)
+ return GetType(func->getParamType(idx));
+ }
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return GetType(func->getReturnType());
+ }
+ return CompilerType();
+}
+
+size_t
+TypeSystemClang::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
+ size_t num_functions = 0;
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Record:
+ if (GetCompleteQualType(&getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ num_functions = std::distance(cxx_record_decl->method_begin(),
+ cxx_record_decl->method_end());
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAs<clang::ObjCObjectPointerType>();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ num_functions = std::distance(class_interface_decl->meth_begin(),
+ class_interface_decl->meth_end());
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl)
+ num_functions = std::distance(class_interface_decl->meth_begin(),
+ class_interface_decl->meth_end());
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return num_functions;
+}
+
+TypeMemberFunctionImpl
+TypeSystemClang::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ std::string name;
+ MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
+ CompilerType clang_type;
+ CompilerDecl clang_decl;
+ if (type) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Record:
+ if (GetCompleteQualType(&getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ auto method_iter = cxx_record_decl->method_begin();
+ auto method_end = cxx_record_decl->method_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::CXXMethodDecl *cxx_method_decl =
+ method_iter->getCanonicalDecl();
+ if (cxx_method_decl) {
+ name = cxx_method_decl->getDeclName().getAsString();
+ if (cxx_method_decl->isStatic())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
+ kind = lldb::eMemberFunctionKindConstructor;
+ else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
+ kind = lldb::eMemberFunctionKindDestructor;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ clang_type = GetType(cxx_method_decl->getType());
+ clang_decl = GetCompilerDecl(cxx_method_decl);
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAs<clang::ObjCObjectPointerType>();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ auto method_iter = class_interface_decl->meth_begin();
+ auto method_end = class_interface_decl->meth_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::ObjCMethodDecl *objc_method_decl =
+ method_iter->getCanonicalDecl();
+ if (objc_method_decl) {
+ clang_decl = GetCompilerDecl(objc_method_decl);
+ name = objc_method_decl->getSelector().getAsString();
+ if (objc_method_decl->isClassMethod())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl) {
+ auto method_iter = class_interface_decl->meth_begin();
+ auto method_end = class_interface_decl->meth_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::ObjCMethodDecl *objc_method_decl =
+ method_iter->getCanonicalDecl();
+ if (objc_method_decl) {
+ clang_decl = GetCompilerDecl(objc_method_decl);
+ name = objc_method_decl->getSelector().getAsString();
+ if (objc_method_decl->isClassMethod())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (kind == eMemberFunctionKindUnknown)
+ return TypeMemberFunctionImpl();
+ else
+ return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
+}
+
+CompilerType
+TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetType(GetQualType(type).getNonReferenceType());
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::CreateTypedefType(
+ const CompilerType &type, const char *typedef_name,
+ const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
+ if (type && typedef_name && typedef_name[0]) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return CompilerType();
+ clang::ASTContext &clang_ast = ast->getASTContext();
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
+
+ clang::DeclContext *decl_ctx =
+ TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
+ if (!decl_ctx)
+ decl_ctx = ast->getASTContext().getTranslationUnitDecl();
+
+ clang::TypedefDecl *decl =
+ clang::TypedefDecl::CreateDeserialized(clang_ast, 0);
+ decl->setDeclContext(decl_ctx);
+ decl->setDeclName(&clang_ast.Idents.get(typedef_name));
+ decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
+
+ SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
+ decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+
+ decl_ctx->addDecl(decl);
+
+ // Get a uniqued clang::QualType for the typedef decl type
+ return ast->GetType(clang_ast.getTypedefType(decl));
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ return GetType(qual_type.getTypePtr()->getPointeeType());
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+
+ switch (qual_type.getDesugaredType(getASTContext())->getTypeClass()) {
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return GetType(getASTContext().getObjCObjectPointerType(qual_type));
+
+ default:
+ return GetType(getASTContext().getPointerType(qual_type));
+ }
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetType(getASTContext().getLValueReferenceType(GetQualType(type)));
+ else
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetType(getASTContext().getRValueReferenceType(GetQualType(type)));
+ else
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetAtomicType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return CompilerType();
+ return GetType(getASTContext().getAtomicType(GetQualType(type)));
+}
+
+CompilerType
+TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addConst();
+ return GetType(result);
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addVolatile();
+ return GetType(result);
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addRestrict();
+ return GetType(result);
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::CreateTypedef(
+ lldb::opaque_compiler_type_t type, const char *typedef_name,
+ const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
+ if (type) {
+ clang::ASTContext &clang_ast = getASTContext();
+ clang::QualType qual_type(GetQualType(type));
+
+ clang::DeclContext *decl_ctx =
+ TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
+ if (!decl_ctx)
+ decl_ctx = getASTContext().getTranslationUnitDecl();
+
+ clang::TypedefDecl *decl = clang::TypedefDecl::Create(
+ clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
+ &clang_ast.Idents.get(typedef_name),
+ clang_ast.getTrivialTypeSourceInfo(qual_type));
+ SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
+
+ clang::TagDecl *tdecl = nullptr;
+ if (!qual_type.isNull()) {
+ if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
+ tdecl = rt->getDecl();
+ if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+ tdecl = et->getDecl();
+ }
+
+ // Check whether this declaration is an anonymous struct, union, or enum,
+ // hidden behind a typedef. If so, we try to check whether we have a
+ // typedef tag to attach to the original record declaration
+ if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
+ tdecl->setTypedefNameForAnonDecl(decl);
+
+ decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+
+ // Get a uniqued clang::QualType for the typedef decl type
+ return GetType(clang_ast.getTypedefType(decl));
+ }
+ return CompilerType();
+}
+
+CompilerType
+TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(
+ RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}));
+ if (typedef_type)
+ return GetType(typedef_type->getDecl()->getUnderlyingType());
+ }
+ return CompilerType();
+}
+
+// Create related types using the current type's AST
+
+CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) {
+ return TypeSystemClang::GetBasicType(basic_type);
+}
+// Exploring the type
+
+const llvm::fltSemantics &
+TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) {
+ clang::ASTContext &ast = getASTContext();
+ const size_t bit_size = byte_size * 8;
+ if (bit_size == ast.getTypeSize(ast.FloatTy))
+ return ast.getFloatTypeSemantics(ast.FloatTy);
+ else if (bit_size == ast.getTypeSize(ast.DoubleTy))
+ return ast.getFloatTypeSemantics(ast.DoubleTy);
+ else if (bit_size == ast.getTypeSize(ast.LongDoubleTy))
+ return ast.getFloatTypeSemantics(ast.LongDoubleTy);
+ else if (bit_size == ast.getTypeSize(ast.HalfTy))
+ return ast.getFloatTypeSemantics(ast.HalfTy);
+ return llvm::APFloatBase::Bogus();
+}
+
+Optional<uint64_t>
+TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) {
+ if (GetCompleteType(type)) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type))
+ return getASTContext().getTypeSize(qual_type);
+ else
+ return None;
+ break;
+
+ case clang::Type::ObjCInterface:
+ case clang::Type::ObjCObject: {
+ ExecutionContext exe_ctx(exe_scope);
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
+ if (objc_runtime) {
+ uint64_t bit_size = 0;
+ if (objc_runtime->GetTypeBitSize(GetType(qual_type), bit_size))
+ return bit_size;
+ }
+ } else {
+ static bool g_printed = false;
+ if (!g_printed) {
+ StreamString s;
+ DumpTypeDescription(type, &s);
+
+ llvm::outs() << "warning: trying to determine the size of type ";
+ llvm::outs() << s.GetString() << "\n";
+ llvm::outs() << "without a valid ExecutionContext. this is not "
+ "reliable. please file a bug against LLDB.\n";
+ llvm::outs() << "backtrace:\n";
+ llvm::sys::PrintStackTrace(llvm::outs());
+ llvm::outs() << "\n";
+ g_printed = true;
+ }
+ }
+ }
+ LLVM_FALLTHROUGH;
+ default:
+ const uint32_t bit_size = getASTContext().getTypeSize(qual_type);
+ if (bit_size == 0) {
+ if (qual_type->isIncompleteArrayType())
+ return getASTContext().getTypeSize(
+ qual_type->getArrayElementTypeNoTypeQual()
+ ->getCanonicalTypeUnqualified());
+ }
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return bit_size +
+ getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy);
+ // Function types actually have a size of 0, that's not an error.
+ if (qual_type->isFunctionProtoType())
+ return bit_size;
+ if (bit_size)
+ return bit_size;
+ }
+ }
+ return None;
+}
+
+llvm::Optional<size_t>
+TypeSystemClang::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) {
+ if (GetCompleteType(type))
+ return getASTContext().getTypeAlign(GetQualType(type));
+ return {};
+}
+
+lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
+ uint64_t &count) {
+ if (!type)
+ return lldb::eEncodingInvalid;
+
+ count = 1;
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Atomic:
+ case clang::Type::Auto:
+ case clang::Type::Decltype:
+ case clang::Type::Elaborated:
+ case clang::Type::Paren:
+ case clang::Type::Typedef:
+ case clang::Type::TypeOf:
+ case clang::Type::TypeOfExpr:
+ llvm_unreachable("Handled in RemoveWrappingTypes!");
+
+ case clang::Type::UnaryTransform:
+ break;
+
+ case clang::Type::FunctionNoProto:
+ case clang::Type::FunctionProto:
+ break;
+
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ break;
+
+ case clang::Type::ConstantArray:
+ break;
+
+ case clang::Type::DependentVector:
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ // TODO: Set this to more than one???
+ break;
+
+ case clang::Type::ExtInt:
+ case clang::Type::DependentExtInt:
+ return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint
+ : lldb::eEncodingSint;
+
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::Void:
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ return lldb::eEncodingSint;
+
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char8:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ return lldb::eEncodingUint;
+
+ // Fixed point types. Note that they are currently ignored.
+ case clang::BuiltinType::ShortAccum:
+ case clang::BuiltinType::Accum:
+ case clang::BuiltinType::LongAccum:
+ case clang::BuiltinType::UShortAccum:
+ case clang::BuiltinType::UAccum:
+ case clang::BuiltinType::ULongAccum:
+ case clang::BuiltinType::ShortFract:
+ case clang::BuiltinType::Fract:
+ case clang::BuiltinType::LongFract:
+ case clang::BuiltinType::UShortFract:
+ case clang::BuiltinType::UFract:
+ case clang::BuiltinType::ULongFract:
+ case clang::BuiltinType::SatShortAccum:
+ case clang::BuiltinType::SatAccum:
+ case clang::BuiltinType::SatLongAccum:
+ case clang::BuiltinType::SatUShortAccum:
+ case clang::BuiltinType::SatUAccum:
+ case clang::BuiltinType::SatULongAccum:
+ case clang::BuiltinType::SatShortFract:
+ case clang::BuiltinType::SatFract:
+ case clang::BuiltinType::SatLongFract:
+ case clang::BuiltinType::SatUShortFract:
+ case clang::BuiltinType::SatUFract:
+ case clang::BuiltinType::SatULongFract:
+ break;
+
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Float16:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::BFloat16:
+ return lldb::eEncodingIEEE754;
+
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCSel:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::NullPtr:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Kind::ARCUnbridgedCast:
+ case clang::BuiltinType::Kind::BoundMember:
+ case clang::BuiltinType::Kind::BuiltinFn:
+ case clang::BuiltinType::Kind::Dependent:
+ case clang::BuiltinType::Kind::OCLClkEvent:
+ case clang::BuiltinType::Kind::OCLEvent:
+ case clang::BuiltinType::Kind::OCLImage1dRO:
+ case clang::BuiltinType::Kind::OCLImage1dWO:
+ case clang::BuiltinType::Kind::OCLImage1dRW:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferWO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRW:
+ case clang::BuiltinType::Kind::OCLImage2dRO:
+ case clang::BuiltinType::Kind::OCLImage2dWO:
+ case clang::BuiltinType::Kind::OCLImage2dRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage3dRO:
+ case clang::BuiltinType::Kind::OCLImage3dWO:
+ case clang::BuiltinType::Kind::OCLImage3dRW:
+ case clang::BuiltinType::Kind::OCLQueue:
+ case clang::BuiltinType::Kind::OCLReserveID:
+ case clang::BuiltinType::Kind::OCLSampler:
+ case clang::BuiltinType::Kind::OMPArraySection:
+ case clang::BuiltinType::Kind::OMPArrayShaping:
+ case clang::BuiltinType::Kind::OMPIterator:
+ case clang::BuiltinType::Kind::Overload:
+ case clang::BuiltinType::Kind::PseudoObject:
+ case clang::BuiltinType::Kind::UnknownAny:
+ break;
+
+ case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
+ case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
+ case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
+ break;
+
+ case clang::BuiltinType::SveBool:
+ case clang::BuiltinType::SveInt8:
+ case clang::BuiltinType::SveInt8x2:
+ case clang::BuiltinType::SveInt8x3:
+ case clang::BuiltinType::SveInt8x4:
+ case clang::BuiltinType::SveInt16:
+ case clang::BuiltinType::SveInt16x2:
+ case clang::BuiltinType::SveInt16x3:
+ case clang::BuiltinType::SveInt16x4:
+ case clang::BuiltinType::SveInt32:
+ case clang::BuiltinType::SveInt32x2:
+ case clang::BuiltinType::SveInt32x3:
+ case clang::BuiltinType::SveInt32x4:
+ case clang::BuiltinType::SveInt64:
+ case clang::BuiltinType::SveInt64x2:
+ case clang::BuiltinType::SveInt64x3:
+ case clang::BuiltinType::SveInt64x4:
+ case clang::BuiltinType::SveUint8:
+ case clang::BuiltinType::SveUint8x2:
+ case clang::BuiltinType::SveUint8x3:
+ case clang::BuiltinType::SveUint8x4:
+ case clang::BuiltinType::SveUint16:
+ case clang::BuiltinType::SveUint16x2:
+ case clang::BuiltinType::SveUint16x3:
+ case clang::BuiltinType::SveUint16x4:
+ case clang::BuiltinType::SveUint32:
+ case clang::BuiltinType::SveUint32x2:
+ case clang::BuiltinType::SveUint32x3:
+ case clang::BuiltinType::SveUint32x4:
+ case clang::BuiltinType::SveUint64:
+ case clang::BuiltinType::SveUint64x2:
+ case clang::BuiltinType::SveUint64x3:
+ case clang::BuiltinType::SveUint64x4:
+ case clang::BuiltinType::SveFloat16:
+ case clang::BuiltinType::SveBFloat16:
+ case clang::BuiltinType::SveBFloat16x2:
+ case clang::BuiltinType::SveBFloat16x3:
+ case clang::BuiltinType::SveBFloat16x4:
+ case clang::BuiltinType::SveFloat16x2:
+ case clang::BuiltinType::SveFloat16x3:
+ case clang::BuiltinType::SveFloat16x4:
+ case clang::BuiltinType::SveFloat32:
+ case clang::BuiltinType::SveFloat32x2:
+ case clang::BuiltinType::SveFloat32x3:
+ case clang::BuiltinType::SveFloat32x4:
+ case clang::BuiltinType::SveFloat64:
+ case clang::BuiltinType::SveFloat64x2:
+ case clang::BuiltinType::SveFloat64x3:
+ case clang::BuiltinType::SveFloat64x4:
+ break;
+
+ case clang::BuiltinType::IncompleteMatrixIdx:
+ break;
+ }
+ break;
+ // All pointer types are represented as unsigned integer encodings. We may
+ // nee to add a eEncodingPointer if we ever need to know the difference
+ case clang::Type::ObjCObjectPointer:
+ case clang::Type::BlockPointer:
+ case clang::Type::Pointer:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::MemberPointer:
+ return lldb::eEncodingUint;
+ case clang::Type::Complex: {
+ lldb::Encoding encoding = lldb::eEncodingIEEE754;
+ if (qual_type->isComplexType())
+ encoding = lldb::eEncodingIEEE754;
+ else {
+ const clang::ComplexType *complex_type =
+ qual_type->getAsComplexIntegerType();
+ if (complex_type)
+ encoding = GetType(complex_type->getElementType()).GetEncoding(count);
+ else
+ encoding = lldb::eEncodingSint;
+ }
+ count = 2;
+ return encoding;
+ }
+
+ case clang::Type::ObjCInterface:
+ break;
+ case clang::Type::Record:
+ break;
+ case clang::Type::Enum:
+ return lldb::eEncodingSint;
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::DeducedTemplateSpecialization:
+ case clang::Type::Adjusted:
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
+ case clang::Type::MacroQualified:
+ break;
+
+ case clang::Type::ConstantMatrix:
+ case clang::Type::DependentSizedMatrix:
+ break;
+ }
+ count = 0;
+ return lldb::eEncodingInvalid;
+}
+
+lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return lldb::eFormatDefault;
+
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Atomic:
+ case clang::Type::Auto:
+ case clang::Type::Decltype:
+ case clang::Type::Elaborated:
+ case clang::Type::Paren:
+ case clang::Type::Typedef:
+ case clang::Type::TypeOf:
+ case clang::Type::TypeOfExpr:
+ llvm_unreachable("Handled in RemoveWrappingTypes!");
+ case clang::Type::UnaryTransform:
+ break;
+
+ case clang::Type::FunctionNoProto:
+ case clang::Type::FunctionProto:
+ break;
+
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ break;
+
+ case clang::Type::ConstantArray:
+ return lldb::eFormatVoid; // no value
+
+ case clang::Type::DependentVector:
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ break;
+
+ case clang::Type::ExtInt:
+ case clang::Type::DependentExtInt:
+ return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned
+ : lldb::eFormatDecimal;
+
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::BoundMember:
+ break;
+
+ case clang::BuiltinType::Bool:
+ return lldb::eFormatBoolean;
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ return lldb::eFormatChar;
+ case clang::BuiltinType::Char16:
+ return lldb::eFormatUnicode16;
+ case clang::BuiltinType::Char32:
+ return lldb::eFormatUnicode32;
+ case clang::BuiltinType::UShort:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Short:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::UInt:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Int:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::ULong:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Long:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::ULongLong:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::LongLong:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::UInt128:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Int128:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ return lldb::eFormatFloat;
+ default:
+ return lldb::eFormatHex;
+ }
+ break;
+ case clang::Type::ObjCObjectPointer:
+ return lldb::eFormatHex;
+ case clang::Type::BlockPointer:
+ return lldb::eFormatHex;
+ case clang::Type::Pointer:
+ return lldb::eFormatHex;
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ return lldb::eFormatHex;
+ case clang::Type::MemberPointer:
+ break;
+ case clang::Type::Complex: {
+ if (qual_type->isComplexType())
+ return lldb::eFormatComplex;
+ else
+ return lldb::eFormatComplexInteger;
+ }
+ case clang::Type::ObjCInterface:
+ break;
+ case clang::Type::Record:
+ break;
+ case clang::Type::Enum:
+ return lldb::eFormatEnum;
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::DeducedTemplateSpecialization:
+ case clang::Type::Adjusted:
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+
+ case clang::Type::DependentAddressSpace:
+ break;
+ case clang::Type::MacroQualified:
+ break;
+
+ // Matrix types we're not sure how to display yet.
+ case clang::Type::ConstantMatrix:
+ case clang::Type::DependentSizedMatrix:
+ break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eFormatBytes;
+}
+
+static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
+ bool check_superclass) {
+ while (class_interface_decl) {
+ if (class_interface_decl->ivar_size() > 0)
+ return true;
+
+ if (check_superclass)
+ class_interface_decl = class_interface_decl->getSuperClass();
+ else
+ break;
+ }
+ return false;
+}
+
+static Optional<SymbolFile::ArrayInfo>
+GetDynamicArrayInfo(TypeSystemClang &ast, SymbolFile *sym_file,
+ clang::QualType qual_type,
+ const ExecutionContext *exe_ctx) {
+ if (qual_type->isIncompleteArrayType())
+ if (auto *metadata = ast.GetMetadata(qual_type.getTypePtr()))
+ return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(),
+ exe_ctx);
+ return llvm::None;
+}
+
+uint32_t TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) {
+ if (!type)
+ return 0;
+
+ uint32_t num_children = 0;
+ clang::QualType qual_type(RemoveWrappingTypes(GetQualType(type)));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::ObjCId: // child is Class
+ case clang::BuiltinType::ObjCClass: // child is Class
+ num_children = 1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case clang::Type::Complex:
+ return 0;
+ case clang::Type::Record:
+ if (GetCompleteQualType(&getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ if (omit_empty_base_classes) {
+ // Check each base classes to see if it or any of its base classes
+ // contain any fields. This can help limit the noise in variable
+ // views by not having to show base classes that contain no members.
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+
+ // Skip empty base classes
+ if (!TypeSystemClang::RecordHasFields(base_class_decl))
+ continue;
+
+ num_children++;
+ }
+ } else {
+ // Include all base classes
+ num_children += cxx_record_decl->getNumBases();
+ }
+ }
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field)
+ ++num_children;
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteQualType(&getASTContext(), qual_type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (omit_empty_base_classes) {
+ if (ObjCDeclHasIVars(superclass_interface_decl, true))
+ ++num_children;
+ } else
+ ++num_children;
+ }
+
+ num_children += class_interface_decl->ivar_size();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::ObjCObjectPointer: {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ uint32_t num_pointee_children = 0;
+ if (pointee_clang_type.IsAggregateType())
+ num_pointee_children =
+ pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
+ // If this type points to a simple type, then it has 1 child
+ if (num_pointee_children == 0)
+ num_children = 1;
+ else
+ num_children = num_pointee_children;
+ } break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ num_children =
+ llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
+ break;
+
+ case clang::Type::ConstantArray:
+ num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
+ ->getSize()
+ .getLimitedValue();
+ break;
+ case clang::Type::IncompleteArray:
+ if (auto array_info =
+ GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx))
+ // Only 1-dimensional arrays are supported.
+ num_children = array_info->element_orders.size()
+ ? array_info->element_orders.back()
+ : 0;
+ break;
+
+ case clang::Type::Pointer: {
+ const clang::PointerType *pointer_type =
+ llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+ clang::QualType pointee_type(pointer_type->getPointeeType());
+ CompilerType pointee_clang_type(GetType(pointee_type));
+ uint32_t num_pointee_children = 0;
+ if (pointee_clang_type.IsAggregateType())
+ num_pointee_children =
+ pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx);
+ if (num_pointee_children == 0) {
+ // We have a pointer to a pointee type that claims it has no children. We
+ // will want to look at
+ num_children = GetNumPointeeChildren(pointee_type);
+ } else
+ num_children = num_pointee_children;
+ } break;
+
+ default:
+ break;
+ }
+ return num_children;
+}
+
+CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) {
+ return GetBasicType(GetBasicTypeEnumeration(name));
+}
+
+lldb::BasicType
+TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ if (type_class == clang::Type::Builtin) {
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::Void:
+ return eBasicTypeVoid;
+ case clang::BuiltinType::Bool:
+ return eBasicTypeBool;
+ case clang::BuiltinType::Char_S:
+ return eBasicTypeSignedChar;
+ case clang::BuiltinType::Char_U:
+ return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::Char16:
+ return eBasicTypeChar16;
+ case clang::BuiltinType::Char32:
+ return eBasicTypeChar32;
+ case clang::BuiltinType::UChar:
+ return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::SChar:
+ return eBasicTypeSignedChar;
+ case clang::BuiltinType::WChar_S:
+ return eBasicTypeSignedWChar;
+ case clang::BuiltinType::WChar_U:
+ return eBasicTypeUnsignedWChar;
+ case clang::BuiltinType::Short:
+ return eBasicTypeShort;
+ case clang::BuiltinType::UShort:
+ return eBasicTypeUnsignedShort;
+ case clang::BuiltinType::Int:
+ return eBasicTypeInt;
+ case clang::BuiltinType::UInt:
+ return eBasicTypeUnsignedInt;
+ case clang::BuiltinType::Long:
+ return eBasicTypeLong;
+ case clang::BuiltinType::ULong:
+ return eBasicTypeUnsignedLong;
+ case clang::BuiltinType::LongLong:
+ return eBasicTypeLongLong;
+ case clang::BuiltinType::ULongLong:
+ return eBasicTypeUnsignedLongLong;
+ case clang::BuiltinType::Int128:
+ return eBasicTypeInt128;
+ case clang::BuiltinType::UInt128:
+ return eBasicTypeUnsignedInt128;
+
+ case clang::BuiltinType::Half:
+ return eBasicTypeHalf;
+ case clang::BuiltinType::Float:
+ return eBasicTypeFloat;
+ case clang::BuiltinType::Double:
+ return eBasicTypeDouble;
+ case clang::BuiltinType::LongDouble:
+ return eBasicTypeLongDouble;
+
+ case clang::BuiltinType::NullPtr:
+ return eBasicTypeNullPtr;
+ case clang::BuiltinType::ObjCId:
+ return eBasicTypeObjCID;
+ case clang::BuiltinType::ObjCClass:
+ return eBasicTypeObjCClass;
+ case clang::BuiltinType::ObjCSel:
+ return eBasicTypeObjCSel;
+ default:
+ return eBasicTypeOther;
+ }
+ }
+ }
+ return eBasicTypeInvalid;
+}
+
+void TypeSystemClang::ForEachEnumerator(
+ lldb::opaque_compiler_type_t type,
+ std::function<bool(const CompilerType &integer_type,
+ ConstString name,
+ const llvm::APSInt &value)> const &callback) {
+ const clang::EnumType *enum_type =
+ llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+ if (enum_type) {
+ const clang::EnumDecl *enum_decl = enum_type->getDecl();
+ if (enum_decl) {
+ CompilerType integer_type = GetType(enum_decl->getIntegerType());
+
+ clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+ for (enum_pos = enum_decl->enumerator_begin(),
+ enum_end_pos = enum_decl->enumerator_end();
+ enum_pos != enum_end_pos; ++enum_pos) {
+ ConstString name(enum_pos->getNameAsString().c_str());
+ if (!callback(integer_type, name, enum_pos->getInitVal()))
+ break;
+ }
+ }
+ }
+}
+
+#pragma mark Aggregate Types
+
+uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return 0;
+
+ uint32_t count = 0;
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
+ if (record_type) {
+ clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field)
+ ++field_idx;
+ count = field_idx;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAs<clang::ObjCObjectPointerType>();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ count = class_interface_decl->ivar_size();
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ count = class_interface_decl->ivar_size();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+static lldb::opaque_compiler_type_t
+GetObjCFieldAtIndex(clang::ASTContext *ast,
+ clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
+ std::string &name, uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
+ if (class_interface_decl) {
+ if (idx < (class_interface_decl->ivar_size())) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ uint32_t ivar_idx = 0;
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
+ ++ivar_pos, ++ivar_idx) {
+ if (ivar_idx == idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ clang::QualType ivar_qual_type(ivar_decl->getType());
+
+ name.assign(ivar_decl->getNameAsString());
+
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &interface_layout =
+ ast->getASTObjCInterfaceLayout(class_interface_decl);
+ *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
+ }
+
+ const bool is_bitfield = ivar_pos->isBitField();
+
+ if (bitfield_bit_size_ptr) {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield && ast) {
+ clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+ clang::Expr::EvalResult result;
+ if (bitfield_bit_size_expr &&
+ bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) {
+ llvm::APSInt bitfield_apsint = result.Val.getInt();
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
+ return ivar_qual_type.getAsOpaquePtr();
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
+CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx, std::string &name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) {
+ if (!type)
+ return CompilerType();
+
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++field_idx) {
+ if (idx == field_idx) {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ name.assign(field->getNameAsString());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext().getASTRecordLayout(record_decl);
+ *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
+ }
+
+ const bool is_bitfield = field->isBitField();
+
+ if (bitfield_bit_size_ptr) {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield) {
+ clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
+ clang::Expr::EvalResult result;
+ if (bitfield_bit_size_expr &&
+ bitfield_bit_size_expr->EvaluateAsInt(result,
+ getASTContext())) {
+ llvm::APSInt bitfield_apsint = result.Val.getInt();
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
+ }
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
+ return GetType(field->getType());
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAs<clang::ObjCObjectPointerType>();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType(static_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ return CompilerType(
+ this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl,
+ idx, name, bit_offset_ptr,
+ bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ return CompilerType(
+ this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl,
+ idx, name, bit_offset_ptr,
+ bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+uint32_t
+TypeSystemClang::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
+ uint32_t count = 0;
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumBases();
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ count = GetPointeeType(type).GetNumDirectBaseClasses();
+ break;
+
+ case clang::Type::ObjCObject:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCInterfaceType *objc_interface_type =
+ qual_type->getAs<clang::ObjCInterfaceType>();
+ if (objc_interface_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getInterface();
+
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+uint32_t
+TypeSystemClang::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
+ uint32_t count = 0;
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumVBases();
+ }
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+CompilerType TypeSystemClang::GetDirectBaseClassAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ uint32_t curr_idx = 0;
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class, ++curr_idx) {
+ if (curr_idx == idx) {
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext().getASTRecordLayout(cxx_record_decl);
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ if (base_class->isVirtual())
+ *bit_offset_ptr =
+ record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ else
+ *bit_offset_ptr =
+ record_layout.getBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ }
+ return GetType(base_class->getType());
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
+
+ case clang::Type::ObjCObject:
+ if (idx == 0 && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return GetType(getASTContext().getObjCInterfaceType(
+ superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+ case clang::Type::ObjCInterface:
+ if (idx == 0 && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_interface_type =
+ qual_type->getAs<clang::ObjCInterfaceType>();
+ if (objc_interface_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return GetType(getASTContext().getObjCInterfaceType(
+ superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ uint32_t curr_idx = 0;
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->vbases_begin(),
+ base_class_end = cxx_record_decl->vbases_end();
+ base_class != base_class_end; ++base_class, ++curr_idx) {
+ if (curr_idx == idx) {
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext().getASTRecordLayout(cxx_record_decl);
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ *bit_offset_ptr =
+ record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ }
+ return GetType(base_class->getType());
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+// If a pointer to a pointee type (the clang_type arg) says that it has no
+// children, then we either need to trust it, or override it and return a
+// different result. For example, an "int *" has one child that is an integer,
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) {
+ if (type.isNull())
+ return 0;
+
+ clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage3dRW:
+ case clang::BuiltinType::OCLSampler:
+ return 0;
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OMPArraySection:
+ return 1;
+ default:
+ return 0;
+ }
+ break;
+
+ case clang::Type::Complex:
+ return 1;
+ case clang::Type::Pointer:
+ return 1;
+ case clang::Type::BlockPointer:
+ return 0; // If block pointers don't have debug info, then no children for
+ // them
+ case clang::Type::LValueReference:
+ return 1;
+ case clang::Type::RValueReference:
+ return 1;
+ case clang::Type::MemberPointer:
+ return 0;
+ case clang::Type::ConstantArray:
+ return 0;
+ case clang::Type::IncompleteArray:
+ return 0;
+ case clang::Type::VariableArray:
+ return 0;
+ case clang::Type::DependentSizedArray:
+ return 0;
+ case clang::Type::DependentSizedExtVector:
+ return 0;
+ case clang::Type::Vector:
+ return 0;
+ case clang::Type::ExtVector:
+ return 0;
+ case clang::Type::FunctionProto:
+ return 0; // When we function pointers, they have no children...
+ case clang::Type::FunctionNoProto:
+ return 0; // When we function pointers, they have no children...
+ case clang::Type::UnresolvedUsing:
+ return 0;
+ case clang::Type::Record:
+ return 0;
+ case clang::Type::Enum:
+ return 1;
+ case clang::Type::TemplateTypeParm:
+ return 1;
+ case clang::Type::SubstTemplateTypeParm:
+ return 1;
+ case clang::Type::TemplateSpecialization:
+ return 1;
+ case clang::Type::InjectedClassName:
+ return 0;
+ case clang::Type::DependentName:
+ return 1;
+ case clang::Type::DependentTemplateSpecialization:
+ return 1;
+ case clang::Type::ObjCObject:
+ return 0;
+ case clang::Type::ObjCInterface:
+ return 0;
+ case clang::Type::ObjCObjectPointer:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex(
+ lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+ bool transparent_pointers, bool omit_empty_base_classes,
+ bool ignore_array_bounds, std::string &child_name,
+ uint32_t &child_byte_size, int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class, bool &child_is_deref_of_parent,
+ ValueObject *valobj, uint64_t &language_flags) {
+ if (!type)
+ return CompilerType();
+
+ auto get_exe_scope = [&exe_ctx]() {
+ return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+ };
+
+ clang::QualType parent_qual_type(
+ RemoveWrappingTypes(GetCanonicalQualType(type)));
+ const clang::Type::TypeClass parent_type_class =
+ parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+ language_flags = 0;
+
+ const bool idx_is_valid =
+ idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx);
+ int32_t bit_offset;
+ switch (parent_type_class) {
+ case clang::Type::Builtin:
+ if (idx_is_valid) {
+ switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ child_name = "isa";
+ child_byte_size =
+ getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy) /
+ CHAR_BIT;
+ return GetType(getASTContext().ObjCBuiltinClassTy);
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext().getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ // We might have base classes to print out first
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const clang::CXXRecordDecl *base_class_decl = nullptr;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes) {
+ base_class_decl = llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()->getAs<clang::RecordType>()->getDecl());
+ if (!TypeSystemClang::RecordHasFields(base_class_decl))
+ continue;
+ }
+
+ if (idx == child_idx) {
+ if (base_class_decl == nullptr)
+ base_class_decl = llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()->getAs<clang::RecordType>()->getDecl());
+
+ if (base_class->isVirtual()) {
+ bool handled = false;
+ if (valobj) {
+ clang::VTableContextBase *vtable_ctx =
+ getASTContext().getVTableContext();
+ if (vtable_ctx)
+ handled = GetVBaseBitOffset(*vtable_ctx, *valobj,
+ record_layout, cxx_record_decl,
+ base_class_decl, bit_offset);
+ }
+ if (!handled)
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ } else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset / 8;
+ CompilerType base_class_clang_type = GetType(base_class->getType());
+ child_name = base_class_clang_type.GetTypeName().AsCString("");
+ Optional<uint64_t> size =
+ base_class_clang_type.GetBitSize(get_exe_scope());
+ if (!size)
+ return {};
+ uint64_t base_class_clang_type_bit_size = *size;
+
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert(base_class_clang_type_bit_size % 8 == 0);
+ child_byte_size = base_class_clang_type_bit_size / 8;
+ child_is_base_class = true;
+ return base_class_clang_type;
+ }
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
+ }
+ }
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++field_idx, ++child_idx) {
+ if (idx == child_idx) {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ CompilerType field_clang_type = GetType(field->getType());
+ assert(field_idx < record_layout.getFieldCount());
+ Optional<uint64_t> size =
+ field_clang_type.GetByteSize(get_exe_scope());
+ if (!size)
+ return {};
+ child_byte_size = *size;
+ const uint32_t child_bit_size = child_byte_size * 8;
+
+ // Figure out the field offset within the current struct/union/class
+ // type
+ bit_offset = record_layout.getFieldOffset(field_idx);
+ if (FieldIsBitfield(*field, child_bitfield_bit_size)) {
+ child_bitfield_bit_offset = bit_offset % child_bit_size;
+ const uint32_t child_bit_offset =
+ bit_offset - child_bitfield_bit_offset;
+ child_byte_offset = child_bit_offset / 8;
+ } else {
+ child_byte_offset = bit_offset / 8;
+ }
+
+ return field_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+
+ const clang::ASTRecordLayout &interface_layout =
+ getASTContext().getASTObjCInterfaceLayout(class_interface_decl);
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (omit_empty_base_classes) {
+ CompilerType base_class_clang_type =
+ GetType(getASTContext().getObjCInterfaceType(
+ superclass_interface_decl));
+ if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
+ exe_ctx) > 0) {
+ if (idx == 0) {
+ clang::QualType ivar_qual_type(
+ getASTContext().getObjCInterfaceType(
+ superclass_interface_decl));
+
+ child_name.assign(
+ superclass_interface_decl->getNameAsString());
+
+ clang::TypeInfo ivar_type_info =
+ getASTContext().getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.Width / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
+
+ return GetType(ivar_qual_type);
+ }
+
+ ++child_idx;
+ }
+ } else
+ ++child_idx;
+ }
+
+ const uint32_t superclass_idx = child_idx;
+
+ if (idx < (child_idx + class_interface_decl->ivar_size())) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos) {
+ if (child_idx == idx) {
+ clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ clang::QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString());
+
+ clang::TypeInfo ivar_type_info =
+ getASTContext().getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.Width / 8;
+
+ // Figure out the field offset within the current
+ // struct/union/class type For ObjC objects, we can't trust the
+ // bit offset we get from the Clang AST, since that doesn't
+ // account for the space taken up by unbacked properties, or
+ // from the changing size of base classes that are newer than
+ // this class. So if we have a process around that we can ask
+ // about this object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = nullptr;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process) {
+ ObjCLanguageRuntime *objc_runtime =
+ ObjCLanguageRuntime::Get(*process);
+ if (objc_runtime != nullptr) {
+ CompilerType parent_ast_type = GetType(parent_qual_type);
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar(
+ parent_ast_type, ivar_decl->getNameAsString().c_str());
+ }
+ }
+
+ // Setting this to INT32_MAX to make sure we don't compute it
+ // twice...
+ bit_offset = INT32_MAX;
+
+ if (child_byte_offset ==
+ static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
+ bit_offset = interface_layout.getFieldOffset(child_idx -
+ superclass_idx);
+ child_byte_offset = bit_offset / 8;
+ }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't
+ // account for the bit offset of a bitfield within its
+ // containing object. So regardless of where we get the byte
+ // offset from, we still need to get the bit offset for
+ // bitfields from the layout.
+
+ if (FieldIsBitfield(ivar_decl, child_bitfield_bit_size)) {
+ if (bit_offset == INT32_MAX)
+ bit_offset = interface_layout.getFieldOffset(
+ child_idx - superclass_idx);
+
+ child_bitfield_bit_offset = bit_offset % 8;
+ }
+ return GetType(ivar_qual_type);
+ }
+ ++child_idx;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid) {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ child_is_deref_of_parent = true;
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : nullptr;
+ if (parent_name) {
+ child_name.assign(1, '*');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0 && pointee_clang_type.GetCompleteType()) {
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ if (idx_is_valid) {
+ const clang::VectorType *array =
+ llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
+ if (array) {
+ CompilerType element_type = GetType(array->getElementType());
+ if (element_type.GetCompleteType()) {
+ char element_name[64];
+ ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
+ static_cast<uint64_t>(idx));
+ child_name.assign(element_name);
+ if (Optional<uint64_t> size =
+ element_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid) {
+ const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
+ if (array) {
+ CompilerType element_type = GetType(array->getElementType());
+ if (element_type.GetCompleteType()) {
+ child_name = std::string(llvm::formatv("[{0}]", idx));
+ if (Optional<uint64_t> size =
+ element_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Pointer: {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ // Don't dereference "void *" pointers
+ if (pointee_clang_type.IsVoidType())
+ return CompilerType();
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ child_is_deref_of_parent = true;
+
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : nullptr;
+ if (parent_name) {
+ child_name.assign(1, '*');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0) {
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+ }
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid) {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+ CompilerType pointee_clang_type =
+ GetType(reference_type->getPointeeType());
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : nullptr;
+ if (parent_name) {
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0) {
+ if (Optional<uint64_t> size =
+ pointee_clang_type.GetByteSize(get_exe_scope())) {
+ child_byte_size = *size;
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
+ const clang::CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes) {
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ if (cxx_record_decl) {
+ clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ if (omit_empty_base_classes) {
+ if (BaseSpecifierIsEmpty(base_class))
+ continue;
+ }
+
+ if (base_class == base_spec)
+ return child_idx;
+ ++child_idx;
+ }
+ }
+
+ return UINT32_MAX;
+}
+
+static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
+ clang::NamedDecl *canonical_decl,
+ bool omit_empty_base_classes) {
+ uint32_t child_idx = TypeSystemClang::GetNumBaseClasses(
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
+ omit_empty_base_classes);
+
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ if (field->getCanonicalDecl() == canonical_decl)
+ return child_idx;
+ }
+
+ return UINT32_MAX;
+}
+
+// Look for a child member (doesn't include base classes, but it does include
+// their members) in the type hierarchy. Returns an index path into
+// "clang_type" on how to reach the appropriate member.
+//
+// class A
+// {
+// public:
+// int m_a;
+// int m_b;
+// };
+//
+// class B
+// {
+// };
+//
+// class C :
+// public B,
+// public A
+// {
+// };
+//
+// If we have a clang type that describes "class C", and we wanted to looked
+// "m_b" in it:
+//
+// With omit_empty_base_classes == false we would get an integer array back
+// with: { 1, 1 } The first index 1 is the child index for "class A" within
+// class C The second index 1 is the child index for "m_b" within class A
+//
+// With omit_empty_base_classes == true we would get an integer array back
+// with: { 0, 1 } The first index 0 is the child index for "class A" within
+// class C (since class B doesn't have any members it doesn't count) The second
+// index 1 is the child index for "m_b" within class A
+
+size_t TypeSystemClang::GetIndexOfChildMemberWithName(
+ lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
+ if (type && name && name[0]) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ // Try and find a field that matches NAME
+ clang::RecordDecl::field_iterator field, field_end;
+ llvm::StringRef name_sref(name);
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ llvm::StringRef field_name = field->getName();
+ if (field_name.empty()) {
+ CompilerType field_type = GetType(field->getType());
+ child_indexes.push_back(child_idx);
+ if (field_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes))
+ return child_indexes.size();
+ child_indexes.pop_back();
+
+ } else if (field_name.equals(name_sref)) {
+ // We have to add on the number of base classes to this index!
+ child_indexes.push_back(
+ child_idx + TypeSystemClang::GetNumBaseClasses(
+ cxx_record_decl, omit_empty_base_classes));
+ return child_indexes.size();
+ }
+ }
+
+ if (cxx_record_decl) {
+ const clang::RecordDecl *parent_record_decl = cxx_record_decl;
+
+ // Didn't find things easily, lets let clang do its thang...
+ clang::IdentifierInfo &ident_ref =
+ getASTContext().Idents.get(name_sref);
+ clang::DeclarationName decl_name(&ident_ref);
+
+ clang::CXXBasePaths paths;
+ if (cxx_record_decl->lookupInBases(
+ [decl_name](const clang::CXXBaseSpecifier *specifier,
+ clang::CXXBasePath &path) {
+ return clang::CXXRecordDecl::FindOrdinaryMember(
+ specifier, path, decl_name);
+ },
+ paths)) {
+ clang::CXXBasePaths::const_paths_iterator path,
+ path_end = paths.end();
+ for (path = paths.begin(); path != path_end; ++path) {
+ const size_t num_path_elements = path->size();
+ for (size_t e = 0; e < num_path_elements; ++e) {
+ clang::CXXBasePathElement elem = (*path)[e];
+
+ child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
+ omit_empty_base_classes);
+ if (child_idx == UINT32_MAX) {
+ child_indexes.clear();
+ return 0;
+ } else {
+ child_indexes.push_back(child_idx);
+ parent_record_decl = llvm::cast<clang::RecordDecl>(
+ elem.Base->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ }
+ }
+ for (clang::NamedDecl *path_decl : path->Decls) {
+ child_idx = GetIndexForRecordChild(
+ parent_record_decl, path_decl, omit_empty_base_classes);
+ if (child_idx == UINT32_MAX) {
+ child_indexes.clear();
+ return 0;
+ } else {
+ child_indexes.push_back(child_idx);
+ }
+ }
+ }
+ return child_indexes.size();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ llvm::StringRef name_sref(name);
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals(name_sref)) {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ (omit_empty_base_classes &&
+ ObjCDeclHasIVars(superclass_interface_decl, true)))
+ ++child_idx;
+
+ child_indexes.push_back(child_idx);
+ return child_indexes.size();
+ }
+ }
+
+ if (superclass_interface_decl) {
+ // The super class index is always zero for ObjC classes, so we
+ // push it onto the child indexes in case we find an ivar in our
+ // superclass...
+ child_indexes.push_back(0);
+
+ CompilerType superclass_clang_type =
+ GetType(getASTContext().getObjCInterfaceType(
+ superclass_interface_decl));
+ if (superclass_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes)) {
+ // We did find an ivar in a superclass so just return the
+ // results!
+ return child_indexes.size();
+ }
+
+ // We didn't find an ivar matching "name" in our superclass, pop
+ // the superclass zero index that we pushed on above.
+ child_indexes.pop_back();
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ CompilerType objc_object_clang_type = GetType(
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ return objc_object_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ } break;
+
+ case clang::Type::ConstantArray: {
+ // const clang::ConstantArrayType *array =
+ // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count =
+ // array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info =
+ // ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name),
+ // "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ } break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type =
+ // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+ // clang::QualType pointee_type =
+ // mem_ptr_type->getPointeeType();
+ //
+ // if (TypeSystemClang::IsAggregateType
+ // (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ clang::QualType pointee_type(reference_type->getPointeeType());
+ CompilerType pointee_clang_type = GetType(pointee_type);
+
+ if (pointee_clang_type.IsAggregateType()) {
+ return pointee_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ }
+ } break;
+
+ case clang::Type::Pointer: {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ if (pointee_clang_type.IsAggregateType()) {
+ return pointee_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ }
+ } break;
+
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+// Get the index of the child of "clang_type" whose name matches. This function
+// doesn't descend into the children, but only looks one level deep and name
+// matches can include base class names.
+
+uint32_t
+TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
+ const char *name,
+ bool omit_empty_base_classes) {
+ if (type && name && name[0]) {
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ if (cxx_record_decl) {
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ // Skip empty base classes
+ clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ if (omit_empty_base_classes &&
+ !TypeSystemClang::RecordHasFields(base_class_decl))
+ continue;
+
+ CompilerType base_class_clang_type = GetType(base_class->getType());
+ std::string base_class_type_name(
+ base_class_clang_type.GetTypeName().AsCString(""));
+ if (base_class_type_name == name)
+ return child_idx;
+ ++child_idx;
+ }
+ }
+
+ // Try and find a field that matches NAME
+ clang::RecordDecl::field_iterator field, field_end;
+ llvm::StringRef name_sref(name);
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ if (field->getName().equals(name_sref))
+ return child_idx;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ llvm::StringRef name_sref(name);
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals(name_sref)) {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ (omit_empty_base_classes &&
+ ObjCDeclHasIVars(superclass_interface_decl, true)))
+ ++child_idx;
+
+ return child_idx;
+ }
+ }
+
+ if (superclass_interface_decl) {
+ if (superclass_interface_decl->getName().equals(name_sref))
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ CompilerType pointee_clang_type = GetType(
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ return pointee_clang_type.GetIndexOfChildWithName(
+ name, omit_empty_base_classes);
+ } break;
+
+ case clang::Type::ConstantArray: {
+ // const clang::ConstantArrayType *array =
+ // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count =
+ // array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info =
+ // ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name),
+ // "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ } break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type =
+ // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+ // clang::QualType pointee_type =
+ // mem_ptr_type->getPointeeType();
+ //
+ // if (TypeSystemClang::IsAggregateType
+ // (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ CompilerType pointee_type = GetType(reference_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType()) {
+ return pointee_type.GetIndexOfChildWithName(name,
+ omit_empty_base_classes);
+ }
+ } break;
+
+ case clang::Type::Pointer: {
+ const clang::PointerType *pointer_type =
+ llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+ CompilerType pointee_type = GetType(pointer_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType()) {
+ return pointee_type.GetIndexOfChildWithName(name,
+ omit_empty_base_classes);
+ } else {
+ // if (parent_name)
+ // {
+ // child_name.assign(1, '*');
+ // child_name += parent_name;
+ // }
+ //
+ // // We have a pointer to an simple type
+ // if (idx == 0)
+ // {
+ // std::pair<uint64_t, unsigned> clang_type_info
+ // = ast->getTypeInfo(pointee_type);
+ // assert(clang_type_info.first % 8 == 0);
+ // child_byte_size = clang_type_info.first / 8;
+ // child_byte_offset = 0;
+ // return pointee_type.getAsOpaquePtr();
+ // }
+ }
+ } break;
+
+ default:
+ break;
+ }
+ }
+ return UINT32_MAX;
+}
+
+size_t
+TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return 0;
+
+ clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
+ cxx_record_decl);
+ if (template_decl)
+ return template_decl->getTemplateArgs().size();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+const clang::ClassTemplateSpecializationDecl *
+TypeSystemClang::GetAsTemplateSpecialization(
+ lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return nullptr;
+
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ if (! GetCompleteType(type))
+ return nullptr;
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (!cxx_record_decl)
+ return nullptr;
+ return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
+ cxx_record_decl);
+ }
+
+ default:
+ return nullptr;
+ }
+}
+
+lldb::TemplateArgumentKind
+TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
+ size_t arg_idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
+ return eTemplateArgumentKindNull;
+
+ switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
+ case clang::TemplateArgument::Null:
+ return eTemplateArgumentKindNull;
+
+ case clang::TemplateArgument::NullPtr:
+ return eTemplateArgumentKindNullPtr;
+
+ case clang::TemplateArgument::Type:
+ return eTemplateArgumentKindType;
+
+ case clang::TemplateArgument::Declaration:
+ return eTemplateArgumentKindDeclaration;
+
+ case clang::TemplateArgument::Integral:
+ return eTemplateArgumentKindIntegral;
+
+ case clang::TemplateArgument::Template:
+ return eTemplateArgumentKindTemplate;
+
+ case clang::TemplateArgument::TemplateExpansion:
+ return eTemplateArgumentKindTemplateExpansion;
+
+ case clang::TemplateArgument::Expression:
+ return eTemplateArgumentKindExpression;
+
+ case clang::TemplateArgument::Pack:
+ return eTemplateArgumentKindPack;
+ }
+ llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind");
+}
+
+CompilerType
+TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (!template_decl || idx >= template_decl->getTemplateArgs().size())
+ return CompilerType();
+
+ const clang::TemplateArgument &template_arg =
+ template_decl->getTemplateArgs()[idx];
+ if (template_arg.getKind() != clang::TemplateArgument::Type)
+ return CompilerType();
+
+ return GetType(template_arg.getAsType());
+}
+
+Optional<CompilerType::IntegralTemplateArgument>
+TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ const clang::ClassTemplateSpecializationDecl *template_decl =
+ GetAsTemplateSpecialization(type);
+ if (! template_decl || idx >= template_decl->getTemplateArgs().size())
+ return llvm::None;
+
+ const clang::TemplateArgument &template_arg =
+ template_decl->getTemplateArgs()[idx];
+ if (template_arg.getKind() != clang::TemplateArgument::Integral)
+ return llvm::None;
+
+ return {
+ {template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}};
+}
+
+CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
+ if (type)
+ return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
+ return CompilerType();
+}
+
+clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) {
+ const clang::EnumType *enutype =
+ llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type));
+ if (enutype)
+ return enutype->getDecl();
+ return nullptr;
+}
+
+clang::RecordDecl *TypeSystemClang::GetAsRecordDecl(const CompilerType &type) {
+ const clang::RecordType *record_type =
+ llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type));
+ if (record_type)
+ return record_type->getDecl();
+ return nullptr;
+}
+
+clang::TagDecl *TypeSystemClang::GetAsTagDecl(const CompilerType &type) {
+ return ClangUtil::GetAsTagDecl(type);
+}
+
+clang::TypedefNameDecl *
+TypeSystemClang::GetAsTypedefDecl(const CompilerType &type) {
+ const clang::TypedefType *typedef_type =
+ llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type));
+ if (typedef_type)
+ return typedef_type->getDecl();
+ return nullptr;
+}
+
+clang::CXXRecordDecl *
+TypeSystemClang::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) {
+ return GetCanonicalQualType(type)->getAsCXXRecordDecl();
+}
+
+clang::ObjCInterfaceDecl *
+TypeSystemClang::GetAsObjCInterfaceDecl(const CompilerType &type) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(
+ ClangUtil::GetCanonicalQualType(type));
+ if (objc_class_type)
+ return objc_class_type->getInterface();
+ return nullptr;
+}
+
+clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
+ const CompilerType &type, llvm::StringRef name,
+ const CompilerType &field_clang_type, AccessType access,
+ uint32_t bitfield_bit_size) {
+ if (!type.IsValid() || !field_clang_type.IsValid())
+ return nullptr;
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return nullptr;
+ clang::ASTContext &clang_ast = ast->getASTContext();
+ clang::IdentifierInfo *ident = nullptr;
+ if (!name.empty())
+ ident = &clang_ast.Idents.get(name);
+
+ clang::FieldDecl *field = nullptr;
+
+ clang::Expr *bit_width = nullptr;
+ if (bitfield_bit_size != 0) {
+ llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy),
+ bitfield_bit_size);
+ bit_width = new (clang_ast)
+ clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint,
+ clang_ast.IntTy, clang::SourceLocation());
+ }
+
+ clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
+ if (record_decl) {
+ field = clang::FieldDecl::CreateDeserialized(clang_ast, 0);
+ field->setDeclContext(record_decl);
+ field->setDeclName(ident);
+ field->setType(ClangUtil::GetQualType(field_clang_type));
+ if (bit_width)
+ field->setBitWidth(bit_width);
+ SetMemberOwningModule(field, record_decl);
+
+ if (name.empty()) {
+ // Determine whether this field corresponds to an anonymous struct or
+ // union.
+ if (const clang::TagType *TagT =
+ field->getType()->getAs<clang::TagType>()) {
+ if (clang::RecordDecl *Rec =
+ llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
+ if (!Rec->getDeclName()) {
+ Rec->setAnonymousStructOrUnion(true);
+ field->setImplicit();
+ }
+ }
+ }
+
+ if (field) {
+ field->setAccess(
+ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
+
+ record_decl->addDecl(field);
+
+ VerifyDecl(field);
+ }
+ } else {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ ast->GetAsObjCInterfaceDecl(type);
+
+ if (class_interface_decl) {
+ const bool is_synthesized = false;
+
+ field_clang_type.GetCompleteType();
+
+ auto *ivar = clang::ObjCIvarDecl::CreateDeserialized(clang_ast, 0);
+ ivar->setDeclContext(class_interface_decl);
+ ivar->setDeclName(ident);
+ ivar->setType(ClangUtil::GetQualType(field_clang_type));
+ ivar->setAccessControl(ConvertAccessTypeToObjCIvarAccessControl(access));
+ if (bit_width)
+ ivar->setBitWidth(bit_width);
+ ivar->setSynthesize(is_synthesized);
+ field = ivar;
+ SetMemberOwningModule(field, class_interface_decl);
+
+ if (field) {
+ class_interface_decl->addDecl(field);
+
+ VerifyDecl(field);
+ }
+ }
+ }
+ return field;
+}
+
+void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
+ if (!type)
+ return;
+
+ TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return;
+
+ clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
+
+ if (!record_decl)
+ return;
+
+ typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector;
+
+ IndirectFieldVector indirect_fields;
+ clang::RecordDecl::field_iterator field_pos;
+ clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+ clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end_pos;
+ last_field_pos = field_pos++) {
+ if (field_pos->isAnonymousStructOrUnion()) {
+ clang::QualType field_qual_type = field_pos->getType();
+
+ const clang::RecordType *field_record_type =
+ field_qual_type->getAs<clang::RecordType>();
+
+ if (!field_record_type)
+ continue;
+
+ clang::RecordDecl *field_record_decl = field_record_type->getDecl();
+
+ if (!field_record_decl)
+ continue;
+
+ for (clang::RecordDecl::decl_iterator
+ di = field_record_decl->decls_begin(),
+ de = field_record_decl->decls_end();
+ di != de; ++di) {
+ if (clang::FieldDecl *nested_field_decl =
+ llvm::dyn_cast<clang::FieldDecl>(*di)) {
+ clang::NamedDecl **chain =
+ new (ast->getASTContext()) clang::NamedDecl *[2];
+ chain[0] = *field_pos;
+ chain[1] = nested_field_decl;
+ clang::IndirectFieldDecl *indirect_field =
+ clang::IndirectFieldDecl::Create(
+ ast->getASTContext(), record_decl, clang::SourceLocation(),
+ nested_field_decl->getIdentifier(),
+ nested_field_decl->getType(), {chain, 2});
+ SetMemberOwningModule(indirect_field, record_decl);
+
+ indirect_field->setImplicit();
+
+ indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
+ field_pos->getAccess(), nested_field_decl->getAccess()));
+
+ indirect_fields.push_back(indirect_field);
+ } else if (clang::IndirectFieldDecl *nested_indirect_field_decl =
+ llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) {
+ size_t nested_chain_size =
+ nested_indirect_field_decl->getChainingSize();
+ clang::NamedDecl **chain = new (ast->getASTContext())
+ clang::NamedDecl *[nested_chain_size + 1];
+ chain[0] = *field_pos;
+
+ int chain_index = 1;
+ for (clang::IndirectFieldDecl::chain_iterator
+ nci = nested_indirect_field_decl->chain_begin(),
+ nce = nested_indirect_field_decl->chain_end();
+ nci < nce; ++nci) {
+ chain[chain_index] = *nci;
+ chain_index++;
+ }
+
+ clang::IndirectFieldDecl *indirect_field =
+ clang::IndirectFieldDecl::Create(
+ ast->getASTContext(), record_decl, clang::SourceLocation(),
+ nested_indirect_field_decl->getIdentifier(),
+ nested_indirect_field_decl->getType(),
+ {chain, nested_chain_size + 1});
+ SetMemberOwningModule(indirect_field, record_decl);
+
+ indirect_field->setImplicit();
+
+ indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
+ field_pos->getAccess(), nested_indirect_field_decl->getAccess()));
+
+ indirect_fields.push_back(indirect_field);
+ }
+ }
+ }
+ }
+
+ // Check the last field to see if it has an incomplete array type as its last
+ // member and if it does, the tell the record decl about it
+ if (last_field_pos != field_end_pos) {
+ if (last_field_pos->getType()->isIncompleteArrayType())
+ record_decl->hasFlexibleArrayMember();
+ }
+
+ for (IndirectFieldVector::iterator ifi = indirect_fields.begin(),
+ ife = indirect_fields.end();
+ ifi < ife; ++ifi) {
+ record_decl->addDecl(*ifi);
+ }
+}
+
+void TypeSystemClang::SetIsPacked(const CompilerType &type) {
+ if (type) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (ast) {
+ clang::RecordDecl *record_decl = GetAsRecordDecl(type);
+
+ if (!record_decl)
+ return;
+
+ record_decl->addAttr(
+ clang::PackedAttr::CreateImplicit(ast->getASTContext()));
+ }
+ }
+}
+
+clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
+ const CompilerType &type, llvm::StringRef name,
+ const CompilerType &var_type, AccessType access) {
+ if (!type.IsValid() || !var_type.IsValid())
+ return nullptr;
+
+ TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return nullptr;
+
+ clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type);
+ if (!record_decl)
+ return nullptr;
+
+ clang::VarDecl *var_decl = nullptr;
+ clang::IdentifierInfo *ident = nullptr;
+ if (!name.empty())
+ ident = &ast->getASTContext().Idents.get(name);
+
+ var_decl = clang::VarDecl::CreateDeserialized(ast->getASTContext(), 0);
+ var_decl->setDeclContext(record_decl);
+ var_decl->setDeclName(ident);
+ var_decl->setType(ClangUtil::GetQualType(var_type));
+ var_decl->setStorageClass(clang::SC_Static);
+ SetMemberOwningModule(var_decl, record_decl);
+ if (!var_decl)
+ return nullptr;
+
+ var_decl->setAccess(
+ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
+ record_decl->addDecl(var_decl);
+
+ VerifyDecl(var_decl);
+
+ return var_decl;
+}
+
+void TypeSystemClang::SetIntegerInitializerForVariable(
+ VarDecl *var, const llvm::APInt &init_value) {
+ assert(!var->hasInit() && "variable already initialized");
+
+ clang::ASTContext &ast = var->getASTContext();
+ QualType qt = var->getType();
+ assert(qt->isIntegralOrEnumerationType() &&
+ "only integer or enum types supported");
+ // If the variable is an enum type, take the underlying integer type as
+ // the type of the integer literal.
+ if (const EnumType *enum_type = llvm::dyn_cast<EnumType>(qt.getTypePtr())) {
+ const EnumDecl *enum_decl = enum_type->getDecl();
+ qt = enum_decl->getIntegerType();
+ }
+ var->setInit(IntegerLiteral::Create(ast, init_value, qt.getUnqualifiedType(),
+ SourceLocation()));
+}
+
+void TypeSystemClang::SetFloatingInitializerForVariable(
+ clang::VarDecl *var, const llvm::APFloat &init_value) {
+ assert(!var->hasInit() && "variable already initialized");
+
+ clang::ASTContext &ast = var->getASTContext();
+ QualType qt = var->getType();
+ assert(qt->isFloatingType() && "only floating point types supported");
+ var->setInit(FloatingLiteral::Create(
+ ast, init_value, true, qt.getUnqualifiedType(), SourceLocation()));
+}
+
+clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
+ lldb::opaque_compiler_type_t type, llvm::StringRef name,
+ const char *mangled_name, const CompilerType &method_clang_type,
+ lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
+ bool is_explicit, bool is_attr_used, bool is_artificial) {
+ if (!type || !method_clang_type.IsValid() || name.empty())
+ return nullptr;
+
+ clang::QualType record_qual_type(GetCanonicalQualType(type));
+
+ clang::CXXRecordDecl *cxx_record_decl =
+ record_qual_type->getAsCXXRecordDecl();
+
+ if (cxx_record_decl == nullptr)
+ return nullptr;
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
+ clang::CXXMethodDecl *cxx_method_decl = nullptr;
+
+ clang::DeclarationName decl_name(&getASTContext().Idents.get(name));
+
+ const clang::FunctionType *function_type =
+ llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
+
+ if (function_type == nullptr)
+ return nullptr;
+
+ const clang::FunctionProtoType *method_function_prototype(
+ llvm::dyn_cast<clang::FunctionProtoType>(function_type));
+
+ if (!method_function_prototype)
+ return nullptr;
+
+ unsigned int num_params = method_function_prototype->getNumParams();
+
+ clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
+ clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
+
+ if (is_artificial)
+ return nullptr; // skip everything artificial
+
+ const clang::ExplicitSpecifier explicit_spec(
+ nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue
+ : clang::ExplicitSpecKind::ResolvedFalse);
+
+ if (name.startswith("~")) {
+ cxx_dtor_decl =
+ clang::CXXDestructorDecl::CreateDeserialized(getASTContext(), 0);
+ cxx_dtor_decl->setDeclContext(cxx_record_decl);
+ cxx_dtor_decl->setDeclName(
+ getASTContext().DeclarationNames.getCXXDestructorName(
+ getASTContext().getCanonicalType(record_qual_type)));
+ cxx_dtor_decl->setType(method_qual_type);
+ cxx_dtor_decl->setImplicit(is_artificial);
+ cxx_dtor_decl->setInlineSpecified(is_inline);
+ cxx_dtor_decl->setConstexprKind(CSK_unspecified);
+ cxx_method_decl = cxx_dtor_decl;
+ } else if (decl_name == cxx_record_decl->getDeclName()) {
+ cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized(
+ getASTContext(), 0, 0);
+ cxx_ctor_decl->setDeclContext(cxx_record_decl);
+ cxx_ctor_decl->setDeclName(
+ getASTContext().DeclarationNames.getCXXConstructorName(
+ getASTContext().getCanonicalType(record_qual_type)));
+ cxx_ctor_decl->setType(method_qual_type);
+ cxx_ctor_decl->setImplicit(is_artificial);
+ cxx_ctor_decl->setInlineSpecified(is_inline);
+ cxx_ctor_decl->setConstexprKind(CSK_unspecified);
+ cxx_ctor_decl->setNumCtorInitializers(0);
+ cxx_ctor_decl->setExplicitSpecifier(explicit_spec);
+ cxx_method_decl = cxx_ctor_decl;
+ } else {
+ clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+
+ if (IsOperator(name, op_kind)) {
+ if (op_kind != clang::NUM_OVERLOADED_OPERATORS) {
+ // Check the number of operator parameters. Sometimes we have seen bad
+ // DWARF that doesn't correctly describe operators and if we try to
+ // create a method and add it to the class, clang will assert and
+ // crash, so we need to make sure things are acceptable.
+ const bool is_method = true;
+ if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
+ is_method, op_kind, num_params))
+ return nullptr;
+ cxx_method_decl =
+ clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0);
+ cxx_method_decl->setDeclContext(cxx_record_decl);
+ cxx_method_decl->setDeclName(
+ getASTContext().DeclarationNames.getCXXOperatorName(op_kind));
+ cxx_method_decl->setType(method_qual_type);
+ cxx_method_decl->setStorageClass(SC);
+ cxx_method_decl->setInlineSpecified(is_inline);
+ cxx_method_decl->setConstexprKind(CSK_unspecified);
+ } else if (num_params == 0) {
+ // Conversion operators don't take params...
+ auto *cxx_conversion_decl =
+ clang::CXXConversionDecl::CreateDeserialized(getASTContext(), 0);
+ cxx_conversion_decl->setDeclContext(cxx_record_decl);
+ cxx_conversion_decl->setDeclName(
+ getASTContext().DeclarationNames.getCXXConversionFunctionName(
+ getASTContext().getCanonicalType(
+ function_type->getReturnType())));
+ cxx_conversion_decl->setType(method_qual_type);
+ cxx_conversion_decl->setInlineSpecified(is_inline);
+ cxx_conversion_decl->setExplicitSpecifier(explicit_spec);
+ cxx_conversion_decl->setConstexprKind(CSK_unspecified);
+ cxx_method_decl = cxx_conversion_decl;
+ }
+ }
+
+ if (cxx_method_decl == nullptr) {
+ cxx_method_decl =
+ clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0);
+ cxx_method_decl->setDeclContext(cxx_record_decl);
+ cxx_method_decl->setDeclName(decl_name);
+ cxx_method_decl->setType(method_qual_type);
+ cxx_method_decl->setInlineSpecified(is_inline);
+ cxx_method_decl->setStorageClass(SC);
+ cxx_method_decl->setConstexprKind(CSK_unspecified);
+ }
+ }
+ SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
+
+ clang::AccessSpecifier access_specifier =
+ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
+
+ cxx_method_decl->setAccess(access_specifier);
+ cxx_method_decl->setVirtualAsWritten(is_virtual);
+
+ if (is_attr_used)
+ cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext()));
+
+ if (mangled_name != nullptr) {
+ cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
+ getASTContext(), mangled_name, /*literal=*/false));
+ }
+
+ // Populate the method decl with parameter decls
+
+ llvm::SmallVector<clang::ParmVarDecl *, 12> params;
+
+ for (unsigned param_index = 0; param_index < num_params; ++param_index) {
+ params.push_back(clang::ParmVarDecl::Create(
+ getASTContext(), cxx_method_decl, clang::SourceLocation(),
+ clang::SourceLocation(),
+ nullptr, // anonymous
+ method_function_prototype->getParamType(param_index), nullptr,
+ clang::SC_None, nullptr));
+ }
+
+ cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
+
+ cxx_record_decl->addDecl(cxx_method_decl);
+
+ // Sometimes the debug info will mention a constructor (default/copy/move),
+ // destructor, or assignment operator (copy/move) but there won't be any
+ // version of this in the code. So we check if the function was artificially
+ // generated and if it is trivial and this lets the compiler/backend know
+ // that it can inline the IR for these when it needs to and we can avoid a
+ // "missing function" error when running expressions.
+
+ if (is_artificial) {
+ if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() &&
+ cxx_record_decl->hasTrivialDefaultConstructor()) ||
+ (cxx_ctor_decl->isCopyConstructor() &&
+ cxx_record_decl->hasTrivialCopyConstructor()) ||
+ (cxx_ctor_decl->isMoveConstructor() &&
+ cxx_record_decl->hasTrivialMoveConstructor()))) {
+ cxx_ctor_decl->setDefaulted();
+ cxx_ctor_decl->setTrivial(true);
+ } else if (cxx_dtor_decl) {
+ if (cxx_record_decl->hasTrivialDestructor()) {
+ cxx_dtor_decl->setDefaulted();
+ cxx_dtor_decl->setTrivial(true);
+ }
+ } else if ((cxx_method_decl->isCopyAssignmentOperator() &&
+ cxx_record_decl->hasTrivialCopyAssignment()) ||
+ (cxx_method_decl->isMoveAssignmentOperator() &&
+ cxx_record_decl->hasTrivialMoveAssignment())) {
+ cxx_method_decl->setDefaulted();
+ cxx_method_decl->setTrivial(true);
+ }
+ }
+
+ VerifyDecl(cxx_method_decl);
+
+ return cxx_method_decl;
+}
+
+void TypeSystemClang::AddMethodOverridesForCXXRecordType(
+ lldb::opaque_compiler_type_t type) {
+ if (auto *record = GetAsCXXRecordDecl(type))
+ for (auto *method : record->methods())
+ addOverridesForMethod(method);
+}
+
+#pragma mark C++ Base Classes
+
+std::unique_ptr<clang::CXXBaseSpecifier>
+TypeSystemClang::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
+ AccessType access, bool is_virtual,
+ bool base_of_class) {
+ if (!type)
+ return nullptr;
+
+ return std::make_unique<clang::CXXBaseSpecifier>(
+ clang::SourceRange(), is_virtual, base_of_class,
+ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access),
+ getASTContext().getTrivialTypeSourceInfo(GetQualType(type)),
+ clang::SourceLocation());
+}
+
+bool TypeSystemClang::TransferBaseClasses(
+ lldb::opaque_compiler_type_t type,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) {
+ if (!type)
+ return false;
+ clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type);
+ if (!cxx_record_decl)
+ return false;
+ std::vector<clang::CXXBaseSpecifier *> raw_bases;
+ raw_bases.reserve(bases.size());
+
+ // Clang will make a copy of them, so it's ok that we pass pointers that we're
+ // about to destroy.
+ for (auto &b : bases)
+ raw_bases.push_back(b.get());
+ cxx_record_decl->setBases(raw_bases.data(), raw_bases.size());
+ return true;
+}
+
+bool TypeSystemClang::SetObjCSuperClass(
+ const CompilerType &type, const CompilerType &superclass_clang_type) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return false;
+ clang::ASTContext &clang_ast = ast->getASTContext();
+
+ if (type && superclass_clang_type.IsValid() &&
+ superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ GetAsObjCInterfaceDecl(type);
+ clang::ObjCInterfaceDecl *super_interface_decl =
+ GetAsObjCInterfaceDecl(superclass_clang_type);
+ if (class_interface_decl && super_interface_decl) {
+ class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo(
+ clang_ast.getObjCInterfaceType(super_interface_decl)));
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::AddObjCClassProperty(
+ const CompilerType &type, const char *property_name,
+ const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name, const char *property_getter_name,
+ uint32_t property_attributes, ClangASTMetadata *metadata) {
+ if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
+ property_name[0] == '\0')
+ return false;
+ TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return false;
+ clang::ASTContext &clang_ast = ast->getASTContext();
+
+ clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
+ if (!class_interface_decl)
+ return false;
+
+ CompilerType property_clang_type_to_access;
+
+ if (property_clang_type.IsValid())
+ property_clang_type_to_access = property_clang_type;
+ else if (ivar_decl)
+ property_clang_type_to_access = ast->GetType(ivar_decl->getType());
+
+ if (!class_interface_decl || !property_clang_type_to_access.IsValid())
+ return false;
+
+ clang::TypeSourceInfo *prop_type_source;
+ if (ivar_decl)
+ prop_type_source = clang_ast.getTrivialTypeSourceInfo(ivar_decl->getType());
+ else
+ prop_type_source = clang_ast.getTrivialTypeSourceInfo(
+ ClangUtil::GetQualType(property_clang_type));
+
+ clang::ObjCPropertyDecl *property_decl =
+ clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, 0);
+ property_decl->setDeclContext(class_interface_decl);
+ property_decl->setDeclName(&clang_ast.Idents.get(property_name));
+ property_decl->setType(ivar_decl
+ ? ivar_decl->getType()
+ : ClangUtil::GetQualType(property_clang_type),
+ prop_type_source);
+ SetMemberOwningModule(property_decl, class_interface_decl);
+
+ if (!property_decl)
+ return false;
+
+ if (metadata)
+ ast->SetMetadata(property_decl, *metadata);
+
+ class_interface_decl->addDecl(property_decl);
+
+ clang::Selector setter_sel, getter_sel;
+
+ if (property_setter_name) {
+ std::string property_setter_no_colon(property_setter_name,
+ strlen(property_setter_name) - 1);
+ clang::IdentifierInfo *setter_ident =
+ &clang_ast.Idents.get(property_setter_no_colon);
+ setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident);
+ } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) {
+ std::string setter_sel_string("set");
+ setter_sel_string.push_back(::toupper(property_name[0]));
+ setter_sel_string.append(&property_name[1]);
+ clang::IdentifierInfo *setter_ident =
+ &clang_ast.Idents.get(setter_sel_string);
+ setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident);
+ }
+ property_decl->setSetterName(setter_sel);
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
+
+ if (property_getter_name != nullptr) {
+ clang::IdentifierInfo *getter_ident =
+ &clang_ast.Idents.get(property_getter_name);
+ getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident);
+ } else {
+ clang::IdentifierInfo *getter_ident = &clang_ast.Idents.get(property_name);
+ getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident);
+ }
+ property_decl->setGetterName(getter_sel);
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
+
+ if (ivar_decl)
+ property_decl->setPropertyIvarDecl(ivar_decl);
+
+ if (property_attributes & DW_APPLE_PROPERTY_readonly)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
+ if (property_attributes & DW_APPLE_PROPERTY_readwrite)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
+ if (property_attributes & DW_APPLE_PROPERTY_assign)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
+ if (property_attributes & DW_APPLE_PROPERTY_retain)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
+ if (property_attributes & DW_APPLE_PROPERTY_copy)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
+ if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
+ if (property_attributes & ObjCPropertyAttribute::kind_nullability)
+ property_decl->setPropertyAttributes(
+ ObjCPropertyAttribute::kind_nullability);
+ if (property_attributes & ObjCPropertyAttribute::kind_null_resettable)
+ property_decl->setPropertyAttributes(
+ ObjCPropertyAttribute::kind_null_resettable);
+ if (property_attributes & ObjCPropertyAttribute::kind_class)
+ property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class);
+
+ const bool isInstance =
+ (property_attributes & ObjCPropertyAttribute::kind_class) == 0;
+
+ clang::ObjCMethodDecl *getter = nullptr;
+ if (!getter_sel.isNull())
+ getter = isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel)
+ : class_interface_decl->lookupClassMethod(getter_sel);
+ if (!getter_sel.isNull() && !getter) {
+ const bool isVariadic = false;
+ const bool isPropertyAccessor = true;
+ const bool isSynthesizedAccessorStub = false;
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const clang::ObjCMethodDecl::ImplementationControl impControl =
+ clang::ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+
+ getter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0);
+ getter->setDeclName(getter_sel);
+ getter->setReturnType(ClangUtil::GetQualType(property_clang_type_to_access));
+ getter->setDeclContext(class_interface_decl);
+ getter->setInstanceMethod(isInstance);
+ getter->setVariadic(isVariadic);
+ getter->setPropertyAccessor(isPropertyAccessor);
+ getter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
+ getter->setImplicit(isImplicitlyDeclared);
+ getter->setDefined(isDefined);
+ getter->setDeclImplementation(impControl);
+ getter->setRelatedResultType(HasRelatedResultType);
+ SetMemberOwningModule(getter, class_interface_decl);
+
+ if (getter) {
+ if (metadata)
+ ast->SetMetadata(getter, *metadata);
+
+ getter->setMethodParams(clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(),
+ llvm::ArrayRef<clang::SourceLocation>());
+ class_interface_decl->addDecl(getter);
+ }
+ }
+ if (getter) {
+ getter->setPropertyAccessor(true);
+ property_decl->setGetterMethodDecl(getter);
+ }
+
+ clang::ObjCMethodDecl *setter = nullptr;
+ setter = isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel)
+ : class_interface_decl->lookupClassMethod(setter_sel);
+ if (!setter_sel.isNull() && !setter) {
+ clang::QualType result_type = clang_ast.VoidTy;
+ const bool isVariadic = false;
+ const bool isPropertyAccessor = true;
+ const bool isSynthesizedAccessorStub = false;
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const clang::ObjCMethodDecl::ImplementationControl impControl =
+ clang::ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+
+ setter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0);
+ setter->setDeclName(setter_sel);
+ setter->setReturnType(result_type);
+ setter->setDeclContext(class_interface_decl);
+ setter->setInstanceMethod(isInstance);
+ setter->setVariadic(isVariadic);
+ setter->setPropertyAccessor(isPropertyAccessor);
+ setter->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
+ setter->setImplicit(isImplicitlyDeclared);
+ setter->setDefined(isDefined);
+ setter->setDeclImplementation(impControl);
+ setter->setRelatedResultType(HasRelatedResultType);
+ SetMemberOwningModule(setter, class_interface_decl);
+
+ if (setter) {
+ if (metadata)
+ ast->SetMetadata(setter, *metadata);
+
+ llvm::SmallVector<clang::ParmVarDecl *, 1> params;
+ params.push_back(clang::ParmVarDecl::Create(
+ clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(),
+ nullptr, // anonymous
+ ClangUtil::GetQualType(property_clang_type_to_access), nullptr,
+ clang::SC_Auto, nullptr));
+
+ setter->setMethodParams(clang_ast,
+ llvm::ArrayRef<clang::ParmVarDecl *>(params),
+ llvm::ArrayRef<clang::SourceLocation>());
+
+ class_interface_decl->addDecl(setter);
+ }
+ }
+ if (setter) {
+ setter->setPropertyAccessor(true);
+ property_decl->setSetterMethodDecl(setter);
+ }
+
+ return true;
+}
+
+bool TypeSystemClang::IsObjCClassTypeAndHasIVars(const CompilerType &type,
+ bool check_superclass) {
+ clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
+ if (class_interface_decl)
+ return ObjCDeclHasIVars(class_interface_decl, check_superclass);
+ return false;
+}
+
+clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
+ const CompilerType &type,
+ const char *name, // the full symbol name as seen in the symbol table
+ // (lldb::opaque_compiler_type_t type, "-[NString
+ // stringWithCString:]")
+ const CompilerType &method_clang_type, lldb::AccessType access,
+ bool is_artificial, bool is_variadic, bool is_objc_direct_call) {
+ if (!type || !method_clang_type.IsValid())
+ return nullptr;
+
+ clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type);
+
+ if (class_interface_decl == nullptr)
+ return nullptr;
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (lldb_ast == nullptr)
+ return nullptr;
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ const char *selector_start = ::strchr(name, ' ');
+ if (selector_start == nullptr)
+ return nullptr;
+
+ selector_start++;
+ llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
+
+ size_t len = 0;
+ const char *start;
+
+ unsigned num_selectors_with_args = 0;
+ for (start = selector_start; start && *start != '\0' && *start != ']';
+ start += len) {
+ len = ::strcspn(start, ":]");
+ bool has_arg = (start[len] == ':');
+ if (has_arg)
+ ++num_selectors_with_args;
+ selector_idents.push_back(&ast.Idents.get(llvm::StringRef(start, len)));
+ if (has_arg)
+ len += 1;
+ }
+
+ if (selector_idents.size() == 0)
+ return nullptr;
+
+ clang::Selector method_selector = ast.Selectors.getSelector(
+ num_selectors_with_args ? selector_idents.size() : 0,
+ selector_idents.data());
+
+ clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type));
+
+ // Populate the method decl with parameter decls
+ const clang::Type *method_type(method_qual_type.getTypePtr());
+
+ if (method_type == nullptr)
+ return nullptr;
+
+ const clang::FunctionProtoType *method_function_prototype(
+ llvm::dyn_cast<clang::FunctionProtoType>(method_type));
+
+ if (!method_function_prototype)
+ return nullptr;
+
+ const bool isInstance = (name[0] == '-');
+ const bool isVariadic = is_variadic;
+ const bool isPropertyAccessor = false;
+ const bool isSynthesizedAccessorStub = false;
+ /// Force this to true because we don't have source locations.
+ const bool isImplicitlyDeclared = true;
+ const bool isDefined = false;
+ const clang::ObjCMethodDecl::ImplementationControl impControl =
+ clang::ObjCMethodDecl::None;
+ const bool HasRelatedResultType = false;
+
+ const unsigned num_args = method_function_prototype->getNumParams();
+
+ if (num_args != num_selectors_with_args)
+ return nullptr; // some debug information is corrupt. We are not going to
+ // deal with it.
+
+ auto *objc_method_decl = clang::ObjCMethodDecl::CreateDeserialized(ast, 0);
+ objc_method_decl->setDeclName(method_selector);
+ objc_method_decl->setReturnType(method_function_prototype->getReturnType());
+ objc_method_decl->setDeclContext(
+ lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)));
+ objc_method_decl->setInstanceMethod(isInstance);
+ objc_method_decl->setVariadic(isVariadic);
+ objc_method_decl->setPropertyAccessor(isPropertyAccessor);
+ objc_method_decl->setSynthesizedAccessorStub(isSynthesizedAccessorStub);
+ objc_method_decl->setImplicit(isImplicitlyDeclared);
+ objc_method_decl->setDefined(isDefined);
+ objc_method_decl->setDeclImplementation(impControl);
+ objc_method_decl->setRelatedResultType(HasRelatedResultType);
+ SetMemberOwningModule(objc_method_decl, class_interface_decl);
+
+ if (objc_method_decl == nullptr)
+ return nullptr;
+
+ if (num_args > 0) {
+ llvm::SmallVector<clang::ParmVarDecl *, 12> params;
+
+ for (unsigned param_index = 0; param_index < num_args; ++param_index) {
+ params.push_back(clang::ParmVarDecl::Create(
+ ast, objc_method_decl, clang::SourceLocation(),
+ clang::SourceLocation(),
+ nullptr, // anonymous
+ method_function_prototype->getParamType(param_index), nullptr,
+ clang::SC_Auto, nullptr));
+ }
+
+ objc_method_decl->setMethodParams(
+ ast, llvm::ArrayRef<clang::ParmVarDecl *>(params),
+ llvm::ArrayRef<clang::SourceLocation>());
+ }
+
+ if (is_objc_direct_call) {
+ // Add a the objc_direct attribute to the declaration we generate that
+ // we generate a direct method call for this ObjCMethodDecl.
+ objc_method_decl->addAttr(
+ clang::ObjCDirectAttr::CreateImplicit(ast, SourceLocation()));
+ // Usually Sema is creating implicit parameters (e.g., self) when it
+ // parses the method. We don't have a parsing Sema when we build our own
+ // AST here so we manually need to create these implicit parameters to
+ // make the direct call code generation happy.
+ objc_method_decl->createImplicitParams(ast, class_interface_decl);
+ }
+
+ class_interface_decl->addDecl(objc_method_decl);
+
+ VerifyDecl(objc_method_decl);
+
+ return objc_method_decl;
+}
+
+bool TypeSystemClang::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
+ bool has_extern) {
+ if (!type)
+ return false;
+
+ clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ cxx_record_decl->setHasExternalLexicalStorage(has_extern);
+ cxx_record_decl->setHasExternalVisibleStorage(has_extern);
+ return true;
+ }
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ enum_decl->setHasExternalLexicalStorage(has_extern);
+ enum_decl->setHasExternalVisibleStorage(has_extern);
+ return true;
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ class_interface_decl->setHasExternalLexicalStorage(has_extern);
+ class_interface_decl->setHasExternalVisibleStorage(has_extern);
+ return true;
+ }
+ }
+ } break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+#pragma mark TagDecl
+
+bool TypeSystemClang::StartTagDeclarationDefinition(const CompilerType &type) {
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
+ if (!qual_type.isNull()) {
+ const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl) {
+ tag_decl->startDefinition();
+ return true;
+ }
+ }
+
+ const clang::ObjCObjectType *object_type =
+ qual_type->getAs<clang::ObjCObjectType>();
+ if (object_type) {
+ clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+ if (interface_decl) {
+ interface_decl->startDefinition();
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::CompleteTagDeclarationDefinition(
+ const CompilerType &type) {
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
+ if (qual_type.isNull())
+ return false;
+
+ // Make sure we use the same methodology as
+ // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end
+ // the definition.
+ const clang::TagType *tag_type = qual_type->getAs<clang::TagType>();
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+
+ if (auto *cxx_record_decl = llvm::dyn_cast<CXXRecordDecl>(tag_decl)) {
+ // If we have a move constructor declared but no copy constructor we
+ // need to explicitly mark it as deleted. Usually Sema would do this for
+ // us in Sema::DeclareImplicitCopyConstructor but we don't have a Sema
+ // when building an AST from debug information.
+ // See also:
+ // C++11 [class.copy]p7, p18:
+ // If the class definition declares a move constructor or move assignment
+ // operator, an implicitly declared copy constructor or copy assignment
+ // operator is defined as deleted.
+ if (cxx_record_decl->hasUserDeclaredMoveConstructor() ||
+ cxx_record_decl->hasUserDeclaredMoveAssignment()) {
+ if (cxx_record_decl->needsImplicitCopyConstructor())
+ cxx_record_decl->setImplicitCopyConstructorIsDeleted();
+ if (cxx_record_decl->needsImplicitCopyAssignment())
+ cxx_record_decl->setImplicitCopyAssignmentIsDeleted();
+ }
+
+ if (!cxx_record_decl->isCompleteDefinition())
+ cxx_record_decl->completeDefinition();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+ cxx_record_decl->setHasExternalLexicalStorage(false);
+ cxx_record_decl->setHasExternalVisibleStorage(false);
+ return true;
+ }
+ }
+
+ const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>();
+
+ if (!enutype)
+ return false;
+ clang::EnumDecl *enum_decl = enutype->getDecl();
+
+ if (enum_decl->isCompleteDefinition())
+ return true;
+
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (lldb_ast == nullptr)
+ return false;
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ /// TODO This really needs to be fixed.
+
+ QualType integer_type(enum_decl->getIntegerType());
+ if (!integer_type.isNull()) {
+ unsigned NumPositiveBits = 1;
+ unsigned NumNegativeBits = 0;
+
+ clang::QualType promotion_qual_type;
+ // If the enum integer type is less than an integer in bit width,
+ // then we must promote it to an integer size.
+ if (ast.getTypeSize(enum_decl->getIntegerType()) <
+ ast.getTypeSize(ast.IntTy)) {
+ if (enum_decl->getIntegerType()->isSignedIntegerType())
+ promotion_qual_type = ast.IntTy;
+ else
+ promotion_qual_type = ast.UnsignedIntTy;
+ } else
+ promotion_qual_type = enum_decl->getIntegerType();
+
+ enum_decl->completeDefinition(enum_decl->getIntegerType(),
+ promotion_qual_type, NumPositiveBits,
+ NumNegativeBits);
+ }
+ return true;
+}
+
+clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ const llvm::APSInt &value) {
+
+ if (!enum_type || ConstString(name).IsEmpty())
+ return nullptr;
+
+ lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
+
+ lldb::opaque_compiler_type_t enum_opaque_compiler_type =
+ enum_type.GetOpaqueQualType();
+
+ if (!enum_opaque_compiler_type)
+ return nullptr;
+
+ clang::QualType enum_qual_type(
+ GetCanonicalQualType(enum_opaque_compiler_type));
+
+ const clang::Type *clang_type = enum_qual_type.getTypePtr();
+
+ if (!clang_type)
+ return nullptr;
+
+ const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type);
+
+ if (!enutype)
+ return nullptr;
+
+ clang::EnumConstantDecl *enumerator_decl =
+ clang::EnumConstantDecl::CreateDeserialized(getASTContext(), 0);
+ enumerator_decl->setDeclContext(enutype->getDecl());
+ if (name && name[0])
+ enumerator_decl->setDeclName(&getASTContext().Idents.get(name));
+ enumerator_decl->setType(clang::QualType(enutype, 0));
+ enumerator_decl->setInitVal(value);
+ SetMemberOwningModule(enumerator_decl, enutype->getDecl());
+
+ if (!enumerator_decl)
+ return nullptr;
+
+ enutype->getDecl()->addDecl(enumerator_decl);
+
+ VerifyDecl(enumerator_decl);
+ return enumerator_decl;
+}
+
+clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ int64_t enum_value, uint32_t enum_value_bit_size) {
+ CompilerType underlying_type = GetEnumerationIntegerType(enum_type);
+ bool is_signed = false;
+ underlying_type.IsIntegerType(is_signed);
+
+ llvm::APSInt value(enum_value_bit_size, is_signed);
+ value = enum_value;
+
+ return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
+}
+
+CompilerType TypeSystemClang::GetEnumerationIntegerType(CompilerType type) {
+ clang::QualType qt(ClangUtil::GetQualType(type));
+ const clang::Type *clang_type = qt.getTypePtrOrNull();
+ const auto *enum_type = llvm::dyn_cast_or_null<clang::EnumType>(clang_type);
+ if (!enum_type)
+ return CompilerType();
+
+ return GetType(enum_type->getDecl()->getIntegerType());
+}
+
+CompilerType
+TypeSystemClang::CreateMemberPointerType(const CompilerType &type,
+ const CompilerType &pointee_type) {
+ if (type && pointee_type.IsValid() &&
+ type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!ast)
+ return CompilerType();
+ return ast->GetType(ast->getASTContext().getMemberPointerType(
+ ClangUtil::GetQualType(pointee_type),
+ ClangUtil::GetQualType(type).getTypePtr()));
+ }
+ return CompilerType();
+}
+
+// Dumping types
+#define DEPTH_INCREMENT 2
+
+#ifndef NDEBUG
+LLVM_DUMP_METHOD void
+TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const {
+ if (!type)
+ return;
+ clang::QualType qual_type(GetQualType(type));
+ qual_type.dump();
+}
+#endif
+
+void TypeSystemClang::Dump(Stream &s) {
+ Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl());
+ tu->dump(s.AsRawOstream());
+}
+
+void TypeSystemClang::DumpFromSymbolFile(Stream &s,
+ llvm::StringRef symbol_name) {
+ SymbolFile *symfile = GetSymbolFile();
+
+ if (!symfile)
+ return;
+
+ lldb_private::TypeList type_list;
+ symfile->GetTypes(nullptr, eTypeClassAny, type_list);
+ size_t ntypes = type_list.GetSize();
+
+ for (size_t i = 0; i < ntypes; ++i) {
+ TypeSP type = type_list.GetTypeAtIndex(i);
+
+ if (!symbol_name.empty())
+ if (symbol_name != type->GetName().GetStringRef())
+ continue;
+
+ s << type->GetName().AsCString() << "\n";
+
+ CompilerType full_type = type->GetFullCompilerType();
+ if (clang::TagDecl *tag_decl = GetAsTagDecl(full_type)) {
+ tag_decl->dump(s.AsRawOstream());
+ continue;
+ }
+ if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(full_type)) {
+ typedef_decl->dump(s.AsRawOstream());
+ continue;
+ }
+ if (auto *objc_obj = llvm::dyn_cast<clang::ObjCObjectType>(
+ ClangUtil::GetQualType(full_type).getTypePtr())) {
+ if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) {
+ interface_decl->dump(s.AsRawOstream());
+ continue;
+ }
+ }
+ GetCanonicalQualType(full_type.GetOpaqueQualType())
+ .dump(s.AsRawOstream(), getASTContext());
+ }
+}
+
+void TypeSystemClang::DumpValue(
+ lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
+ lldb::Format format, const lldb_private::DataExtractor &data,
+ lldb::offset_t data_byte_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
+ bool show_summary, bool verbose, uint32_t depth) {
+ if (!type)
+ return;
+
+ clang::QualType qual_type(GetQualType(type));
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ uint32_t field_bit_offset = 0;
+ uint32_t field_byte_offset = 0;
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext().getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ // We might have base classes to print out first
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()->getAs<clang::RecordType>()->getDecl());
+
+ // Skip empty base classes
+ if (!verbose && !TypeSystemClang::RecordHasFields(base_class_decl))
+ continue;
+
+ if (base_class->isVirtual())
+ field_bit_offset =
+ record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ else
+ field_bit_offset = record_layout.getBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ field_byte_offset = field_bit_offset / 8;
+ assert(field_bit_offset % 8 == 0);
+ if (child_idx == 0)
+ s->PutChar('{');
+ else
+ s->PutChar(',');
+
+ clang::QualType base_class_qual_type = base_class->getType();
+ std::string base_class_type_name(base_class_qual_type.getAsString());
+
+ // Indent and print the base class type name
+ s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT),
+ base_class_type_name);
+
+ clang::TypeInfo base_class_type_info =
+ getASTContext().getTypeInfo(base_class_qual_type);
+
+ // Dump the value of the member
+ CompilerType base_clang_type = GetType(base_class_qual_type);
+ base_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ base_clang_type
+ .GetFormat(), // The format with which to display the member
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + field_byte_offset, // Offset into "data" where
+ // to grab value from
+ base_class_type_info.Width / 8, // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable
+ // types
+ show_summary, // Boolean indicating if we should show a summary
+ // for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have
+ // children
+
+ ++child_idx;
+ }
+ }
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++field_idx, ++child_idx) {
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comma (for member 2 and beyond) for the struct/union/class member.
+ if (child_idx == 0)
+ s->PutChar('{');
+ else
+ s->PutChar(',');
+
+ // Indent
+ s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
+
+ clang::QualType field_type = field->getType();
+ // Print the member type if requested
+ // Figure out the type byte size (field_type_info.first) and alignment
+ // (field_type_info.second) from the AST context.
+ clang::TypeInfo field_type_info =
+ getASTContext().getTypeInfo(field_type);
+ assert(field_idx < record_layout.getFieldCount());
+ // Figure out the field offset within the current struct/union/class
+ // type
+ field_bit_offset = record_layout.getFieldOffset(field_idx);
+ field_byte_offset = field_bit_offset / 8;
+ uint32_t field_bitfield_bit_size = 0;
+ uint32_t field_bitfield_bit_offset = 0;
+ if (FieldIsBitfield(*field, field_bitfield_bit_size))
+ field_bitfield_bit_offset = field_bit_offset % 8;
+
+ if (show_types) {
+ std::string field_type_name(field_type.getAsString());
+ if (field_bitfield_bit_size > 0)
+ s->Printf("(%s:%u) ", field_type_name.c_str(),
+ field_bitfield_bit_size);
+ else
+ s->Printf("(%s) ", field_type_name.c_str());
+ }
+ // Print the member name and equal sign
+ s->Printf("%s = ", field->getNameAsString().c_str());
+
+ // Dump the value of the member
+ CompilerType field_clang_type = GetType(field_type);
+ field_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ field_clang_type
+ .GetFormat(), // The format with which to display the member
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + field_byte_offset, // Offset into "data" where to
+ // grab value from
+ field_type_info.Width / 8, // Size of this type in bytes
+ field_bitfield_bit_size, // Bitfield bit size
+ field_bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable
+ // types
+ show_summary, // Boolean indicating if we should show a summary for
+ // the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have
+ // children
+ }
+
+ // Indent the trailing squiggly bracket
+ if (child_idx > 0)
+ s->Printf("\n%*s}", depth, "");
+ }
+ return;
+
+ case clang::Type::Enum:
+ if (GetCompleteType(type)) {
+ const clang::EnumType *enutype =
+ llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+ const clang::EnumDecl *enum_decl = enutype->getDecl();
+ assert(enum_decl);
+ clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+ lldb::offset_t offset = data_byte_offset;
+ const int64_t enum_value = data.GetMaxU64Bitfield(
+ &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
+ for (enum_pos = enum_decl->enumerator_begin(),
+ enum_end_pos = enum_decl->enumerator_end();
+ enum_pos != enum_end_pos; ++enum_pos) {
+ if (enum_pos->getInitVal() == enum_value) {
+ s->Printf("%s", enum_pos->getNameAsString().c_str());
+ return;
+ }
+ }
+ // If we have gotten here we didn't get find the enumerator in the enum
+ // decl, so just print the integer.
+ s->Printf("%" PRIi64, enum_value);
+ }
+ return;
+
+ case clang::Type::ConstantArray: {
+ const clang::ConstantArrayType *array =
+ llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
+ bool is_array_of_characters = false;
+ clang::QualType element_qual_type = array->getElementType();
+
+ const clang::Type *canonical_type =
+ element_qual_type->getCanonicalTypeInternal().getTypePtr();
+ if (canonical_type)
+ is_array_of_characters = canonical_type->isCharType();
+
+ const uint64_t element_count = array->getSize().getLimitedValue();
+
+ clang::TypeInfo field_type_info =
+ getASTContext().getTypeInfo(element_qual_type);
+
+ uint32_t element_idx = 0;
+ uint32_t element_offset = 0;
+ uint64_t element_byte_size = field_type_info.Width / 8;
+ uint32_t element_stride = element_byte_size;
+
+ if (is_array_of_characters) {
+ s->PutChar('"');
+ DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
+ element_byte_size, element_count, UINT32_MAX,
+ LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('"');
+ return;
+ } else {
+ CompilerType element_clang_type = GetType(element_qual_type);
+ lldb::Format element_format = element_clang_type.GetFormat();
+
+ for (element_idx = 0; element_idx < element_count; ++element_idx) {
+ // Print the starting squiggly bracket (if this is the first member) or
+ // comman (for member 2 and beyong) for the struct/union/class member.
+ if (element_idx == 0)
+ s->PutChar('{');
+ else
+ s->PutChar(',');
+
+ // Indent and print the index
+ s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
+
+ // Figure out the field offset within the current struct/union/class
+ // type
+ element_offset = element_idx * element_stride;
+
+ // Dump the value of the member
+ element_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ element_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset +
+ element_offset, // Offset into "data" where to grab value from
+ element_byte_size, // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable
+ // types
+ show_summary, // Boolean indicating if we should show a summary for
+ // the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have
+ // children
+ }
+
+ // Indent the trailing squiggly bracket
+ if (element_idx > 0)
+ s->Printf("\n%*s}", depth, "");
+ }
+ }
+ return;
+
+ case clang::Type::Typedef: {
+ clang::QualType typedef_qual_type =
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType();
+
+ CompilerType typedef_clang_type = GetType(typedef_qual_type);
+ lldb::Format typedef_format = typedef_clang_type.GetFormat();
+ clang::TypeInfo typedef_type_info =
+ getASTContext().getTypeInfo(typedef_qual_type);
+ uint64_t typedef_byte_size = typedef_type_info.Width / 8;
+
+ return typedef_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ typedef_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ typedef_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the
+ // current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ } break;
+
+ case clang::Type::Auto: {
+ clang::QualType elaborated_qual_type =
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
+ CompilerType elaborated_clang_type = GetType(elaborated_qual_type);
+ lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
+ clang::TypeInfo elaborated_type_info =
+ getASTContext().getTypeInfo(elaborated_qual_type);
+ uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
+
+ return elaborated_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the
+ // current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ } break;
+
+ case clang::Type::Elaborated: {
+ clang::QualType elaborated_qual_type =
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
+ CompilerType elaborated_clang_type = GetType(elaborated_qual_type);
+ lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
+ clang::TypeInfo elaborated_type_info =
+ getASTContext().getTypeInfo(elaborated_qual_type);
+ uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
+
+ return elaborated_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the
+ // current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ } break;
+
+ case clang::Type::Paren: {
+ clang::QualType desugar_qual_type =
+ llvm::cast<clang::ParenType>(qual_type)->desugar();
+ CompilerType desugar_clang_type = GetType(desugar_qual_type);
+
+ lldb::Format desugar_format = desugar_clang_type.GetFormat();
+ clang::TypeInfo desugar_type_info =
+ getASTContext().getTypeInfo(desugar_qual_type);
+ uint64_t desugar_byte_size = desugar_type_info.Width / 8;
+
+ return desugar_clang_type.DumpValue(
+ exe_ctx,
+ s, // Stream to dump to
+ desugar_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ desugar_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the
+ // current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ } break;
+
+ default:
+ // We are down to a scalar type that we just need to display.
+ DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
+ UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
+ bitfield_bit_offset);
+
+ if (show_summary)
+ DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+ break;
+ }
+}
+
+static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s,
+ const DataExtractor &data, lldb::offset_t byte_offset,
+ size_t byte_size, uint32_t bitfield_bit_offset,
+ uint32_t bitfield_bit_size) {
+ const clang::EnumType *enutype =
+ llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+ const clang::EnumDecl *enum_decl = enutype->getDecl();
+ assert(enum_decl);
+ lldb::offset_t offset = byte_offset;
+ const uint64_t enum_svalue = data.GetMaxS64Bitfield(
+ &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
+ bool can_be_bitfield = true;
+ uint64_t covered_bits = 0;
+ int num_enumerators = 0;
+
+ // Try to find an exact match for the value.
+ // At the same time, we're applying a heuristic to determine whether we want
+ // to print this enum as a bitfield. We're likely dealing with a bitfield if
+ // every enumerator is either a one bit value or a superset of the previous
+ // enumerators. Also 0 doesn't make sense when the enumerators are used as
+ // flags.
+ for (auto *enumerator : enum_decl->enumerators()) {
+ uint64_t val = enumerator->getInitVal().getSExtValue();
+ val = llvm::SignExtend64(val, 8*byte_size);
+ if (llvm::countPopulation(val) != 1 && (val & ~covered_bits) != 0)
+ can_be_bitfield = false;
+ covered_bits |= val;
+ ++num_enumerators;
+ if (val == enum_svalue) {
+ // Found an exact match, that's all we need to do.
+ s->PutCString(enumerator->getNameAsString());
+ return true;
+ }
+ }
+
+ // Unsigned values make more sense for flags.
+ offset = byte_offset;
+ const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
+ &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
+
+ // No exact match, but we don't think this is a bitfield. Print the value as
+ // decimal.
+ if (!can_be_bitfield) {
+ if (qual_type->isSignedIntegerOrEnumerationType())
+ s->Printf("%" PRIi64, enum_svalue);
+ else
+ s->Printf("%" PRIu64, enum_uvalue);
+ return true;
+ }
+
+ uint64_t remaining_value = enum_uvalue;
+ std::vector<std::pair<uint64_t, llvm::StringRef>> values;
+ values.reserve(num_enumerators);
+ for (auto *enumerator : enum_decl->enumerators())
+ if (auto val = enumerator->getInitVal().getZExtValue())
+ values.emplace_back(val, enumerator->getName());
+
+ // Sort in reverse order of the number of the population count, so that in
+ // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that
+ // A | C where A is declared before C is displayed in this order.
+ std::stable_sort(values.begin(), values.end(), [](const auto &a, const auto &b) {
+ return llvm::countPopulation(a.first) > llvm::countPopulation(b.first);
+ });
+
+ for (const auto &val : values) {
+ if ((remaining_value & val.first) != val.first)
+ continue;
+ remaining_value &= ~val.first;
+ s->PutCString(val.second);
+ if (remaining_value)
+ s->PutCString(" | ");
+ }
+
+ // If there is a remainder that is not covered by the value, print it as hex.
+ if (remaining_value)
+ s->Printf("0x%" PRIx64, remaining_value);
+
+ return true;
+}
+
+bool TypeSystemClang::DumpTypeValue(
+ lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
+ const lldb_private::DataExtractor &data, lldb::offset_t byte_offset,
+ size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope) {
+ if (!type)
+ return false;
+ if (IsAggregateType(type)) {
+ return false;
+ } else {
+ clang::QualType qual_type(GetQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ if (type_class == clang::Type::Elaborated) {
+ qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
+ return DumpTypeValue(qual_type.getAsOpaquePtr(), s, format, data, byte_offset, byte_size,
+ bitfield_bit_size, bitfield_bit_offset, exe_scope);
+ }
+
+ switch (type_class) {
+ case clang::Type::Typedef: {
+ clang::QualType typedef_qual_type =
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType();
+ CompilerType typedef_clang_type = GetType(typedef_qual_type);
+ if (format == eFormatDefault)
+ format = typedef_clang_type.GetFormat();
+ clang::TypeInfo typedef_type_info =
+ getASTContext().getTypeInfo(typedef_qual_type);
+ uint64_t typedef_byte_size = typedef_type_info.Width / 8;
+
+ return typedef_clang_type.DumpTypeValue(
+ s,
+ format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ byte_offset, // Offset into "data" where to grab value from
+ typedef_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
+ // treat as a bitfield
+ bitfield_bit_offset, // Offset in bits of a bitfield value if
+ // bitfield_bit_size != 0
+ exe_scope);
+ } break;
+
+ case clang::Type::Enum:
+ // If our format is enum or default, show the enumeration value as its
+ // enumeration string value, else just display it as requested.
+ if ((format == eFormatEnum || format == eFormatDefault) &&
+ GetCompleteType(type))
+ return DumpEnumValue(qual_type, s, data, byte_offset, byte_size,
+ bitfield_bit_offset, bitfield_bit_size);
+ // format was not enum, just fall through and dump the value as
+ // requested....
+ LLVM_FALLTHROUGH;
+
+ default:
+ // We are down to a scalar type that we just need to display.
+ {
+ uint32_t item_count = 1;
+ // A few formats, we might need to modify our size and count for
+ // depending
+ // on how we are trying to display the value...
+ switch (format) {
+ default:
+ case eFormatBoolean:
+ case eFormatBinary:
+ case eFormatComplex:
+ case eFormatCString: // NULL terminated C strings
+ case eFormatDecimal:
+ case eFormatEnum:
+ case eFormatHex:
+ case eFormatHexUppercase:
+ case eFormatFloat:
+ case eFormatOctal:
+ case eFormatOSType:
+ case eFormatUnsigned:
+ case eFormatPointer:
+ case eFormatVectorOfChar:
+ case eFormatVectorOfSInt8:
+ case eFormatVectorOfUInt8:
+ case eFormatVectorOfSInt16:
+ case eFormatVectorOfUInt16:
+ case eFormatVectorOfSInt32:
+ case eFormatVectorOfUInt32:
+ case eFormatVectorOfSInt64:
+ case eFormatVectorOfUInt64:
+ case eFormatVectorOfFloat32:
+ case eFormatVectorOfFloat64:
+ case eFormatVectorOfUInt128:
+ break;
+
+ case eFormatChar:
+ case eFormatCharPrintable:
+ case eFormatCharArray:
+ case eFormatBytes:
+ case eFormatBytesWithASCII:
+ item_count = byte_size;
+ byte_size = 1;
+ break;
+
+ case eFormatUnicode16:
+ item_count = byte_size / 2;
+ byte_size = 2;
+ break;
+
+ case eFormatUnicode32:
+ item_count = byte_size / 4;
+ byte_size = 4;
+ break;
+ }
+ return DumpDataExtractor(data, s, byte_offset, format, byte_size,
+ item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
+ bitfield_bit_size, bitfield_bit_offset,
+ exe_scope);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type,
+ ExecutionContext *exe_ctx, Stream *s,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_byte_offset,
+ size_t data_byte_size) {
+ uint32_t length = 0;
+ if (IsCStringType(type, length)) {
+ if (exe_ctx) {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process) {
+ lldb::offset_t offset = data_byte_offset;
+ lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
+ std::vector<uint8_t> buf;
+ if (length > 0)
+ buf.resize(length);
+ else
+ buf.resize(256);
+
+ DataExtractor cstr_data(&buf.front(), buf.size(),
+ process->GetByteOrder(), 4);
+ buf.back() = '\0';
+ size_t bytes_read;
+ size_t total_cstr_len = 0;
+ Status error;
+ while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(),
+ buf.size(), error)) > 0) {
+ const size_t len = strlen((const char *)&buf.front());
+ if (len == 0)
+ break;
+ if (total_cstr_len == 0)
+ s->PutCString(" \"");
+ DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
+ UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+ total_cstr_len += len;
+ if (len < buf.size())
+ break;
+ pointer_address += total_cstr_len;
+ }
+ if (total_cstr_len > 0)
+ s->PutChar('"');
+ }
+ }
+ }
+}
+
+void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
+ lldb::DescriptionLevel level) {
+ StreamFile s(stdout, false);
+ DumpTypeDescription(type, &s, level);
+
+ CompilerType ct(this, type);
+ const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
+ ClangASTMetadata *metadata = GetMetadata(clang_type);
+ if (metadata) {
+ metadata->Dump(&s);
+ }
+}
+
+void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
+ Stream *s,
+ lldb::DescriptionLevel level) {
+ if (type) {
+ clang::QualType qual_type =
+ RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef});
+
+ llvm::SmallVector<char, 1024> buf;
+ llvm::raw_svector_ostream llvm_ostrm(buf);
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ GetCompleteType(type);
+
+ auto *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (!objc_class_type)
+ break;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (!class_interface_decl)
+ break;
+ if (level == eDescriptionLevelVerbose)
+ class_interface_decl->dump(llvm_ostrm);
+ else
+ class_interface_decl->print(llvm_ostrm,
+ getASTContext().getPrintingPolicy(),
+ s->GetIndentLevel());
+ } break;
+
+ case clang::Type::Typedef: {
+ auto *typedef_type = qual_type->getAs<clang::TypedefType>();
+ if (!typedef_type)
+ break;
+ const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+ if (level == eDescriptionLevelVerbose)
+ typedef_decl->dump(llvm_ostrm);
+ else {
+ std::string clang_typedef_name(
+ typedef_decl->getQualifiedNameAsString());
+ if (!clang_typedef_name.empty()) {
+ s->PutCString("typedef ");
+ s->PutCString(clang_typedef_name);
+ }
+ }
+ } break;
+
+ case clang::Type::Record: {
+ GetCompleteType(type);
+
+ auto *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (level == eDescriptionLevelVerbose)
+ record_decl->dump(llvm_ostrm);
+ else {
+ if (auto *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl))
+ cxx_record_decl->print(llvm_ostrm,
+ getASTContext().getPrintingPolicy(),
+ s->GetIndentLevel());
+ else
+ record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(),
+ s->GetIndentLevel());
+ }
+ } break;
+
+ default: {
+ if (auto *tag_type =
+ llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) {
+ if (clang::TagDecl *tag_decl = tag_type->getDecl()) {
+ if (level == eDescriptionLevelVerbose)
+ tag_decl->dump(llvm_ostrm);
+ else
+ tag_decl->print(llvm_ostrm, 0);
+ }
+ } else {
+ if (level == eDescriptionLevelVerbose)
+ qual_type->dump(llvm_ostrm, getASTContext());
+ else {
+ std::string clang_type_name(qual_type.getAsString());
+ if (!clang_type_name.empty())
+ s->PutCString(clang_type_name);
+ }
+ }
+ }
+ }
+
+ if (buf.size() > 0) {
+ s->Write(buf.data(), buf.size());
+ }
+}
+}
+
+void TypeSystemClang::DumpTypeName(const CompilerType &type) {
+ if (ClangUtil::IsClangType(type)) {
+ clang::QualType qual_type(
+ ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ printf("class %s", cxx_record_decl->getName().str().c_str());
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ printf("enum %s", enum_decl->getName().str().c_str());
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly
+ // added ASTContext because it only supports TagDecl objects right
+ // now...
+ if (class_interface_decl)
+ printf("@class %s", class_interface_decl->getName().str().c_str());
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getName()
+ .str()
+ .c_str());
+ break;
+
+ case clang::Type::Auto:
+ printf("auto ");
+ return DumpTypeName(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ printf("elaborated ");
+ return DumpTypeName(CompilerType(
+ type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ printf("paren ");
+ return DumpTypeName(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ printf("TypeSystemClang::DumpTypeName() type_class = %u", type_class);
+ break;
+ }
+ }
+}
+
+clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
+ const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
+ if (template_param_infos.IsValid()) {
+ std::string template_basename(parent_name);
+ template_basename.erase(template_basename.find('<'));
+
+ return CreateClassTemplateDecl(decl_ctx, owning_module, access_type,
+ template_basename.c_str(), tag_decl_kind,
+ template_param_infos);
+ }
+ return nullptr;
+}
+
+void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) {
+ SymbolFile *sym_file = GetSymbolFile();
+ if (sym_file) {
+ CompilerType clang_type = GetTypeForDecl(decl);
+ if (clang_type)
+ sym_file->CompleteType(clang_type);
+ }
+}
+
+void TypeSystemClang::CompleteObjCInterfaceDecl(
+ clang::ObjCInterfaceDecl *decl) {
+ SymbolFile *sym_file = GetSymbolFile();
+ if (sym_file) {
+ CompilerType clang_type = GetTypeForDecl(decl);
+ if (clang_type)
+ sym_file->CompleteType(clang_type);
+ }
+}
+
+DWARFASTParser *TypeSystemClang::GetDWARFParser() {
+ if (!m_dwarf_ast_parser_up)
+ m_dwarf_ast_parser_up = std::make_unique<DWARFASTParserClang>(*this);
+ return m_dwarf_ast_parser_up.get();
+}
+
+PDBASTParser *TypeSystemClang::GetPDBParser() {
+ if (!m_pdb_ast_parser_up)
+ m_pdb_ast_parser_up = std::make_unique<PDBASTParser>(*this);
+ return m_pdb_ast_parser_up.get();
+}
+
+bool TypeSystemClang::LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &bit_size,
+ uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets) {
+ lldb_private::ClangASTImporter *importer = nullptr;
+ if (m_dwarf_ast_parser_up)
+ importer = &m_dwarf_ast_parser_up->GetClangASTImporter();
+ if (!importer && m_pdb_ast_parser_up)
+ importer = &m_pdb_ast_parser_up->GetClangASTImporter();
+ if (!importer)
+ return false;
+
+ return importer->LayoutRecordType(record_decl, bit_size, alignment,
+ field_offsets, base_offsets, vbase_offsets);
+}
+
+// CompilerDecl override functions
+
+ConstString TypeSystemClang::DeclGetName(void *opaque_decl) {
+ if (opaque_decl) {
+ clang::NamedDecl *nd =
+ llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl);
+ if (nd != nullptr)
+ return ConstString(nd->getDeclName().getAsString());
+ }
+ return ConstString();
+}
+
+ConstString TypeSystemClang::DeclGetMangledName(void *opaque_decl) {
+ if (opaque_decl) {
+ clang::NamedDecl *nd =
+ llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl);
+ if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) {
+ clang::MangleContext *mc = getMangleContext();
+ if (mc && mc->shouldMangleCXXName(nd)) {
+ llvm::SmallVector<char, 1024> buf;
+ llvm::raw_svector_ostream llvm_ostrm(buf);
+ if (llvm::isa<clang::CXXConstructorDecl>(nd)) {
+ mc->mangleName(
+ clang::GlobalDecl(llvm::dyn_cast<clang::CXXConstructorDecl>(nd),
+ Ctor_Complete),
+ llvm_ostrm);
+ } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) {
+ mc->mangleName(
+ clang::GlobalDecl(llvm::dyn_cast<clang::CXXDestructorDecl>(nd),
+ Dtor_Complete),
+ llvm_ostrm);
+ } else {
+ mc->mangleName(nd, llvm_ostrm);
+ }
+ if (buf.size() > 0)
+ return ConstString(buf.data(), buf.size());
+ }
+ }
+ }
+ return ConstString();
+}
+
+CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) {
+ if (opaque_decl)
+ return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext());
+ return CompilerDeclContext();
+}
+
+CompilerType TypeSystemClang::DeclGetFunctionReturnType(void *opaque_decl) {
+ if (clang::FunctionDecl *func_decl =
+ llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
+ return GetType(func_decl->getReturnType());
+ if (clang::ObjCMethodDecl *objc_method =
+ llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
+ return GetType(objc_method->getReturnType());
+ else
+ return CompilerType();
+}
+
+size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) {
+ if (clang::FunctionDecl *func_decl =
+ llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl))
+ return func_decl->param_size();
+ if (clang::ObjCMethodDecl *objc_method =
+ llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl))
+ return objc_method->param_size();
+ else
+ return 0;
+}
+
+CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
+ size_t idx) {
+ if (clang::FunctionDecl *func_decl =
+ llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) {
+ if (idx < func_decl->param_size()) {
+ ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
+ if (var_decl)
+ return GetType(var_decl->getOriginalType());
+ }
+ } else if (clang::ObjCMethodDecl *objc_method =
+ llvm::dyn_cast<clang::ObjCMethodDecl>(
+ (clang::Decl *)opaque_decl)) {
+ if (idx < objc_method->param_size())
+ return GetType(objc_method->parameters()[idx]->getOriginalType());
+ }
+ return CompilerType();
+}
+
+// CompilerDeclContext functions
+
+std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
+ void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
+ std::vector<CompilerDecl> found_decls;
+ if (opaque_decl_ctx) {
+ DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
+ std::set<DeclContext *> searched;
+ std::multimap<DeclContext *, DeclContext *> search_queue;
+ SymbolFile *symbol_file = GetSymbolFile();
+
+ for (clang::DeclContext *decl_context = root_decl_ctx;
+ decl_context != nullptr && found_decls.empty();
+ decl_context = decl_context->getParent()) {
+ search_queue.insert(std::make_pair(decl_context, decl_context));
+
+ for (auto it = search_queue.find(decl_context); it != search_queue.end();
+ it++) {
+ if (!searched.insert(it->second).second)
+ continue;
+ symbol_file->ParseDeclsForContext(
+ CreateDeclContext(it->second));
+
+ for (clang::Decl *child : it->second->decls()) {
+ if (clang::UsingDirectiveDecl *ud =
+ llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
+ if (ignore_using_decls)
+ continue;
+ clang::DeclContext *from = ud->getCommonAncestor();
+ if (searched.find(ud->getNominatedNamespace()) == searched.end())
+ search_queue.insert(
+ std::make_pair(from, ud->getNominatedNamespace()));
+ } else if (clang::UsingDecl *ud =
+ llvm::dyn_cast<clang::UsingDecl>(child)) {
+ if (ignore_using_decls)
+ continue;
+ for (clang::UsingShadowDecl *usd : ud->shadows()) {
+ clang::Decl *target = usd->getTargetDecl();
+ if (clang::NamedDecl *nd =
+ llvm::dyn_cast<clang::NamedDecl>(target)) {
+ IdentifierInfo *ii = nd->getIdentifier();
+ if (ii != nullptr &&
+ ii->getName().equals(name.AsCString(nullptr)))
+ found_decls.push_back(GetCompilerDecl(nd));
+ }
+ }
+ } else if (clang::NamedDecl *nd =
+ llvm::dyn_cast<clang::NamedDecl>(child)) {
+ IdentifierInfo *ii = nd->getIdentifier();
+ if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
+ found_decls.push_back(GetCompilerDecl(nd));
+ }
+ }
+ }
+ }
+ }
+ return found_decls;
+}
+
+// Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents,
+// and return the number of levels it took to find it, or
+// LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using
+// declaration, its name and/or type, if set, will be used to check that the
+// decl found in the scope is a match.
+//
+// The optional name is required by languages (like C++) to handle using
+// declarations like:
+//
+// void poo();
+// namespace ns {
+// void foo();
+// void goo();
+// }
+// void bar() {
+// using ns::foo;
+// // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and
+// // LLDB_INVALID_DECL_LEVEL for 'goo'.
+// }
+//
+// The optional type is useful in the case that there's a specific overload
+// that we're looking for that might otherwise be shadowed, like:
+//
+// void foo(int);
+// namespace ns {
+// void foo();
+// }
+// void bar() {
+// using ns::foo;
+// // CountDeclLevels returns 0 for { 'foo', void() },
+// // 1 for { 'foo', void(int) }, and
+// // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }.
+// }
+//
+// NOTE: Because file statics are at the TranslationUnit along with globals, a
+// function at file scope will return the same level as a function at global
+// scope. Ideally we'd like to treat the file scope as an additional scope just
+// below the global scope. More work needs to be done to recognise that, if
+// the decl we're trying to look up is static, we should compare its source
+// file with that of the current scope and return a lower number for it.
+uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx,
+ clang::DeclContext *child_decl_ctx,
+ ConstString *child_name,
+ CompilerType *child_type) {
+ if (frame_decl_ctx) {
+ std::set<DeclContext *> searched;
+ std::multimap<DeclContext *, DeclContext *> search_queue;
+ SymbolFile *symbol_file = GetSymbolFile();
+
+ // Get the lookup scope for the decl we're trying to find.
+ clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
+
+ // Look for it in our scope's decl context and its parents.
+ uint32_t level = 0;
+ for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr;
+ decl_ctx = decl_ctx->getParent()) {
+ if (!decl_ctx->isLookupContext())
+ continue;
+ if (decl_ctx == parent_decl_ctx)
+ // Found it!
+ return level;
+ search_queue.insert(std::make_pair(decl_ctx, decl_ctx));
+ for (auto it = search_queue.find(decl_ctx); it != search_queue.end();
+ it++) {
+ if (searched.find(it->second) != searched.end())
+ continue;
+
+ // Currently DWARF has one shared translation unit for all Decls at top
+ // level, so this would erroneously find using statements anywhere. So
+ // don't look at the top-level translation unit.
+ // TODO fix this and add a testcase that depends on it.
+
+ if (llvm::isa<clang::TranslationUnitDecl>(it->second))
+ continue;
+
+ searched.insert(it->second);
+ symbol_file->ParseDeclsForContext(
+ CreateDeclContext(it->second));
+
+ for (clang::Decl *child : it->second->decls()) {
+ if (clang::UsingDirectiveDecl *ud =
+ llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) {
+ clang::DeclContext *ns = ud->getNominatedNamespace();
+ if (ns == parent_decl_ctx)
+ // Found it!
+ return level;
+ clang::DeclContext *from = ud->getCommonAncestor();
+ if (searched.find(ns) == searched.end())
+ search_queue.insert(std::make_pair(from, ns));
+ } else if (child_name) {
+ if (clang::UsingDecl *ud =
+ llvm::dyn_cast<clang::UsingDecl>(child)) {
+ for (clang::UsingShadowDecl *usd : ud->shadows()) {
+ clang::Decl *target = usd->getTargetDecl();
+ clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target);
+ if (!nd)
+ continue;
+ // Check names.
+ IdentifierInfo *ii = nd->getIdentifier();
+ if (ii == nullptr ||
+ !ii->getName().equals(child_name->AsCString(nullptr)))
+ continue;
+ // Check types, if one was provided.
+ if (child_type) {
+ CompilerType clang_type = GetTypeForDecl(nd);
+ if (!AreTypesSame(clang_type, *child_type,
+ /*ignore_qualifiers=*/true))
+ continue;
+ }
+ // Found it!
+ return level;
+ }
+ }
+ }
+ }
+ }
+ ++level;
+ }
+ }
+ return LLDB_INVALID_DECL_LEVEL;
+}
+
+ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) {
+ if (opaque_decl_ctx) {
+ clang::NamedDecl *named_decl =
+ llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
+ if (named_decl)
+ return ConstString(named_decl->getName());
+ }
+ return ConstString();
+}
+
+ConstString
+TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
+ if (opaque_decl_ctx) {
+ clang::NamedDecl *named_decl =
+ llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
+ if (named_decl)
+ return ConstString(
+ llvm::StringRef(named_decl->getQualifiedNameAsString()));
+ }
+ return ConstString();
+}
+
+bool TypeSystemClang::DeclContextIsClassMethod(
+ void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
+ bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
+ if (opaque_decl_ctx) {
+ clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
+ if (ObjCMethodDecl *objc_method =
+ llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) {
+ if (is_instance_method_ptr)
+ *is_instance_method_ptr = objc_method->isInstanceMethod();
+ if (language_ptr)
+ *language_ptr = eLanguageTypeObjC;
+ if (language_object_name_ptr)
+ language_object_name_ptr->SetCString("self");
+ return true;
+ } else if (CXXMethodDecl *cxx_method =
+ llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) {
+ if (is_instance_method_ptr)
+ *is_instance_method_ptr = cxx_method->isInstance();
+ if (language_ptr)
+ *language_ptr = eLanguageTypeC_plus_plus;
+ if (language_object_name_ptr)
+ language_object_name_ptr->SetCString("this");
+ return true;
+ } else if (clang::FunctionDecl *function_decl =
+ llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) {
+ ClangASTMetadata *metadata = GetMetadata(function_decl);
+ if (metadata && metadata->HasObjectPtr()) {
+ if (is_instance_method_ptr)
+ *is_instance_method_ptr = true;
+ if (language_ptr)
+ *language_ptr = eLanguageTypeObjC;
+ if (language_object_name_ptr)
+ language_object_name_ptr->SetCString(metadata->GetObjectPtrName());
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool TypeSystemClang::DeclContextIsContainedInLookup(
+ void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
+ auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
+ auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
+
+ do {
+ // A decl context always includes its own contents in its lookup.
+ if (decl_ctx == other)
+ return true;
+
+ // If we have an inline namespace, then the lookup of the parent context
+ // also includes the inline namespace contents.
+ } while (other->isInlineNamespace() && (other = other->getParent()));
+
+ return false;
+}
+
+static bool IsClangDeclContext(const CompilerDeclContext &dc) {
+ return dc.IsValid() && isa<TypeSystemClang>(dc.GetTypeSystem());
+}
+
+clang::DeclContext *
+TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
+ if (IsClangDeclContext(dc))
+ return (clang::DeclContext *)dc.GetOpaqueDeclContext();
+ return nullptr;
+}
+
+ObjCMethodDecl *
+TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
+ if (IsClangDeclContext(dc))
+ return llvm::dyn_cast<clang::ObjCMethodDecl>(
+ (clang::DeclContext *)dc.GetOpaqueDeclContext());
+ return nullptr;
+}
+
+CXXMethodDecl *
+TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
+ if (IsClangDeclContext(dc))
+ return llvm::dyn_cast<clang::CXXMethodDecl>(
+ (clang::DeclContext *)dc.GetOpaqueDeclContext());
+ return nullptr;
+}
+
+clang::FunctionDecl *
+TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
+ if (IsClangDeclContext(dc))
+ return llvm::dyn_cast<clang::FunctionDecl>(
+ (clang::DeclContext *)dc.GetOpaqueDeclContext());
+ return nullptr;
+}
+
+clang::NamespaceDecl *
+TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
+ if (IsClangDeclContext(dc))
+ return llvm::dyn_cast<clang::NamespaceDecl>(
+ (clang::DeclContext *)dc.GetOpaqueDeclContext());
+ return nullptr;
+}
+
+ClangASTMetadata *
+TypeSystemClang::DeclContextGetMetaData(const CompilerDeclContext &dc,
+ const Decl *object) {
+ TypeSystemClang *ast = llvm::cast<TypeSystemClang>(dc.GetTypeSystem());
+ return ast->GetMetadata(object);
+}
+
+clang::ASTContext *
+TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(dc.GetTypeSystem());
+ if (ast)
+ return &ast->getASTContext();
+ return nullptr;
+}
+
+TypeSystemClangForExpressions::TypeSystemClangForExpressions(
+ Target &target, llvm::Triple triple)
+ : TypeSystemClang("scratch ASTContext", triple),
+ m_target_wp(target.shared_from_this()),
+ m_persistent_variables(new ClangPersistentVariables) {
+ m_scratch_ast_source_up = std::make_unique<ClangASTSource>(
+ target.shared_from_this(), m_persistent_variables->GetClangASTImporter());
+ m_scratch_ast_source_up->InstallASTContext(*this);
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
+ m_scratch_ast_source_up->CreateProxy());
+ SetExternalSource(proxy_ast_source);
+}
+
+void TypeSystemClangForExpressions::Finalize() {
+ TypeSystemClang::Finalize();
+ m_scratch_ast_source_up.reset();
+}
+
+UserExpression *TypeSystemClangForExpressions::GetUserExpression(
+ llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
+ Expression::ResultType desired_type,
+ const EvaluateExpressionOptions &options,
+ ValueObject *ctx_obj) {
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ return new ClangUserExpression(*target_sp.get(), expr, prefix, language,
+ desired_type, options, ctx_obj);
+}
+
+FunctionCaller *TypeSystemClangForExpressions::GetFunctionCaller(
+ const CompilerType &return_type, const Address &function_address,
+ const ValueList &arg_value_list, const char *name) {
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ Process *process = target_sp->GetProcessSP().get();
+ if (!process)
+ return nullptr;
+
+ return new ClangFunctionCaller(*process, return_type, function_address,
+ arg_value_list, name);
+}
+
+UtilityFunction *
+TypeSystemClangForExpressions::GetUtilityFunction(const char *text,
+ const char *name) {
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return nullptr;
+
+ return new ClangUtilityFunction(*target_sp.get(), text, name);
+}
+
+PersistentExpressionState *
+TypeSystemClangForExpressions::GetPersistentExpressionState() {
+ return m_persistent_variables.get();
+}
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
new file mode 100644
index 000000000000..9475e4d9f442
--- /dev/null
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -0,0 +1,1153 @@
+//===-- TypeSystemClang.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
+#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
+
+#include <stdint.h>
+
+#include <functional>
+#include <initializer_list>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTFwd.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
+#include "lldb/Expression/ExpressionVariable.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/lldb-enumerations.h"
+
+class DWARFASTParserClang;
+class PDBASTParser;
+
+namespace clang {
+class FileManager;
+class HeaderSearch;
+class ModuleMap;
+} // namespace clang
+
+namespace lldb_private {
+
+class ClangASTMetadata;
+class ClangASTSource;
+class Declaration;
+
+/// A Clang module ID.
+class OptionalClangModuleID {
+ unsigned m_id = 0;
+
+public:
+ OptionalClangModuleID() = default;
+ explicit OptionalClangModuleID(unsigned id) : m_id(id) {}
+ bool HasValue() const { return m_id != 0; }
+ unsigned GetValue() const { return m_id; }
+};
+
+/// The implementation of lldb::Type's m_payload field for TypeSystemClang.
+class TypePayloadClang {
+ /// The Layout is as follows:
+ /// \verbatim
+ /// bit 0..30 ... Owning Module ID.
+ /// bit 31 ...... IsCompleteObjCClass.
+ /// \endverbatim
+ Type::Payload m_payload = 0;
+
+public:
+ TypePayloadClang() = default;
+ explicit TypePayloadClang(OptionalClangModuleID owning_module,
+ bool is_complete_objc_class = false);
+ explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {}
+ operator Type::Payload() { return m_payload; }
+
+ static constexpr unsigned ObjCClassBit = 1 << 31;
+ bool IsCompleteObjCClass() { return Flags(m_payload).Test(ObjCClassBit); }
+ void SetIsCompleteObjCClass(bool is_complete_objc_class) {
+ m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit)
+ : Flags(m_payload).Clear(ObjCClassBit);
+ }
+ OptionalClangModuleID GetOwningModule() {
+ return OptionalClangModuleID(Flags(m_payload).Clear(ObjCClassBit));
+ }
+ void SetOwningModule(OptionalClangModuleID id);
+ /// \}
+};
+
+/// A TypeSystem implementation based on Clang.
+///
+/// This class uses a single clang::ASTContext as the backend for storing
+/// its types and declarations. Every clang::ASTContext should also just have
+/// a single associated TypeSystemClang instance that manages it.
+///
+/// The clang::ASTContext instance can either be created by TypeSystemClang
+/// itself or it can adopt an existing clang::ASTContext (for example, when
+/// it is necessary to provide a TypeSystem interface for an existing
+/// clang::ASTContext that was created by clang::CompilerInstance).
+class TypeSystemClang : public TypeSystem {
+ // LLVM RTTI support
+ static char ID;
+
+public:
+ typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
+ typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton,
+ clang::ObjCInterfaceDecl *);
+
+ // llvm casting support
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const TypeSystem *ts) { return ts->isA(&ID); }
+
+ /// Constructs a TypeSystemClang with an ASTContext using the given triple.
+ ///
+ /// \param name The name for the TypeSystemClang (for logging purposes)
+ /// \param triple The llvm::Triple used for the ASTContext. The triple defines
+ /// certain characteristics of the ASTContext and its types
+ /// (e.g., whether certain primitive types exist or what their
+ /// signedness is).
+ explicit TypeSystemClang(llvm::StringRef name, llvm::Triple triple);
+
+ /// Constructs a TypeSystemClang that uses an existing ASTContext internally.
+ /// Useful when having an existing ASTContext created by Clang.
+ ///
+ /// \param name The name for the TypeSystemClang (for logging purposes)
+ /// \param existing_ctxt An existing ASTContext.
+ explicit TypeSystemClang(llvm::StringRef name,
+ clang::ASTContext &existing_ctxt);
+
+ ~TypeSystemClang() override;
+
+ void Finalize() override;
+
+ // PluginInterface functions
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ static ConstString GetPluginNameStatic();
+
+ static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
+ Module *module, Target *target);
+
+ static LanguageSet GetSupportedLanguagesForTypes();
+ static LanguageSet GetSupportedLanguagesForExpressions();
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static TypeSystemClang *GetASTContext(clang::ASTContext *ast_ctx);
+
+ static TypeSystemClang *GetScratch(Target &target,
+ bool create_on_demand = true) {
+ auto type_system_or_err = target.GetScratchTypeSystemForLanguage(
+ lldb::eLanguageTypeC, create_on_demand);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
+ std::move(err), "Couldn't get scratch TypeSystemClang");
+ return nullptr;
+ }
+ return llvm::dyn_cast<TypeSystemClang>(&type_system_or_err.get());
+ }
+
+ /// Returns the display name of this TypeSystemClang that indicates what
+ /// purpose it serves in LLDB. Used for example in logs.
+ llvm::StringRef getDisplayName() const { return m_display_name; }
+
+ /// Returns the clang::ASTContext instance managed by this TypeSystemClang.
+ clang::ASTContext &getASTContext();
+
+ clang::MangleContext *getMangleContext();
+
+ std::shared_ptr<clang::TargetOptions> &getTargetOptions();
+
+ clang::TargetInfo *getTargetInfo();
+
+ void setSema(clang::Sema *s);
+ clang::Sema *getSema() { return m_sema; }
+
+ const char *GetTargetTriple();
+
+ void SetExternalSource(
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up);
+
+ bool GetCompleteDecl(clang::Decl *decl) {
+ return TypeSystemClang::GetCompleteDecl(&getASTContext(), decl);
+ }
+
+ static void DumpDeclHiearchy(clang::Decl *decl);
+
+ static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx);
+
+ static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl);
+
+ static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl);
+
+ void SetMetadataAsUserID(const clang::Decl *decl, lldb::user_id_t user_id);
+ void SetMetadataAsUserID(const clang::Type *type, lldb::user_id_t user_id);
+
+ void SetMetadata(const clang::Decl *object, ClangASTMetadata &meta_data);
+
+ void SetMetadata(const clang::Type *object, ClangASTMetadata &meta_data);
+ ClangASTMetadata *GetMetadata(const clang::Decl *object);
+ ClangASTMetadata *GetMetadata(const clang::Type *object);
+
+ // Basic Types
+ CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
+ size_t bit_size) override;
+
+ CompilerType GetBasicType(lldb::BasicType type);
+
+ static lldb::BasicType GetBasicTypeEnumeration(ConstString name);
+
+ CompilerType
+ GetBuiltinTypeForDWARFEncodingAndBitSize(llvm::StringRef type_name,
+ uint32_t dw_ate, uint32_t bit_size);
+
+ CompilerType GetCStringType(bool is_const);
+
+ static clang::DeclContext *GetDeclContextForType(clang::QualType type);
+
+ static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
+
+ uint32_t GetPointerByteSize() override;
+
+ clang::TranslationUnitDecl *GetTranslationUnitDecl() {
+ return getASTContext().getTranslationUnitDecl();
+ }
+
+ static bool AreTypesSame(CompilerType type1, CompilerType type2,
+ bool ignore_qualifiers = false);
+
+ /// Creates a CompilerType form the given QualType with the current
+ /// TypeSystemClang instance as the CompilerType's typesystem.
+ /// \param qt The QualType for a type that belongs to the ASTContext of this
+ /// TypeSystemClang.
+ /// \return The CompilerType representing the given QualType. If the
+ /// QualType's type pointer is a nullptr then the function returns an
+ /// invalid CompilerType.
+ CompilerType GetType(clang::QualType qt) {
+ if (qt.getTypePtrOrNull() == nullptr)
+ return CompilerType();
+ // Check that the type actually belongs to this TypeSystemClang.
+ assert(qt->getAsTagDecl() == nullptr ||
+ &qt->getAsTagDecl()->getASTContext() == &getASTContext());
+ return CompilerType(this, qt.getAsOpaquePtr());
+ }
+
+ CompilerType GetTypeForDecl(clang::NamedDecl *decl);
+
+ CompilerType GetTypeForDecl(clang::TagDecl *decl);
+
+ CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl);
+
+ template <typename RecordDeclType>
+ CompilerType
+ GetTypeForIdentifier(ConstString type_name,
+ clang::DeclContext *decl_context = nullptr) {
+ CompilerType compiler_type;
+
+ if (type_name.GetLength()) {
+ clang::ASTContext &ast = getASTContext();
+ if (!decl_context)
+ decl_context = ast.getTranslationUnitDecl();
+
+ clang::IdentifierInfo &myIdent = ast.Idents.get(type_name.GetCString());
+ clang::DeclarationName myName =
+ ast.DeclarationNames.getIdentifier(&myIdent);
+
+ clang::DeclContext::lookup_result result = decl_context->lookup(myName);
+
+ if (!result.empty()) {
+ clang::NamedDecl *named_decl = result[0];
+ if (const RecordDeclType *record_decl =
+ llvm::dyn_cast<RecordDeclType>(named_decl))
+ compiler_type.SetCompilerType(
+ this, clang::QualType(record_decl->getTypeForDecl(), 0)
+ .getAsOpaquePtr());
+ }
+ }
+
+ return compiler_type;
+ }
+
+ CompilerType CreateStructForIdentifier(
+ ConstString type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed = false);
+
+ CompilerType GetOrCreateStructForIdentifier(
+ ConstString type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed = false);
+
+ static bool IsOperator(llvm::StringRef name,
+ clang::OverloadedOperatorKind &op_kind);
+
+ // Structure, Unions, Classes
+
+ static clang::AccessSpecifier
+ ConvertAccessTypeToAccessSpecifier(lldb::AccessType access);
+
+ static clang::AccessSpecifier
+ UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);
+
+ static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
+ bool omit_empty_base_classes);
+
+ /// Synthesize a clang::Module and return its ID or a default-constructed ID.
+ OptionalClangModuleID GetOrCreateClangModule(llvm::StringRef name,
+ OptionalClangModuleID parent,
+ bool is_framework = false,
+ bool is_explicit = false);
+
+ CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ lldb::AccessType access_type,
+ llvm::StringRef name, int kind,
+ lldb::LanguageType language,
+ ClangASTMetadata *metadata = nullptr,
+ bool exports_symbols = false);
+
+ class TemplateParameterInfos {
+ public:
+ bool IsValid() const {
+ if (args.empty())
+ return false;
+ return args.size() == names.size() &&
+ ((bool)pack_name == (bool)packed_args) &&
+ (!packed_args || !packed_args->packed_args);
+ }
+
+ llvm::SmallVector<const char *, 2> names;
+ llvm::SmallVector<clang::TemplateArgument, 2> args;
+
+ const char * pack_name = nullptr;
+ std::unique_ptr<TemplateParameterInfos> packed_args;
+ };
+
+ clang::FunctionTemplateDecl *
+ CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ clang::FunctionDecl *func_decl, const char *name,
+ const TemplateParameterInfos &infos);
+
+ void CreateFunctionTemplateSpecializationInfo(
+ clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template,
+ const TemplateParameterInfos &infos);
+
+ clang::ClassTemplateDecl *
+ CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ lldb::AccessType access_type, const char *class_name,
+ int kind, const TemplateParameterInfos &infos);
+
+ clang::TemplateTemplateParmDecl *
+ CreateTemplateTemplateParmDecl(const char *template_name);
+
+ clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ clang::ClassTemplateDecl *class_template_decl, int kind,
+ const TemplateParameterInfos &infos);
+
+ CompilerType
+ CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl *
+ class_template_specialization_decl);
+
+ static clang::DeclContext *
+ GetAsDeclContext(clang::FunctionDecl *function_decl);
+
+ static bool CheckOverloadedOperatorKindParameterCount(
+ bool is_method, clang::OverloadedOperatorKind op_kind,
+ uint32_t num_params);
+
+ bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size);
+
+ static bool RecordHasFields(const clang::RecordDecl *record_decl);
+
+ CompilerType CreateObjCClass(llvm::StringRef name,
+ clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ bool isForwardDecl, bool isInternal,
+ ClangASTMetadata *metadata = nullptr);
+
+ bool SetTagTypeKind(clang::QualType type, int kind) const;
+
+ bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
+ int default_accessibility,
+ int *assigned_accessibilities,
+ size_t num_assigned_accessibilities);
+
+ // Returns a mask containing bits from the TypeSystemClang::eTypeXXX
+ // enumerations
+
+ // Namespace Declarations
+
+ clang::NamespaceDecl *
+ GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ bool is_inline = false);
+
+ // Function Types
+
+ clang::FunctionDecl *
+ CreateFunctionDeclaration(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ const char *name, const CompilerType &function_Type,
+ int storage, bool is_inline);
+
+ CompilerType CreateFunctionType(const CompilerType &result_type,
+ const CompilerType *args, unsigned num_args,
+ bool is_variadic, unsigned type_quals,
+ clang::CallingConv cc);
+
+ CompilerType CreateFunctionType(const CompilerType &result_type,
+ const CompilerType *args, unsigned num_args,
+ bool is_variadic, unsigned type_quals) {
+ return CreateFunctionType(result_type, args, num_args, is_variadic,
+ type_quals, clang::CC_C);
+ }
+
+ clang::ParmVarDecl *
+ CreateParameterDeclaration(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ const char *name, const CompilerType &param_type,
+ int storage, bool add_decl = false);
+
+ void SetFunctionParameters(clang::FunctionDecl *function_decl,
+ clang::ParmVarDecl **params, unsigned num_params);
+
+ CompilerType CreateBlockPointerType(const CompilerType &function_type);
+
+ // Array Types
+
+ CompilerType CreateArrayType(const CompilerType &element_type,
+ size_t element_count, bool is_vector);
+
+ // Enumeration Types
+ CompilerType CreateEnumerationType(const char *name,
+ clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ const Declaration &decl,
+ const CompilerType &integer_qual_type,
+ bool is_scoped);
+
+ // Integer type functions
+
+ CompilerType GetIntTypeFromBitSize(size_t bit_size, bool is_signed);
+
+ CompilerType GetPointerSizedIntType(bool is_signed);
+
+ // Floating point functions
+
+ static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast,
+ size_t bit_size);
+
+ // TypeSystem methods
+ DWARFASTParser *GetDWARFParser() override;
+ PDBASTParser *GetPDBParser() override;
+
+ // TypeSystemClang callbacks for external source lookups.
+ void CompleteTagDecl(clang::TagDecl *);
+
+ void CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *);
+
+ bool LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets);
+
+ /// Creates a CompilerDecl from the given Decl with the current
+ /// TypeSystemClang instance as its typesystem.
+ /// The Decl has to come from the ASTContext of this
+ /// TypeSystemClang.
+ CompilerDecl GetCompilerDecl(clang::Decl *decl) {
+ assert(&decl->getASTContext() == &getASTContext() &&
+ "CreateCompilerDecl for Decl from wrong ASTContext?");
+ return CompilerDecl(this, decl);
+ }
+
+ // CompilerDecl override functions
+ ConstString DeclGetName(void *opaque_decl) override;
+
+ ConstString DeclGetMangledName(void *opaque_decl) override;
+
+ CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override;
+
+ CompilerType DeclGetFunctionReturnType(void *opaque_decl) override;
+
+ size_t DeclGetFunctionNumArguments(void *opaque_decl) override;
+
+ CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
+ size_t arg_idx) override;
+
+ CompilerType GetTypeForDecl(void *opaque_decl) override;
+
+ // CompilerDeclContext override functions
+
+ /// Creates a CompilerDeclContext from the given DeclContext
+ /// with the current TypeSystemClang instance as its typesystem.
+ /// The DeclContext has to come from the ASTContext of this
+ /// TypeSystemClang.
+ CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx);
+
+ /// Set the owning module for \p decl.
+ static void SetOwningModule(clang::Decl *decl,
+ OptionalClangModuleID owning_module);
+
+ std::vector<CompilerDecl>
+ DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
+ const bool ignore_using_decls) override;
+
+ ConstString DeclContextGetName(void *opaque_decl_ctx) override;
+
+ ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override;
+
+ bool DeclContextIsClassMethod(void *opaque_decl_ctx,
+ lldb::LanguageType *language_ptr,
+ bool *is_instance_method_ptr,
+ ConstString *language_object_name_ptr) override;
+
+ bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
+ void *other_opaque_decl_ctx) override;
+
+ // Clang specific clang::DeclContext functions
+
+ static clang::DeclContext *
+ DeclContextGetAsDeclContext(const CompilerDeclContext &dc);
+
+ static clang::ObjCMethodDecl *
+ DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc);
+
+ static clang::CXXMethodDecl *
+ DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc);
+
+ static clang::FunctionDecl *
+ DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc);
+
+ static clang::NamespaceDecl *
+ DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc);
+
+ static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc,
+ const clang::Decl *object);
+
+ static clang::ASTContext *
+ DeclContextGetTypeSystemClang(const CompilerDeclContext &dc);
+
+ // Tests
+
+#ifndef NDEBUG
+ bool Verify(lldb::opaque_compiler_type_t type) override;
+#endif
+
+ bool IsArrayType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type, uint64_t *size,
+ bool *is_incomplete) override;
+
+ bool IsVectorType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type, uint64_t *size) override;
+
+ bool IsAggregateType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsAnonymousType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsBeingDefined(lldb::opaque_compiler_type_t type) override;
+
+ bool IsCharType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsCompleteType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsConst(lldb::opaque_compiler_type_t type) override;
+
+ bool IsCStringType(lldb::opaque_compiler_type_t type,
+ uint32_t &length) override;
+
+ static bool IsCXXClassType(const CompilerType &type);
+
+ bool IsDefined(lldb::opaque_compiler_type_t type) override;
+
+ bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
+ bool &is_complex) override;
+
+ bool IsFunctionType(lldb::opaque_compiler_type_t type,
+ bool *is_variadic_ptr) override;
+
+ uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
+ CompilerType *base_type_ptr) override;
+
+ size_t
+ GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
+ const size_t index) override;
+
+ bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsBlockPointerType(lldb::opaque_compiler_type_t type,
+ CompilerType *function_pointer_type_ptr) override;
+
+ bool IsIntegerType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) override;
+
+ bool IsEnumerationType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) override;
+
+ static bool IsObjCClassType(const CompilerType &type);
+
+ static bool IsObjCClassTypeAndHasIVars(const CompilerType &type,
+ bool check_superclass);
+
+ static bool IsObjCObjectOrInterfaceType(const CompilerType &type);
+
+ static bool IsObjCObjectPointerType(const CompilerType &type,
+ CompilerType *target_type = nullptr);
+
+ bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;
+
+ static bool IsClassType(lldb::opaque_compiler_type_t type);
+
+ static bool IsEnumType(lldb::opaque_compiler_type_t type);
+
+ bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
+ CompilerType *target_type, // Can pass nullptr
+ bool check_cplusplus, bool check_objc) override;
+
+ bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsPointerType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type) override;
+
+ bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type) override;
+
+ bool IsReferenceType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type, bool *is_rvalue) override;
+
+ bool IsScalarType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsTypedefType(lldb::opaque_compiler_type_t type) override;
+
+ bool IsVoidType(lldb::opaque_compiler_type_t type) override;
+
+ bool CanPassInRegisters(const CompilerType &type) override;
+
+ bool SupportsLanguage(lldb::LanguageType language) override;
+
+ static llvm::Optional<std::string> GetCXXClassName(const CompilerType &type);
+
+ // Type Completion
+
+ bool GetCompleteType(lldb::opaque_compiler_type_t type) override;
+
+ // Accessors
+
+ ConstString GetTypeName(lldb::opaque_compiler_type_t type) override;
+
+ ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) override;
+
+ uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_or_element_compiler_type) override;
+
+ lldb::LanguageType
+ GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;
+
+ lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;
+
+ unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;
+
+ // Creating related types
+
+ /// Using the current type, create a new typedef to that type using
+ /// "typedef_name" as the name and "decl_ctx" as the decl context.
+ /// \param payload is an opaque TypePayloadClang.
+ static CompilerType
+ CreateTypedefType(const CompilerType &type, const char *typedef_name,
+ const CompilerDeclContext &compiler_decl_ctx,
+ uint32_t opaque_payload);
+
+ CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
+ uint64_t *stride) override;
+
+ CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
+ uint64_t size) override;
+
+ CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
+
+ // Returns -1 if this isn't a function of if the function doesn't have a
+ // prototype Returns a value >= 0 if there is a prototype.
+ int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx) override;
+
+ CompilerType
+ GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;
+
+ size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;
+
+ TypeMemberFunctionImpl
+ GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx) override;
+
+ CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetLValueReferenceType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType
+ GetRValueReferenceType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetAtomicType(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
+ const char *name,
+ const CompilerDeclContext &decl_ctx,
+ uint32_t opaque_payload) override;
+
+ // If the current object represents a typedef type, get the underlying type
+ CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;
+
+ // Create related types using the current type's AST
+ CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;
+
+ // Exploring the type
+
+ const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override;
+
+ llvm::Optional<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) {
+ if (llvm::Optional<uint64_t> bit_size = GetBitSize(type, exe_scope))
+ return (*bit_size + 7) / 8;
+ return llvm::None;
+ }
+
+ llvm::Optional<uint64_t>
+ GetBitSize(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) override;
+
+ lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type,
+ uint64_t &count) override;
+
+ lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override;
+
+ llvm::Optional<size_t>
+ GetTypeBitAlign(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) override;
+
+ uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
+ bool omit_empty_base_classes,
+ const ExecutionContext *exe_ctx) override;
+
+ CompilerType GetBuiltinTypeByName(ConstString name) override;
+
+ lldb::BasicType
+ GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
+
+ static lldb::BasicType
+ GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type,
+ ConstString name);
+
+ void ForEachEnumerator(
+ lldb::opaque_compiler_type_t type,
+ std::function<bool(const CompilerType &integer_type,
+ ConstString name,
+ const llvm::APSInt &value)> const &callback) override;
+
+ uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
+ std::string &name, uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) override;
+
+ uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;
+
+ uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override;
+
+ CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx,
+ uint32_t *bit_offset_ptr) override;
+
+ CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx,
+ uint32_t *bit_offset_ptr) override;
+
+ static uint32_t GetNumPointeeChildren(clang::QualType type);
+
+ CompilerType GetChildCompilerTypeAtIndex(
+ lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+ bool transparent_pointers, bool omit_empty_base_classes,
+ bool ignore_array_bounds, std::string &child_name,
+ uint32_t &child_byte_size, int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class, bool &child_is_deref_of_parent,
+ ValueObject *valobj, uint64_t &language_flags) override;
+
+ // Lookup a child given a name. This function will match base class names and
+ // member member names in "clang_type" only, not descendants.
+ uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
+ const char *name,
+ bool omit_empty_base_classes) override;
+
+ // Lookup a child member given a name. This function will match member names
+ // only and will descend into "clang_type" children in search for the first
+ // member in this class, or any base class that matches "name".
+ // TODO: Return all matches for a given name by returning a
+ // vector<vector<uint32_t>>
+ // so we catch all names that match a given child name, not just the first.
+ size_t
+ GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
+ const char *name, bool omit_empty_base_classes,
+ std::vector<uint32_t> &child_indexes) override;
+
+ size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
+
+ lldb::TemplateArgumentKind
+ GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
+ size_t idx) override;
+ CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) override;
+ llvm::Optional<CompilerType::IntegralTemplateArgument>
+ GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
+ size_t idx) override;
+
+ CompilerType GetTypeForFormatters(void *type) override;
+
+#define LLDB_INVALID_DECL_LEVEL UINT32_MAX
+ // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx
+ // could not be found in decl_ctx.
+ uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx,
+ clang::DeclContext *child_decl_ctx,
+ ConstString *child_name = nullptr,
+ CompilerType *child_type = nullptr);
+
+ // Modifying RecordType
+ static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type,
+ llvm::StringRef name,
+ const CompilerType &field_type,
+ lldb::AccessType access,
+ uint32_t bitfield_bit_size);
+
+ static void BuildIndirectFields(const CompilerType &type);
+
+ static void SetIsPacked(const CompilerType &type);
+
+ static clang::VarDecl *AddVariableToRecordType(const CompilerType &type,
+ llvm::StringRef name,
+ const CompilerType &var_type,
+ lldb::AccessType access);
+
+ /// Initializes a variable with an integer value.
+ /// \param var The variable to initialize. Must not already have an
+ /// initializer and must have an integer or enum type.
+ /// \param init_value The integer value that the variable should be
+ /// initialized to. Has to match the bit width of the
+ /// variable type.
+ static void SetIntegerInitializerForVariable(clang::VarDecl *var,
+ const llvm::APInt &init_value);
+
+ /// Initializes a variable with a floating point value.
+ /// \param var The variable to initialize. Must not already have an
+ /// initializer and must have a floating point type.
+ /// \param init_value The float value that the variable should be
+ /// initialized to.
+ static void
+ SetFloatingInitializerForVariable(clang::VarDecl *var,
+ const llvm::APFloat &init_value);
+
+ clang::CXXMethodDecl *AddMethodToCXXRecordType(
+ lldb::opaque_compiler_type_t type, llvm::StringRef name,
+ const char *mangled_name, const CompilerType &method_type,
+ lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
+ bool is_explicit, bool is_attr_used, bool is_artificial);
+
+ void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type);
+
+ // C++ Base Classes
+ std::unique_ptr<clang::CXXBaseSpecifier>
+ CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
+ lldb::AccessType access, bool is_virtual,
+ bool base_of_class);
+
+ bool TransferBaseClasses(
+ lldb::opaque_compiler_type_t type,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases);
+
+ static bool SetObjCSuperClass(const CompilerType &type,
+ const CompilerType &superclass_compiler_type);
+
+ static bool AddObjCClassProperty(const CompilerType &type,
+ const char *property_name,
+ const CompilerType &property_compiler_type,
+ clang::ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name,
+ const char *property_getter_name,
+ uint32_t property_attributes,
+ ClangASTMetadata *metadata);
+
+ static clang::ObjCMethodDecl *AddMethodToObjCObjectType(
+ const CompilerType &type,
+ const char *name, // the full symbol name as seen in the symbol table
+ // (lldb::opaque_compiler_type_t type, "-[NString
+ // stringWithCString:]")
+ const CompilerType &method_compiler_type, lldb::AccessType access,
+ bool is_artificial, bool is_variadic, bool is_objc_direct_call);
+
+ static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
+ bool has_extern);
+
+ // Tag Declarations
+ static bool StartTagDeclarationDefinition(const CompilerType &type);
+
+ static bool CompleteTagDeclarationDefinition(const CompilerType &type);
+
+ // Modifying Enumeration types
+ clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ int64_t enum_value, uint32_t enum_value_bit_size);
+ clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
+ const CompilerType &enum_type, const Declaration &decl, const char *name,
+ const llvm::APSInt &value);
+
+ /// Returns the underlying integer type for an enum type. If the given type
+ /// is invalid or not an enum-type, the function returns an invalid
+ /// CompilerType.
+ CompilerType GetEnumerationIntegerType(CompilerType type);
+
+ // Pointers & References
+
+ // Call this function using the class type when you want to make a member
+ // pointer type to pointee_type.
+ static CompilerType CreateMemberPointerType(const CompilerType &type,
+ const CompilerType &pointee_type);
+
+ // Dumping types
+#ifndef NDEBUG
+ /// Convenience LLVM-style dump method for use in the debugger only.
+ /// In contrast to the other \p Dump() methods this directly invokes
+ /// \p clang::QualType::dump().
+ LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override;
+#endif
+
+ void Dump(Stream &s);
+
+ /// Dump clang AST types from the symbol file.
+ ///
+ /// \param[in] s
+ /// A stream to send the dumped AST node(s) to
+ /// \param[in] symbol_name
+ /// The name of the symbol to dump, if it is empty dump all the symbols
+ void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name);
+
+ void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
+ Stream *s, lldb::Format format, const DataExtractor &data,
+ lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+ bool show_types, bool show_summary, bool verbose,
+ uint32_t depth) override;
+
+ bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
+ lldb::Format format, const DataExtractor &data,
+ lldb::offset_t data_offset, size_t data_byte_size,
+ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope) override;
+
+ void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
+ Stream *s, const DataExtractor &data,
+ lldb::offset_t data_offset, size_t data_byte_size) override;
+
+ void DumpTypeDescription(
+ lldb::opaque_compiler_type_t type,
+ lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override;
+
+ void DumpTypeDescription(
+ lldb::opaque_compiler_type_t type, Stream *s,
+ lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override;
+
+ static void DumpTypeName(const CompilerType &type);
+
+ static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type);
+
+ static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type);
+
+ static clang::TagDecl *GetAsTagDecl(const CompilerType &type);
+
+ static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type);
+
+ static clang::CXXRecordDecl *
+ GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type);
+
+ static clang::ObjCInterfaceDecl *
+ GetAsObjCInterfaceDecl(const CompilerType &type);
+
+ clang::ClassTemplateDecl *ParseClassTemplateDecl(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
+ const TypeSystemClang::TemplateParameterInfos &template_param_infos);
+
+ clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx,
+ OptionalClangModuleID owning_module);
+
+ clang::UsingDirectiveDecl *
+ CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
+ OptionalClangModuleID owning_module,
+ clang::NamespaceDecl *ns_decl);
+
+ clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+ OptionalClangModuleID owning_module,
+ clang::NamedDecl *target);
+
+ clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
+ OptionalClangModuleID owning_module,
+ const char *name,
+ clang::QualType type);
+
+ static lldb::opaque_compiler_type_t
+ GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type);
+
+ static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return clang::QualType::getFromOpaquePtr(type);
+ return clang::QualType();
+ }
+
+ static clang::QualType
+ GetCanonicalQualType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return clang::QualType::getFromOpaquePtr(type).getCanonicalType();
+ return clang::QualType();
+ }
+
+ clang::DeclarationName
+ GetDeclarationName(const char *name, const CompilerType &function_clang_type);
+
+ clang::LangOptions *GetLangOpts() const {
+ return m_language_options_up.get();
+ }
+ clang::SourceManager *GetSourceMgr() const {
+ return m_source_manager_up.get();
+ }
+
+private:
+ const clang::ClassTemplateSpecializationDecl *
+ GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
+
+ // Classes that inherit from TypeSystemClang can see and modify these
+ std::string m_target_triple;
+ std::unique_ptr<clang::ASTContext> m_ast_up;
+ std::unique_ptr<clang::LangOptions> m_language_options_up;
+ std::unique_ptr<clang::FileManager> m_file_manager_up;
+ std::unique_ptr<clang::SourceManager> m_source_manager_up;
+ std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up;
+ std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up;
+ std::shared_ptr<clang::TargetOptions> m_target_options_rp;
+ std::unique_ptr<clang::TargetInfo> m_target_info_up;
+ std::unique_ptr<clang::IdentifierTable> m_identifier_table_up;
+ std::unique_ptr<clang::SelectorTable> m_selector_table_up;
+ std::unique_ptr<clang::Builtin::Context> m_builtins_up;
+ std::unique_ptr<clang::HeaderSearch> m_header_search_up;
+ std::unique_ptr<clang::ModuleMap> m_module_map_up;
+ std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
+ std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
+ std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
+ uint32_t m_pointer_byte_size = 0;
+ bool m_ast_owned = false;
+ /// A string describing what this TypeSystemClang represents (e.g.,
+ /// AST for debug information, an expression, some other utility ClangAST).
+ /// Useful for logging and debugging.
+ std::string m_display_name;
+
+ typedef llvm::DenseMap<const clang::Decl *, ClangASTMetadata> DeclMetadataMap;
+ /// Maps Decls to their associated ClangASTMetadata.
+ DeclMetadataMap m_decl_metadata;
+
+ typedef llvm::DenseMap<const clang::Type *, ClangASTMetadata> TypeMetadataMap;
+ /// Maps Types to their associated ClangASTMetadata.
+ TypeMetadataMap m_type_metadata;
+
+ /// The sema associated that is currently used to build this ASTContext.
+ /// May be null if we are already done parsing this ASTContext or the
+ /// ASTContext wasn't created by parsing source code.
+ clang::Sema *m_sema = nullptr;
+
+ // For TypeSystemClang only
+ TypeSystemClang(const TypeSystemClang &);
+ const TypeSystemClang &operator=(const TypeSystemClang &);
+ /// Creates the internal ASTContext.
+ void CreateASTContext();
+ void SetTargetTriple(llvm::StringRef target_triple);
+};
+
+/// The TypeSystemClang instance used for the scratch ASTContext in a
+/// lldb::Target.
+class TypeSystemClangForExpressions : public TypeSystemClang {
+public:
+ TypeSystemClangForExpressions(Target &target, llvm::Triple triple);
+
+ ~TypeSystemClangForExpressions() override = default;
+
+ void Finalize() override;
+
+ UserExpression *
+ GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
+ lldb::LanguageType language,
+ Expression::ResultType desired_type,
+ const EvaluateExpressionOptions &options,
+ ValueObject *ctx_obj) override;
+
+ FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
+ const Address &function_address,
+ const ValueList &arg_value_list,
+ const char *name) override;
+
+ UtilityFunction *GetUtilityFunction(const char *text,
+ const char *name) override;
+
+ PersistentExpressionState *GetPersistentExpressionState() override;
+private:
+ lldb::TargetWP m_target_wp;
+ std::unique_ptr<ClangPersistentVariables>
+ m_persistent_variables; // These are the persistent variables associated
+ // with this process for the expression parser
+ std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 4aa9fb634b61..1bc071c2b161 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -1,4 +1,4 @@
-//===-- UnwindAssemblyInstEmulation.cpp --------------------------*- C++-*-===//
+//===-- UnwindAssemblyInstEmulation.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -28,6 +28,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE(UnwindAssemblyInstEmulation)
+
// UnwindAssemblyInstEmulation method definitions
bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
@@ -123,18 +125,12 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
// Add the initial state to the save list with offset 0.
saved_unwind_states.insert({0, {last_row, m_register_values}});
- // cache the pc register number (in whatever register numbering this
- // UnwindPlan uses) for quick reference during instruction parsing.
- RegisterInfo pc_reg_info;
- m_inst_emulator_up->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info);
-
- // cache the return address register number (in whatever register
+ // cache the stack pointer register number (in whatever register
// numbering this UnwindPlan uses) for quick reference during
// instruction parsing.
- RegisterInfo ra_reg_info;
+ RegisterInfo sp_reg_info;
m_inst_emulator_up->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info);
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp_reg_info);
// The architecture dependent condition code of the last processed
// instruction.
@@ -165,6 +161,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
*newrow = *it->second.first;
m_curr_row.reset(newrow);
m_register_values = it->second.second;
+ // re-set the CFA register ivars to match the
+ // new m_curr_row.
+ if (sp_reg_info.name &&
+ m_curr_row->GetCFAValue().IsRegisterPlusOffset()) {
+ uint32_t row_cfa_regnum =
+ m_curr_row->GetCFAValue().GetRegisterNumber();
+ lldb::RegisterKind row_kind =
+ m_unwind_plan_ptr->GetRegisterKind();
+ // set m_cfa_reg_info to the row's CFA reg.
+ m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum,
+ m_cfa_reg_info);
+ // set m_fp_is_cfa.
+ if (sp_reg_info.kinds[row_kind] == row_cfa_regnum)
+ m_fp_is_cfa = false;
+ else
+ m_fp_is_cfa = true;
+ }
}
m_inst_emulator_up->SetInstruction(inst->GetOpcode(),
@@ -195,6 +208,23 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
std::make_shared<UnwindPlan::Row>(*saved_state.first);
m_curr_row->SetOffset(current_offset);
m_register_values = saved_state.second;
+ // re-set the CFA register ivars to match the
+ // new m_curr_row.
+ if (sp_reg_info.name &&
+ m_curr_row->GetCFAValue().IsRegisterPlusOffset()) {
+ uint32_t row_cfa_regnum =
+ m_curr_row->GetCFAValue().GetRegisterNumber();
+ lldb::RegisterKind row_kind =
+ m_unwind_plan_ptr->GetRegisterKind();
+ // set m_cfa_reg_info to the row's CFA reg.
+ m_inst_emulator_up->GetRegisterInfo(row_kind, row_cfa_regnum,
+ m_cfa_reg_info);
+ // set m_fp_is_cfa.
+ if (sp_reg_info.kinds[row_kind] == row_cfa_regnum)
+ m_fp_is_cfa = false;
+ else
+ m_fp_is_cfa = true;
+ }
bool replace_existing =
true; // The last instruction might already
// created a row for this offset and
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
index 9125bd5b1fe3..5784a42a8269 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_UnwindAssemblyInstEmulation_h_
-#define liblldb_UnwindAssemblyInstEmulation_h_
+#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H
+#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -151,4 +151,4 @@ private:
uint32_t m_forward_branch_offset;
};
-#endif // liblldb_UnwindAssemblyInstEmulation_h_
+#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index ce168f021047..fe1275d5b0cf 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -1,4 +1,4 @@
-//===-- UnwindAssembly-x86.cpp ----------------------------------*- C++ -*-===//
+//===-- UnwindAssembly-x86.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -30,6 +30,8 @@
using namespace lldb;
using namespace lldb_private;
+LLDB_PLUGIN_DEFINE_ADV(UnwindAssembly_x86, UnwindAssemblyX86)
+
// UnwindAssemblyParser_x86 method definitions
UnwindAssembly_x86::UnwindAssembly_x86(const ArchSpec &arch)
@@ -139,7 +141,7 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
// and we don't need to modify it at all.
if (first_row_pc_loc.GetOffset() == -wordsize) {
- do_augment_unwindplan = false;
+ return true;
}
}
}
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
index 7c198bbc33af..3e1588f2065c 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
+++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_UnwindAssembly_x86_h_
-#define liblldb_UnwindAssembly_x86_h_
+#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H
+#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H
#include "x86AssemblyInspectionEngine.h"
@@ -62,4 +62,4 @@ private:
lldb_private::x86AssemblyInspectionEngine *m_assembly_inspection_engine;
};
-#endif // liblldb_UnwindAssembly_x86_h_
+#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_UNWINDASSEMBLY_X86_H
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index bf6f60a2d26c..36e7b90cad24 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -1,4 +1,4 @@
-//===-- x86AssemblyInspectionEngine.cpp -------------------------*- C++ -*-===//
+//===-- x86AssemblyInspectionEngine.cpp -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index 680598abdeff..f39dce1afaa6 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_x86AssemblyInspectionEngine_h_
-#define liblldb_x86AssemblyInspectionEngine_h_
+#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H
+#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H
#include "llvm-c/Disassembler.h"
@@ -191,9 +191,11 @@ private:
::LLVMDisasmContextRef m_disasm_context;
- DISALLOW_COPY_AND_ASSIGN(x86AssemblyInspectionEngine);
+ x86AssemblyInspectionEngine(const x86AssemblyInspectionEngine &) = delete;
+ const x86AssemblyInspectionEngine &
+ operator=(const x86AssemblyInspectionEngine &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_x86AssemblyInspectionEngine_h_
+#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H