aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
commitead246455adf1a215ec2715dad6533073a6beb4e (patch)
treef3f97a47d77053bf96fe74cdbd6fae74380e8a92
parentfdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff)
downloadsrc-vendor/lldb.tar.gz
src-vendor/lldb.zip
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes: svn path=/vendor/lldb/dist/; revision=353952 svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
-rw-r--r--docs/lldb.12
-rw-r--r--include/lldb/API/LLDB.h3
-rw-r--r--include/lldb/API/SBCommandReturnObject.h52
-rw-r--r--include/lldb/API/SBDebugger.h27
-rw-r--r--include/lldb/API/SBDefines.h1
-rw-r--r--include/lldb/API/SBError.h1
-rw-r--r--include/lldb/API/SBFile.h47
-rw-r--r--include/lldb/API/SBInstruction.h4
-rw-r--r--include/lldb/API/SBInstructionList.h6
-rw-r--r--include/lldb/API/SBProcess.h4
-rw-r--r--include/lldb/API/SBStream.h4
-rw-r--r--include/lldb/API/SBStructuredData.h2
-rw-r--r--include/lldb/API/SBThread.h4
-rw-r--r--include/lldb/API/SBThreadPlan.h6
-rw-r--r--include/lldb/Breakpoint/BreakpointLocation.h2
-rw-r--r--include/lldb/Breakpoint/BreakpointOptions.h45
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverAddress.h4
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileLine.h4
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileRegex.h6
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverName.h6
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverScripted.h7
-rw-r--r--include/lldb/Core/Address.h17
-rw-r--r--include/lldb/Core/AddressResolverFileLine.h4
-rw-r--r--include/lldb/Core/AddressResolverName.h6
-rw-r--r--include/lldb/Core/Debugger.h43
-rw-r--r--include/lldb/Core/FileLineResolver.h4
-rw-r--r--include/lldb/Core/FileSpecList.h17
-rw-r--r--include/lldb/Core/FormatEntity.h2
-rw-r--r--include/lldb/Core/IOHandler.h35
-rw-r--r--include/lldb/Core/LoadedModuleInfoList.h3
-rw-r--r--include/lldb/Core/Mangled.h22
-rw-r--r--include/lldb/Core/Module.h156
-rw-r--r--include/lldb/Core/ModuleList.h79
-rw-r--r--include/lldb/Core/ModuleSpec.h5
-rw-r--r--include/lldb/Core/PluginManager.h47
-rw-r--r--include/lldb/Core/PropertiesBase.td49
-rw-r--r--include/lldb/Core/SearchFilter.h4
-rw-r--r--include/lldb/Core/Section.h5
-rw-r--r--include/lldb/Core/StreamFile.h12
-rw-r--r--include/lldb/Core/StructuredDataImpl.h3
-rw-r--r--include/lldb/Core/Value.h1
-rw-r--r--include/lldb/Core/dwarf.h2
-rw-r--r--include/lldb/DataFormatters/FormattersContainer.h123
-rw-r--r--include/lldb/DataFormatters/StringPrinter.h237
-rw-r--r--include/lldb/DataFormatters/TypeCategory.h2
-rw-r--r--include/lldb/Expression/DWARFExpression.h22
-rw-r--r--include/lldb/Expression/DiagnosticManager.h40
-rw-r--r--include/lldb/Expression/ExpressionSourceCode.h17
-rw-r--r--include/lldb/Expression/LLVMUserExpression.h16
-rw-r--r--include/lldb/Expression/Materializer.h2
-rw-r--r--include/lldb/Expression/REPL.h6
-rw-r--r--include/lldb/Host/Config.h.cmake4
-rw-r--r--include/lldb/Host/Editline.h7
-rw-r--r--include/lldb/Host/File.h358
-rw-r--r--include/lldb/Host/FileCache.h5
-rw-r--r--include/lldb/Host/FileSystem.h17
-rw-r--r--include/lldb/Host/LZMA.h34
-rw-r--r--include/lldb/Host/Socket.h3
-rw-r--r--include/lldb/Host/common/NativeProcessProtocol.h41
-rw-r--r--include/lldb/Interpreter/CommandAlias.h8
-rw-r--r--include/lldb/Interpreter/CommandCompletions.h87
-rw-r--r--include/lldb/Interpreter/CommandInterpreter.h35
-rw-r--r--include/lldb/Interpreter/CommandObject.h33
-rw-r--r--include/lldb/Interpreter/CommandObjectMultiword.h10
-rw-r--r--include/lldb/Interpreter/CommandObjectRegexCommand.h2
-rw-r--r--include/lldb/Interpreter/CommandReturnObject.h24
-rw-r--r--include/lldb/Interpreter/OptionGroupPythonClassWithDict.h65
-rw-r--r--include/lldb/Interpreter/OptionValue.h4
-rw-r--r--include/lldb/Interpreter/OptionValueArch.h4
-rw-r--r--include/lldb/Interpreter/OptionValueBoolean.h4
-rw-r--r--include/lldb/Interpreter/OptionValueEnumeration.h4
-rw-r--r--include/lldb/Interpreter/OptionValueFileSpec.h4
-rw-r--r--include/lldb/Interpreter/OptionValueFormatEntity.h4
-rw-r--r--include/lldb/Interpreter/OptionValueRegex.h6
-rw-r--r--include/lldb/Interpreter/OptionValueUUID.h4
-rw-r--r--include/lldb/Interpreter/Options.h9
-rw-r--r--include/lldb/Interpreter/ScriptInterpreter.h7
-rw-r--r--include/lldb/Symbol/CallFrameInfo.h28
-rw-r--r--include/lldb/Symbol/ClangASTContext.h132
-rw-r--r--include/lldb/Symbol/ClangASTImporter.h58
-rw-r--r--include/lldb/Symbol/CompileUnit.h10
-rw-r--r--include/lldb/Symbol/CompilerType.h13
-rw-r--r--include/lldb/Symbol/DeclVendor.h24
-rw-r--r--include/lldb/Symbol/FuncUnwinders.h9
-rw-r--r--include/lldb/Symbol/Function.h31
-rw-r--r--include/lldb/Symbol/ObjectFile.h46
-rw-r--r--include/lldb/Symbol/PostfixExpression.h6
-rw-r--r--include/lldb/Symbol/Symbol.h5
-rw-r--r--include/lldb/Symbol/SymbolContext.h2
-rw-r--r--include/lldb/Symbol/SymbolFile.h97
-rw-r--r--include/lldb/Symbol/SymbolVendor.h108
-rw-r--r--include/lldb/Symbol/Symtab.h22
-rw-r--r--include/lldb/Symbol/Type.h21
-rw-r--r--include/lldb/Symbol/TypeList.h5
-rw-r--r--include/lldb/Symbol/TypeSystem.h51
-rw-r--r--include/lldb/Symbol/UnwindPlan.h35
-rw-r--r--include/lldb/Symbol/UnwindTable.h3
-rw-r--r--include/lldb/Symbol/Variable.h79
-rw-r--r--include/lldb/Symbol/VerifyDecl.h18
-rw-r--r--include/lldb/Target/ABI.h18
-rw-r--r--include/lldb/Target/DynamicLoader.h10
-rw-r--r--include/lldb/Target/Language.h10
-rw-r--r--include/lldb/Target/Platform.h19
-rw-r--r--include/lldb/Target/Process.h28
-rw-r--r--include/lldb/Target/RemoteAwarePlatform.h2
-rw-r--r--include/lldb/Target/StackFrame.h15
-rw-r--r--include/lldb/Target/StopInfo.h11
-rw-r--r--include/lldb/Target/Target.h129
-rw-r--r--include/lldb/Target/Thread.h12
-rw-r--r--include/lldb/Target/ThreadPlanPython.h10
-rw-r--r--include/lldb/Target/Unwind.h10
-rw-r--r--include/lldb/Utility/AnsiTerminal.h4
-rw-r--r--include/lldb/Utility/ArchSpec.h5
-rw-r--r--include/lldb/Utility/Args.h35
-rw-r--r--include/lldb/Utility/CleanUp.h42
-rw-r--r--include/lldb/Utility/CompletionRequest.h128
-rw-r--r--include/lldb/Utility/ConstString.h48
-rw-r--r--include/lldb/Utility/DataEncoder.h24
-rw-r--r--include/lldb/Utility/DataExtractor.h54
-rw-r--r--include/lldb/Utility/FileCollector.h77
-rw-r--r--include/lldb/Utility/FileSpec.h37
-rw-r--r--include/lldb/Utility/Flags.h26
-rw-r--r--include/lldb/Utility/GDBRemote.h117
-rw-r--r--include/lldb/Utility/IOObject.h5
-rw-r--r--include/lldb/Utility/JSON.h283
-rw-r--r--include/lldb/Utility/Log.h48
-rw-r--r--include/lldb/Utility/Logging.h2
-rw-r--r--include/lldb/Utility/Predicate.h10
-rw-r--r--include/lldb/Utility/ProcessInfo.h22
-rw-r--r--include/lldb/Utility/RangeMap.h14
-rw-r--r--include/lldb/Utility/RegularExpression.h187
-rw-r--r--include/lldb/Utility/Reproducer.h99
-rw-r--r--include/lldb/Utility/ReproducerInstrumentation.h36
-rw-r--r--include/lldb/Utility/Scalar.h28
-rw-r--r--include/lldb/Utility/Status.h22
-rw-r--r--include/lldb/Utility/Stream.h2
-rw-r--r--include/lldb/Utility/StreamGDBRemote.h45
-rw-r--r--include/lldb/Utility/StringExtractor.h21
-rw-r--r--include/lldb/Utility/StringLexer.h4
-rw-r--r--include/lldb/Utility/StringList.h22
-rw-r--r--include/lldb/Utility/StructuredData.h27
-rw-r--r--include/lldb/Utility/UUID.h24
-rw-r--r--include/lldb/lldb-enumerations.h579
-rw-r--r--include/lldb/lldb-forward.h2
-rw-r--r--include/lldb/lldb-private-enumerations.h28
-rw-r--r--include/lldb/lldb-private-interfaces.h7
-rw-r--r--source/API/SBAddress.cpp8
-rw-r--r--source/API/SBBreakpointOptionCommon.cpp2
-rw-r--r--source/API/SBCommandInterpreter.cpp57
-rw-r--r--source/API/SBCommandReturnObject.cpp304
-rw-r--r--source/API/SBCompileUnit.cpp9
-rw-r--r--source/API/SBDebugger.cpp432
-rw-r--r--source/API/SBDeclaration.cpp2
-rw-r--r--source/API/SBFile.cpp129
-rw-r--r--source/API/SBFrame.cpp10
-rw-r--r--source/API/SBInstruction.cpp22
-rw-r--r--source/API/SBInstructionList.cpp32
-rw-r--r--source/API/SBLineEntry.cpp4
-rw-r--r--source/API/SBModule.cpp101
-rw-r--r--source/API/SBProcess.cpp34
-rw-r--r--source/API/SBReproducer.cpp1
-rw-r--r--source/API/SBReproducerPrivate.h2
-rw-r--r--source/API/SBStream.cpp73
-rw-r--r--source/API/SBStringList.cpp2
-rw-r--r--source/API/SBSymbolContext.cpp4
-rw-r--r--source/API/SBTarget.cpp103
-rw-r--r--source/API/SBThread.cpp25
-rw-r--r--source/API/SBThreadPlan.cpp51
-rw-r--r--source/API/SBType.cpp2
-rw-r--r--source/API/SBTypeCategory.cpp16
-rw-r--r--source/API/SystemInitializerFull.cpp67
-rw-r--r--source/API/Utils.h2
-rw-r--r--source/Breakpoint/Breakpoint.cpp21
-rw-r--r--source/Breakpoint/BreakpointIDList.cpp10
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp13
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp2
-rw-r--r--source/Breakpoint/BreakpointResolver.cpp23
-rw-r--r--source/Breakpoint/BreakpointResolverAddress.cpp9
-rw-r--r--source/Breakpoint/BreakpointResolverFileLine.cpp6
-rw-r--r--source/Breakpoint/BreakpointResolverFileRegex.cpp15
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp22
-rw-r--r--source/Breakpoint/BreakpointResolverScripted.cpp52
-rw-r--r--source/Breakpoint/Watchpoint.cpp17
-rw-r--r--source/Breakpoint/WatchpointOptions.cpp5
-rw-r--r--source/Commands/CommandCompletions.cpp178
-rw-r--r--source/Commands/CommandObjectApropos.cpp12
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp578
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp115
-rw-r--r--source/Commands/CommandObjectBugreport.cpp124
-rw-r--r--source/Commands/CommandObjectBugreport.h27
-rw-r--r--source/Commands/CommandObjectCommands.cpp164
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp45
-rw-r--r--source/Commands/CommandObjectExpression.cpp265
-rw-r--r--source/Commands/CommandObjectExpression.h2
-rw-r--r--source/Commands/CommandObjectFrame.cpp95
-rw-r--r--source/Commands/CommandObjectGUI.cpp7
-rw-r--r--source/Commands/CommandObjectHelp.cpp35
-rw-r--r--source/Commands/CommandObjectHelp.h6
-rw-r--r--source/Commands/CommandObjectLog.cpp68
-rw-r--r--source/Commands/CommandObjectMemory.cpp130
-rw-r--r--source/Commands/CommandObjectMultiword.cpp68
-rw-r--r--source/Commands/CommandObjectPlatform.cpp175
-rw-r--r--source/Commands/CommandObjectPlugin.cpp9
-rw-r--r--source/Commands/CommandObjectProcess.cpp160
-rw-r--r--source/Commands/CommandObjectRegister.cpp20
-rw-r--r--source/Commands/CommandObjectReproducer.cpp285
-rw-r--r--source/Commands/CommandObjectSettings.cpp201
-rw-r--r--source/Commands/CommandObjectSource.cpp92
-rw-r--r--source/Commands/CommandObjectStats.cpp16
-rw-r--r--source/Commands/CommandObjectTarget.cpp2122
-rw-r--r--source/Commands/CommandObjectThread.cpp304
-rw-r--r--source/Commands/CommandObjectType.cpp179
-rw-r--r--source/Commands/CommandObjectWatchpoint.cpp71
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp74
-rw-r--r--source/Commands/Options.td819
-rw-r--r--source/Commands/OptionsBase.td20
-rw-r--r--source/Core/Address.cpp55
-rw-r--r--source/Core/AddressResolverFileLine.cpp17
-rw-r--r--source/Core/AddressResolverName.cpp15
-rw-r--r--source/Core/Communication.cpp55
-rw-r--r--source/Core/CoreProperties.td118
-rw-r--r--source/Core/Debugger.cpp488
-rw-r--r--source/Core/Disassembler.cpp239
-rw-r--r--source/Core/DumpDataExtractor.cpp96
-rw-r--r--source/Core/FileLineResolver.cpp2
-rw-r--r--source/Core/FormatEntity.cpp143
-rw-r--r--source/Core/Highlighter.cpp5
-rw-r--r--source/Core/IOHandler.cpp332
-rw-r--r--source/Core/Mangled.cpp72
-rw-r--r--source/Core/Module.cpp349
-rw-r--r--source/Core/ModuleList.cpp207
-rw-r--r--source/Core/PluginManager.cpp96
-rw-r--r--source/Core/SearchFilter.cpp37
-rw-r--r--source/Core/Section.cpp6
-rw-r--r--source/Core/SourceManager.cpp8
-rw-r--r--source/Core/StreamFile.cpp55
-rw-r--r--source/Core/Value.cpp11
-rw-r--r--source/Core/ValueObject.cpp44
-rw-r--r--source/Core/ValueObjectCast.cpp2
-rw-r--r--source/Core/ValueObjectChild.cpp26
-rw-r--r--source/Core/ValueObjectConstResult.cpp2
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp8
-rw-r--r--source/Core/ValueObjectMemory.cpp4
-rw-r--r--source/Core/ValueObjectRegister.cpp21
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp118
-rw-r--r--source/Core/ValueObjectVariable.cpp4
-rw-r--r--source/DataFormatters/FormatManager.cpp180
-rw-r--r--source/DataFormatters/FormattersHelpers.cpp42
-rw-r--r--source/DataFormatters/TypeCategoryMap.cpp56
-rw-r--r--source/DataFormatters/TypeFormat.cpp2
-rw-r--r--source/DataFormatters/ValueObjectPrinter.cpp30
-rw-r--r--source/DataFormatters/VectorType.cpp22
-rw-r--r--source/Expression/DWARFExpression.cpp800
-rw-r--r--source/Expression/DiagnosticManager.cpp18
-rw-r--r--source/Expression/ExpressionVariable.cpp18
-rw-r--r--source/Expression/FunctionCaller.cpp42
-rw-r--r--source/Expression/IRExecutionUnit.cpp97
-rw-r--r--source/Expression/IRInterpreter.cpp309
-rw-r--r--source/Expression/IRMemoryMap.cpp64
-rw-r--r--source/Expression/LLVMUserExpression.cpp23
-rw-r--r--source/Expression/Materializer.cpp140
-rw-r--r--source/Expression/REPL.cpp87
-rw-r--r--source/Expression/UserExpression.cpp43
-rw-r--r--source/Expression/UtilityFunction.cpp2
-rw-r--r--source/Host/common/Editline.cpp172
-rw-r--r--source/Host/common/File.cpp410
-rw-r--r--source/Host/common/FileCache.cpp38
-rw-r--r--source/Host/common/FileSystem.cpp33
-rw-r--r--source/Host/common/Host.cpp39
-rw-r--r--source/Host/common/HostInfoBase.cpp21
-rw-r--r--source/Host/common/HostNativeThreadBase.cpp3
-rw-r--r--source/Host/common/LZMA.cpp146
-rw-r--r--source/Host/common/MainLoop.cpp1
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp75
-rw-r--r--source/Host/common/NativeRegisterContext.cpp32
-rw-r--r--source/Host/common/Socket.cpp102
-rw-r--r--source/Host/common/TCPSocket.cpp6
-rw-r--r--source/Host/common/UDPSocket.cpp5
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp11
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp159
-rw-r--r--source/Host/posix/HostInfoPosix.cpp45
-rw-r--r--source/Initialization/SystemInitializerCommon.cpp12
-rw-r--r--source/Interpreter/CommandAlias.cpp16
-rw-r--r--source/Interpreter/CommandInterpreter.cpp375
-rw-r--r--source/Interpreter/CommandObject.cpp29
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp20
-rw-r--r--source/Interpreter/CommandReturnObject.cpp3
-rw-r--r--source/Interpreter/InterpreterProperties.td28
-rw-r--r--source/Interpreter/OptionArgParser.cpp36
-rw-r--r--source/Interpreter/OptionGroupArchitecture.cpp3
-rw-r--r--source/Interpreter/OptionGroupFormat.cpp3
-rw-r--r--source/Interpreter/OptionGroupOutputFile.cpp3
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp3
-rw-r--r--source/Interpreter/OptionGroupPythonClassWithDict.cpp123
-rw-r--r--source/Interpreter/OptionGroupUUID.cpp3
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp3
-rw-r--r--source/Interpreter/OptionGroupVariable.cpp4
-rw-r--r--source/Interpreter/OptionGroupWatchpoint.cpp49
-rw-r--r--source/Interpreter/OptionValue.cpp7
-rw-r--r--source/Interpreter/OptionValueArch.cpp6
-rw-r--r--source/Interpreter/OptionValueBoolean.cpp18
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp6
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp15
-rw-r--r--source/Interpreter/OptionValueFileSpec.cpp6
-rw-r--r--source/Interpreter/OptionValueFileSpecList.cpp (renamed from source/Interpreter/OptionValueFileSpecLIst.cpp)2
-rw-r--r--source/Interpreter/OptionValueFormatEntity.cpp6
-rw-r--r--source/Interpreter/OptionValueLanguage.cpp16
-rw-r--r--source/Interpreter/OptionValueRegex.cpp12
-rw-r--r--source/Interpreter/OptionValueUUID.cpp40
-rw-r--r--source/Interpreter/Options.cpp95
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp4
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h4
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp12
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h4
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp4
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp614
-rw-r--r--source/Plugins/ABI/SysV-arc/ABISysV_arc.h106
-rw-r--r--source/Plugins/ABI/SysV-arc/CMakeLists.txt11
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp4
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.h4
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp13
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h4
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp4
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp29
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.h4
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp29
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp28
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp46
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h4
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp21
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h4
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp59
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h4
-rw-r--r--source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp27
-rw-r--r--source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h4
-rw-r--r--source/Plugins/Architecture/Mips/ArchitectureMips.cpp8
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp13
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp50
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp37
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp232
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h23
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp203
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp46
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTDumper.cpp8
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp30
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp456
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp30
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h50
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp341
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp285
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h11
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp42
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h31
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangHost.cpp21
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp22
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h9
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp23
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h19
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp189
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h37
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp2
-rw-r--r--source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp82
-rw-r--r--source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h84
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp22
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp663
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.h36
-rw-r--r--source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h10
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp1
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp4
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp1
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp1
-rw-r--r--source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp1
-rw-r--r--source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp2
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp12
-rw-r--r--source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp2
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp124
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td9
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp59
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp51
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.h6
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp15
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp11
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp39
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp13
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp29
-rw-r--r--source/Plugins/Language/ObjC/CoreMedia.cpp20
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp26
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.h4
-rw-r--r--source/Plugins/Language/ObjC/NSString.cpp22
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp2
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp111
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp133
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h8
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp23
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp12
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp162
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp62
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp49
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h32
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp25
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp36
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h1
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp8
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp733
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h12
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp11
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp98
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h25
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp4
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h9
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp425
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h27
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp2
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.h7
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp56
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp71
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp108
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h2
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp42
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp194
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp568
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp18
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp28
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp60
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp140
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp11
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp4
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp7
-rw-r--r--source/Plugins/Process/POSIX/NativeProcessELF.cpp72
-rw-r--r--source/Plugins/Process/POSIX/NativeProcessELF.h7
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp7
-rw-r--r--source/Plugins/Process/Utility/AuxVector.cpp6
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp114
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp8
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp4
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h3
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp87
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.h3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp227
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp89
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_i386.h27
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp152
-rw-r--r--source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h28
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h439
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp900
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp96
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h3
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp6
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h3
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp51
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.h40
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp70
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h66
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp206
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp184
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h8
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp75
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h85
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp18
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp12
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp106
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp664
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp56
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp55
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp781
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td16
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp8
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp53
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h2
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp37
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h113
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp94
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h2
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp38
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h6
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp4
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp1244
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h622
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp169
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h56
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp567
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h3
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h53
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp330
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td12
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp257
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h84
-rw-r--r--source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp1078
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h91
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp1038
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h227
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp67
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp959
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h72
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp237
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td12
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp2
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp29
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h7
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp60
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp143
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h58
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp23
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp2
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp345
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h56
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp38
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h18
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp144
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp32
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp1
-rw-r--r--source/Symbol/Block.cpp38
-rw-r--r--source/Symbol/ClangASTContext.cpp1935
-rw-r--r--source/Symbol/ClangASTImporter.cpp384
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp11
-rw-r--r--source/Symbol/CompileUnit.cpp87
-rw-r--r--source/Symbol/CompilerType.cpp28
-rw-r--r--source/Symbol/CxxModuleHandler.cpp14
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp17
-rw-r--r--source/Symbol/DeclVendor.cpp11
-rw-r--r--source/Symbol/FuncUnwinders.cpp65
-rw-r--r--source/Symbol/Function.cpp53
-rw-r--r--source/Symbol/LineTable.cpp68
-rw-r--r--source/Symbol/LocateSymbolFile.cpp171
-rw-r--r--source/Symbol/LocateSymbolFileMacOSX.cpp71
-rw-r--r--source/Symbol/ObjectFile.cpp77
-rw-r--r--source/Symbol/PostfixExpression.cpp23
-rw-r--r--source/Symbol/Symbol.cpp9
-rw-r--r--source/Symbol/SymbolContext.cpp166
-rw-r--r--source/Symbol/SymbolFile.cpp180
-rw-r--r--source/Symbol/SymbolVendor.cpp413
-rw-r--r--source/Symbol/Symtab.cpp18
-rw-r--r--source/Symbol/Type.cpp120
-rw-r--r--source/Symbol/TypeMap.cpp13
-rw-r--r--source/Symbol/TypeSystem.cpp192
-rw-r--r--source/Symbol/UnwindPlan.cpp46
-rw-r--r--source/Symbol/UnwindTable.cpp24
-rw-r--r--source/Symbol/Variable.cpp123
-rw-r--r--source/Symbol/VerifyDecl.cpp15
-rw-r--r--source/Target/ABI.cpp19
-rw-r--r--source/Target/ExecutionContext.cpp4
-rw-r--r--source/Target/Language.cpp24
-rw-r--r--source/Target/LanguageRuntime.cpp7
-rw-r--r--source/Target/Memory.cpp28
-rw-r--r--source/Target/ModuleCache.cpp29
-rw-r--r--source/Target/Platform.cpp150
-rw-r--r--source/Target/Process.cpp837
-rw-r--r--source/Target/RegisterContext.cpp8
-rw-r--r--source/Target/RemoteAwarePlatform.cpp4
-rw-r--r--source/Target/SectionLoadList.cpp12
-rw-r--r--source/Target/StackFrame.cpp42
-rw-r--r--source/Target/StackFrameList.cpp78
-rw-r--r--source/Target/StopInfo.cpp117
-rw-r--r--source/Target/Target.cpp1127
-rw-r--r--source/Target/TargetProperties.td237
-rw-r--r--source/Target/Thread.cpp250
-rw-r--r--source/Target/ThreadList.cpp55
-rw-r--r--source/Target/ThreadPlan.cpp3
-rw-r--r--source/Target/ThreadPlanBase.cpp40
-rw-r--r--source/Target/ThreadPlanCallFunction.cpp132
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp5
-rw-r--r--source/Target/ThreadPlanPython.cpp42
-rw-r--r--source/Target/ThreadPlanRunToAddress.cpp3
-rw-r--r--source/Target/ThreadPlanShouldStopHere.cpp17
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp70
-rw-r--r--source/Target/ThreadPlanStepInstruction.cpp24
-rw-r--r--source/Target/ThreadPlanStepOut.cpp4
-rw-r--r--source/Target/ThreadPlanStepOverBreakpoint.cpp16
-rw-r--r--source/Target/ThreadPlanStepOverRange.cpp14
-rw-r--r--source/Target/ThreadPlanStepRange.cpp57
-rw-r--r--source/Target/ThreadPlanStepThrough.cpp16
-rw-r--r--source/Target/ThreadPlanStepUntil.cpp3
-rw-r--r--source/Target/ThreadPlanTracer.cpp21
-rw-r--r--source/Utility/ArchSpec.cpp44
-rw-r--r--source/Utility/Args.cpp57
-rw-r--r--source/Utility/Broadcaster.cpp11
-rw-r--r--source/Utility/CompletionRequest.cpp57
-rw-r--r--source/Utility/ConstString.cpp17
-rw-r--r--source/Utility/DataExtractor.cpp37
-rw-r--r--source/Utility/FileCollector.cpp182
-rw-r--r--source/Utility/FileSpec.cpp8
-rw-r--r--source/Utility/GDBRemote.cpp105
-rw-r--r--source/Utility/JSON.cpp550
-rw-r--r--source/Utility/Listener.cpp69
-rw-r--r--source/Utility/Log.cpp39
-rw-r--r--source/Utility/Logging.cpp10
-rw-r--r--source/Utility/ProcessInfo.cpp95
-rw-r--r--source/Utility/RegularExpression.cpp168
-rw-r--r--source/Utility/Reproducer.cpp85
-rw-r--r--source/Utility/Scalar.cpp45
-rw-r--r--source/Utility/SelectHelper.cpp4
-rw-r--r--source/Utility/StreamGDBRemote.cpp45
-rw-r--r--source/Utility/StringExtractor.cpp28
-rw-r--r--source/Utility/StringLexer.cpp2
-rw-r--r--source/Utility/StringList.cpp36
-rw-r--r--source/Utility/StructuredData.cpp244
-rw-r--r--tools/argdumper/argdumper.cpp22
-rw-r--r--tools/compact-unwind/compact-unwind-dumper.c2
-rw-r--r--tools/driver/Driver.cpp52
-rw-r--r--tools/driver/Platform.h5
-rw-r--r--tools/lldb-instr/Instrument.cpp6
-rw-r--r--tools/lldb-mi/MICmdArgContext.cpp221
-rw-r--r--tools/lldb-mi/MICmdArgContext.h43
-rw-r--r--tools/lldb-mi/MICmdArgSet.cpp386
-rw-r--r--tools/lldb-mi/MICmdArgSet.h107
-rw-r--r--tools/lldb-mi/MICmdArgValBase.cpp129
-rw-r--r--tools/lldb-mi/MICmdArgValBase.h115
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.cpp88
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.h53
-rw-r--r--tools/lldb-mi/MICmdArgValFile.cpp178
-rw-r--r--tools/lldb-mi/MICmdArgValFile.h47
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.cpp209
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.h101
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.cpp167
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.h92
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.cpp156
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.h69
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.cpp291
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.h104
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.cpp121
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.h59
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.cpp125
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.h56
-rw-r--r--tools/lldb-mi/MICmdArgValString.cpp380
-rw-r--r--tools/lldb-mi/MICmdArgValString.h82
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.cpp141
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.h53
-rw-r--r--tools/lldb-mi/MICmdBase.cpp329
-rw-r--r--tools/lldb-mi/MICmdBase.h193
-rw-r--r--tools/lldb-mi/MICmdCmd.cpp158
-rw-r--r--tools/lldb-mi/MICmdCmd.h90
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp1024
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.h262
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp1673
-rw-r--r--tools/lldb-mi/MICmdCmdData.h381
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.cpp145
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.h57
-rw-r--r--tools/lldb-mi/MICmdCmdExec.cpp1115
-rw-r--r--tools/lldb-mi/MICmdCmdExec.h316
-rw-r--r--tools/lldb-mi/MICmdCmdFile.cpp206
-rw-r--r--tools/lldb-mi/MICmdCmdFile.h66
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.cpp225
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.h87
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.cpp491
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.h101
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.cpp395
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.h101
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.cpp89
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.h50
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.cpp586
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.h156
-rw-r--r--tools/lldb-mi/MICmdCmdStack.cpp1053
-rw-r--r--tools/lldb-mi/MICmdCmdStack.h256
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.cpp117
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.h58
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.cpp96
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.h51
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.cpp177
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.h59
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.cpp447
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.h117
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp211
-rw-r--r--tools/lldb-mi/MICmdCmdThread.h69
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.cpp88
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.h50
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp1460
-rw-r--r--tools/lldb-mi/MICmdCmdVar.h348
-rw-r--r--tools/lldb-mi/MICmdCommands.cpp134
-rw-r--r--tools/lldb-mi/MICmdCommands.h19
-rw-r--r--tools/lldb-mi/MICmdData.cpp10
-rw-r--r--tools/lldb-mi/MICmdData.h58
-rw-r--r--tools/lldb-mi/MICmdFactory.cpp206
-rw-r--r--tools/lldb-mi/MICmdFactory.h84
-rw-r--r--tools/lldb-mi/MICmdInterpreter.cpp290
-rw-r--r--tools/lldb-mi/MICmdInterpreter.h62
-rw-r--r--tools/lldb-mi/MICmdInvoker.cpp321
-rw-r--r--tools/lldb-mi/MICmdInvoker.h103
-rw-r--r--tools/lldb-mi/MICmdMgr.cpp248
-rw-r--r--tools/lldb-mi/MICmdMgr.h69
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp87
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h72
-rw-r--r--tools/lldb-mi/MICmnBase.cpp123
-rw-r--r--tools/lldb-mi/MICmnBase.h46
-rw-r--r--tools/lldb-mi/MICmnConfig.h19
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.cpp68
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.h44
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp863
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.h292
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp573
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h139
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp905
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.h134
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp1883
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h99
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.cpp134
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.h34
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.cpp497
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.h77
-rw-r--r--tools/lldb-mi/MICmnLog.cpp330
-rw-r--r--tools/lldb-mi/MICmnLog.h138
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.cpp385
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.h84
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.cpp202
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.h93
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.cpp133
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.h79
-rw-r--r--tools/lldb-mi/MICmnMIValue.cpp43
-rw-r--r--tools/lldb-mi/MICmnMIValue.h50
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.cpp77
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.h59
-rw-r--r--tools/lldb-mi/MICmnMIValueList.cpp177
-rw-r--r--tools/lldb-mi/MICmnMIValueList.h55
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.cpp116
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.h66
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.cpp194
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.h63
-rw-r--r--tools/lldb-mi/MICmnResources.cpp619
-rw-r--r--tools/lldb-mi/MICmnResources.h339
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.cpp249
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.h61
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.cpp218
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.h60
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.cpp230
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.h62
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.cpp145
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.h123
-rw-r--r--tools/lldb-mi/MIDataTypes.h60
-rw-r--r--tools/lldb-mi/MIDriver.cpp1318
-rw-r--r--tools/lldb-mi/MIDriver.h180
-rw-r--r--tools/lldb-mi/MIDriverBase.cpp179
-rw-r--r--tools/lldb-mi/MIDriverBase.h67
-rw-r--r--tools/lldb-mi/MIDriverMain.cpp194
-rw-r--r--tools/lldb-mi/MIDriverMgr.cpp727
-rw-r--r--tools/lldb-mi/MIDriverMgr.h128
-rw-r--r--tools/lldb-mi/MIExtensions.txt104
-rw-r--r--tools/lldb-mi/MIReadMe.txt37
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.cpp84
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.h40
-rw-r--r--tools/lldb-mi/MIUtilDebug.cpp91
-rw-r--r--tools/lldb-mi/MIUtilDebug.h79
-rw-r--r--tools/lldb-mi/MIUtilFileStd.cpp282
-rw-r--r--tools/lldb-mi/MIUtilFileStd.h48
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.cpp99
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.h129
-rw-r--r--tools/lldb-mi/MIUtilSingletonBase.h52
-rw-r--r--tools/lldb-mi/MIUtilSingletonHelper.h81
-rw-r--r--tools/lldb-mi/MIUtilString.cpp915
-rw-r--r--tools/lldb-mi/MIUtilString.h95
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.cpp302
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.h140
-rw-r--r--tools/lldb-mi/MIUtilVariant.cpp344
-rw-r--r--tools/lldb-mi/MIUtilVariant.h247
-rw-r--r--tools/lldb-mi/Platform.h87
-rw-r--r--tools/lldb-mi/module.modulemap79
-rw-r--r--tools/lldb-server/LLDBServerUtilities.cpp2
-rw-r--r--tools/lldb-server/lldb-gdbserver.cpp17
-rw-r--r--tools/lldb-server/lldb-platform.cpp61
-rw-r--r--tools/lldb-server/lldb-server.cpp4
-rw-r--r--utils/TableGen/LLDBOptionDefEmitter.cpp162
-rw-r--r--utils/TableGen/LLDBPropertyDefEmitter.cpp165
-rw-r--r--utils/TableGen/LLDBTableGen.cpp32
-rw-r--r--utils/TableGen/LLDBTableGenBackends.h12
-rw-r--r--utils/TableGen/LLDBTableGenUtils.cpp21
-rw-r--r--utils/TableGen/LLDBTableGenUtils.h34
816 files changed, 26234 insertions, 60896 deletions
diff --git a/docs/lldb.1 b/docs/lldb.1
index a28cabe7acc0..a48b6d1b918f 100644
--- a/docs/lldb.1
+++ b/docs/lldb.1
@@ -149,6 +149,6 @@ The LLDB project page http://lldb.llvm.org/ has many different resources for
users -- the gdb/lldb command equivalence page http://lldb.llvm.org/lldb-gdb.html can
be especially helpful for users coming from gdb.
.Sh BUGS
-To report bugs, please visit http://llvm.org/bugs/
+To report bugs, please visit https://bugs.llvm.org/
.Sh AUTHOR
Maintained by the LLDB Team, http://lldb.llvm.org/
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h
index 0806ab700a94..75e2d70c0c39 100644
--- a/include/lldb/API/LLDB.h
+++ b/include/lldb/API/LLDB.h
@@ -13,8 +13,8 @@
#include "lldb/API/SBAttachInfo.h"
#include "lldb/API/SBBlock.h"
#include "lldb/API/SBBreakpoint.h"
-#include "lldb/API/SBBreakpointName.h"
#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBBreakpointName.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
@@ -28,6 +28,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBExecutionContext.h"
#include "lldb/API/SBExpressionOptions.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBFileSpecList.h"
#include "lldb/API/SBFrame.h"
diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h
index 2877afb9b8b0..e3fbacf85afc 100644
--- a/include/lldb/API/SBCommandReturnObject.h
+++ b/include/lldb/API/SBCommandReturnObject.h
@@ -15,23 +15,27 @@
#include "lldb/API/SBDefines.h"
+namespace lldb_private {
+class SBCommandReturnObjectImpl;
+}
+
namespace lldb {
class LLDB_API SBCommandReturnObject {
public:
SBCommandReturnObject();
+ SBCommandReturnObject(lldb_private::CommandReturnObject &ref);
+
+ // rvalue ctor+assignment are incompatible with Reproducers.
+
SBCommandReturnObject(const lldb::SBCommandReturnObject &rhs);
~SBCommandReturnObject();
- const lldb::SBCommandReturnObject &
+ lldb::SBCommandReturnObject &
operator=(const lldb::SBCommandReturnObject &rhs);
- SBCommandReturnObject(lldb_private::CommandReturnObject *ptr);
-
- lldb_private::CommandReturnObject *Release();
-
explicit operator bool() const;
bool IsValid() const;
@@ -40,13 +44,21 @@ public:
const char *GetError();
- size_t PutOutput(FILE *fh);
+ size_t PutOutput(FILE *fh); // DEPRECATED
+
+ size_t PutOutput(SBFile file);
+
+ size_t PutOutput(FileSP file);
size_t GetOutputSize();
size_t GetErrorSize();
- size_t PutError(FILE *fh);
+ size_t PutError(FILE *fh); // DEPRECATED
+
+ size_t PutError(SBFile file);
+
+ size_t PutError(FileSP file);
void Clear();
@@ -64,14 +76,21 @@ public:
bool GetDescription(lldb::SBStream &description);
- // deprecated, these two functions do not take ownership of file handle
- void SetImmediateOutputFile(FILE *fh);
+ void SetImmediateOutputFile(FILE *fh); // DEPRECATED
- void SetImmediateErrorFile(FILE *fh);
+ void SetImmediateErrorFile(FILE *fh); // DEPRECATED
- void SetImmediateOutputFile(FILE *fh, bool transfer_ownership);
+ void SetImmediateOutputFile(FILE *fh, bool transfer_ownership); // DEPRECATED
- void SetImmediateErrorFile(FILE *fh, bool transfer_ownership);
+ void SetImmediateErrorFile(FILE *fh, bool transfer_ownership); // DEPRECATED
+
+ void SetImmediateOutputFile(SBFile file);
+
+ void SetImmediateErrorFile(SBFile file);
+
+ void SetImmediateOutputFile(FileSP file);
+
+ void SetImmediateErrorFile(FileSP file);
void PutCString(const char *string, int len = -1);
@@ -86,6 +105,9 @@ public:
void SetError(const char *error_cstr);
+ // ref() is internal for LLDB only.
+ lldb_private::CommandReturnObject &ref() const;
+
protected:
friend class SBCommandInterpreter;
friend class SBOptions;
@@ -96,12 +118,8 @@ protected:
lldb_private::CommandReturnObject &operator*() const;
- lldb_private::CommandReturnObject &ref() const;
-
- void SetLLDBObjectPtr(lldb_private::CommandReturnObject *ptr);
-
private:
- std::unique_ptr<lldb_private::CommandReturnObject> m_opaque_up;
+ std::unique_ptr<lldb_private::SBCommandReturnObjectImpl> m_opaque_up;
};
} // namespace lldb
diff --git a/include/lldb/API/SBDebugger.h b/include/lldb/API/SBDebugger.h
index 417cead24a8c..580f6281fbb6 100644
--- a/include/lldb/API/SBDebugger.h
+++ b/include/lldb/API/SBDebugger.h
@@ -88,6 +88,24 @@ public:
FILE *GetErrorFileHandle();
+ SBError SetInputFile(SBFile file);
+
+ SBError SetOutputFile(SBFile file);
+
+ SBError SetErrorFile(SBFile file);
+
+ SBError SetInputFile(FileSP file);
+
+ SBError SetOutputFile(FileSP file);
+
+ SBError SetErrorFile(FileSP file);
+
+ SBFile GetInputFile();
+
+ SBFile GetOutputFile();
+
+ SBFile GetErrorFile();
+
void SaveInputTerminalState();
void RestoreInputTerminalState();
@@ -99,7 +117,14 @@ public:
lldb::SBListener GetListener();
void HandleProcessEvent(const lldb::SBProcess &process,
- const lldb::SBEvent &event, FILE *out, FILE *err);
+ const lldb::SBEvent &event, FILE *out,
+ FILE *err); // DEPRECATED
+
+ void HandleProcessEvent(const lldb::SBProcess &process,
+ const lldb::SBEvent &event, SBFile out, SBFile err);
+
+ void HandleProcessEvent(const lldb::SBProcess &process,
+ const lldb::SBEvent &event, FileSP out, FileSP err);
lldb::SBTarget CreateTarget(const char *filename, const char *target_triple,
const char *platform_name,
diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h
index 838c84cece6d..68aca930d199 100644
--- a/include/lldb/API/SBDefines.h
+++ b/include/lldb/API/SBDefines.h
@@ -41,6 +41,7 @@ class LLDB_API SBEvent;
class LLDB_API SBEventList;
class LLDB_API SBExecutionContext;
class LLDB_API SBExpressionOptions;
+class LLDB_API SBFile;
class LLDB_API SBFileSpec;
class LLDB_API SBFileSpecList;
class LLDB_API SBFrame;
diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h
index b076f87b7669..3db2658d9fb7 100644
--- a/include/lldb/API/SBError.h
+++ b/include/lldb/API/SBError.h
@@ -70,6 +70,7 @@ protected:
friend class SBTrace;
friend class SBValue;
friend class SBWatchpoint;
+ friend class SBFile;
lldb_private::Status *get();
diff --git a/include/lldb/API/SBFile.h b/include/lldb/API/SBFile.h
new file mode 100644
index 000000000000..7d6c14809923
--- /dev/null
+++ b/include/lldb/API/SBFile.h
@@ -0,0 +1,47 @@
+//===-- SBFile.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_SBFile_h_
+#define LLDB_SBFile_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class LLDB_API SBFile {
+ friend class SBInstruction;
+ friend class SBInstructionList;
+ friend class SBDebugger;
+ friend class SBCommandReturnObject;
+ friend class SBProcess;
+
+public:
+ SBFile();
+ SBFile(FileSP file_sp);
+ SBFile(FILE *file, bool transfer_ownership);
+ SBFile(int fd, const char *mode, bool transfer_ownership);
+ ~SBFile();
+
+ SBError Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read);
+ SBError Write(const uint8_t *buf, size_t num_bytes, size_t *bytes_written);
+ SBError Flush();
+ bool IsValid() const;
+ SBError Close();
+
+ operator bool() const;
+ bool operator!() const;
+
+ FileSP GetFile() const;
+
+private:
+ FileSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBFile_h_
diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h
index 0bb587795607..7d83a37ba5d6 100644
--- a/include/lldb/API/SBInstruction.h
+++ b/include/lldb/API/SBInstruction.h
@@ -55,6 +55,10 @@ public:
void Print(FILE *out);
+ void Print(SBFile out);
+
+ void Print(FileSP out);
+
bool GetDescription(lldb::SBStream &description);
bool EmulateWithFrame(lldb::SBFrame &frame, uint32_t evaluate_options);
diff --git a/include/lldb/API/SBInstructionList.h b/include/lldb/API/SBInstructionList.h
index 4434d50f471f..e203d0b80564 100644
--- a/include/lldb/API/SBInstructionList.h
+++ b/include/lldb/API/SBInstructionList.h
@@ -46,6 +46,10 @@ public:
void Print(FILE *out);
+ void Print(SBFile out);
+
+ void Print(FileSP out);
+
bool GetDescription(lldb::SBStream &description);
bool DumpEmulationForAllInstructions(const char *triple);
@@ -56,6 +60,8 @@ protected:
friend class SBTarget;
void SetDisassembler(const lldb::DisassemblerSP &opaque_sp);
+ bool GetDescription(lldb_private::Stream &description);
+
private:
lldb::DisassemblerSP m_opaque_sp;
diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h
index 863cb3ced674..8ab8bfa3a93e 100644
--- a/include/lldb/API/SBProcess.h
+++ b/include/lldb/API/SBProcess.h
@@ -67,6 +67,10 @@ public:
void ReportEventState(const lldb::SBEvent &event, FILE *out) const;
+ void ReportEventState(const lldb::SBEvent &event, SBFile file) const;
+
+ void ReportEventState(const lldb::SBEvent &event, FileSP file) const;
+
void AppendEventStateReport(const lldb::SBEvent &event,
lldb::SBCommandReturnObject &result);
diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h
index 8afbf4575621..b78c498e5f3d 100644
--- a/include/lldb/API/SBStream.h
+++ b/include/lldb/API/SBStream.h
@@ -39,6 +39,10 @@ public:
void RedirectToFile(const char *path, bool append);
+ void RedirectToFile(lldb::SBFile file);
+
+ void RedirectToFile(lldb::FileSP file);
+
void RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership);
void RedirectToFileDescriptor(int fd, bool transfer_fh_ownership);
diff --git a/include/lldb/API/SBStructuredData.h b/include/lldb/API/SBStructuredData.h
index 5b10133500ef..a090272e45ac 100644
--- a/include/lldb/API/SBStructuredData.h
+++ b/include/lldb/API/SBStructuredData.h
@@ -91,6 +91,8 @@ protected:
friend class SBTraceOptions;
friend class SBDebugger;
friend class SBTarget;
+ friend class SBThread;
+ friend class SBThreadPlan;
StructuredDataImplUP m_impl_up;
};
diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h
index da8726a2a9b2..b5f1794f9fe0 100644
--- a/include/lldb/API/SBThread.h
+++ b/include/lldb/API/SBThread.h
@@ -122,6 +122,10 @@ public:
SBError StepUsingScriptedThreadPlan(const char *script_class_name,
bool resume_immediately);
+ SBError StepUsingScriptedThreadPlan(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ bool resume_immediately);
+
SBError JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line);
void RunToAddress(lldb::addr_t addr);
diff --git a/include/lldb/API/SBThreadPlan.h b/include/lldb/API/SBThreadPlan.h
index 007e9e2de21a..dbe417e63749 100644
--- a/include/lldb/API/SBThreadPlan.h
+++ b/include/lldb/API/SBThreadPlan.h
@@ -28,6 +28,9 @@ public:
SBThreadPlan(lldb::SBThread &thread, const char *class_name);
+ SBThreadPlan(lldb::SBThread &thread, const char *class_name,
+ lldb::SBStructuredData &args_data);
+
~SBThreadPlan();
explicit operator bool() const;
@@ -100,6 +103,9 @@ public:
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name);
SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name,
SBError &error);
+ SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ SBError &error);
private:
friend class SBBreakpoint;
diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h
index 7b27160563a0..aadd52288485 100644
--- a/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/include/lldb/Breakpoint/BreakpointLocation.h
@@ -67,7 +67,7 @@ public:
// The next section deals with various breakpoint options.
- /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
+ /// If \a enabled is \b true, enable the breakpoint, if \b false disable it.
void SetEnabled(bool enabled);
/// Check the Enable/Disable state.
diff --git a/include/lldb/Breakpoint/BreakpointOptions.h b/include/lldb/Breakpoint/BreakpointOptions.h
index cdac5d3dbd75..55a4be2d19c1 100644
--- a/include/lldb/Breakpoint/BreakpointOptions.h
+++ b/include/lldb/Breakpoint/BreakpointOptions.h
@@ -107,6 +107,12 @@ public:
/// \param[in] ignore
/// How many breakpoint hits we should ignore before stopping.
///
+ /// \param[in] one_shot
+ /// Should this breakpoint delete itself after being hit once.
+ ///
+ /// \param[in] auto_continue
+ /// Should this breakpoint auto-continue after running its commands.
+ ///
BreakpointOptions(const char *condition, bool enabled = true,
int32_t ignore = 0, bool one_shot = false,
bool auto_continue = false);
@@ -319,7 +325,10 @@ public:
void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
- /// Returns true if the breakpoint option has a callback set.
+ /// Check if the breakpoint option has a callback set.
+ ///
+ /// \return
+ /// If the breakpoint option has a callback, \b true otherwise \b false.
bool HasCallback() const;
/// This is the default empty callback.
@@ -367,22 +376,32 @@ protected:
void SetThreadSpec(std::unique_ptr<ThreadSpec> &thread_spec_up);
private:
- // For BreakpointOptions only
- BreakpointHitCallback m_callback; // This is the callback function pointer
- lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
+ /// For BreakpointOptions only
+
+ /// This is the callback function pointer
+ BreakpointHitCallback m_callback;
+ /// This is the client data for the callback
+ lldb::BatonSP m_callback_baton_sp;
bool m_baton_is_command_baton;
bool m_callback_is_synchronous;
bool m_enabled;
+ /// If set, the breakpoint delete itself after being hit once.
bool m_one_shot;
- uint32_t m_ignore_count; // Number of times to ignore this breakpoint
- std::unique_ptr<ThreadSpec>
- m_thread_spec_up; // Thread for which this breakpoint will take
- std::string m_condition_text; // The condition to test.
- size_t m_condition_text_hash; // Its hash, so that locations know when the
- // condition is updated.
- bool m_auto_continue; // If set, auto-continue from breakpoint.
- Flags m_set_flags; // Which options are set at this level. Drawn
- // from BreakpointOptions::SetOptionsFlags.
+ /// Number of times to ignore this breakpoint.
+ uint32_t m_ignore_count;
+ /// Thread for which this breakpoint will stop.
+ std::unique_ptr<ThreadSpec> m_thread_spec_up;
+ /// The condition to test.
+ std::string m_condition_text;
+ /// Its hash, so that locations know when the condition is updated.
+ size_t m_condition_text_hash;
+ /// If set, inject breakpoint condition into process.
+ bool m_inject_condition;
+ /// If set, auto-continue from breakpoint.
+ bool m_auto_continue;
+ /// Which options are set at this level.
+ /// Drawn from BreakpointOptions::SetOptionsFlags.
+ Flags m_set_flags;
};
} // namespace lldb_private
diff --git a/include/lldb/Breakpoint/BreakpointResolverAddress.h b/include/lldb/Breakpoint/BreakpointResolverAddress.h
index 949a788282b9..3df89641c711 100644
--- a/include/lldb/Breakpoint/BreakpointResolverAddress.h
+++ b/include/lldb/Breakpoint/BreakpointResolverAddress.h
@@ -41,8 +41,8 @@ public:
ModuleList &modules) override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
index f146a704ca54..9ca48ecf0dc0 100644
--- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h
+++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h
@@ -35,8 +35,8 @@ public:
~BreakpointResolverFileLine() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
index 963145722e39..df4c13ed59e2 100644
--- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
+++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
@@ -24,7 +24,7 @@ namespace lldb_private {
class BreakpointResolverFileRegex : public BreakpointResolver {
public:
BreakpointResolverFileRegex(
- Breakpoint *bkpt, RegularExpression &regex,
+ Breakpoint *bkpt, RegularExpression regex,
const std::unordered_set<std::string> &func_name_set, bool exact_match);
static BreakpointResolver *
@@ -37,8 +37,8 @@ public:
~BreakpointResolverFileRegex() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h
index 85a41b6007f0..196d88db848c 100644
--- a/include/lldb/Breakpoint/BreakpointResolverName.h
+++ b/include/lldb/Breakpoint/BreakpointResolverName.h
@@ -44,7 +44,7 @@ public:
// Creates a function breakpoint by regular expression. Takes over control
// of the lifespan of func_regex.
- BreakpointResolverName(Breakpoint *bkpt, RegularExpression &func_regex,
+ BreakpointResolverName(Breakpoint *bkpt, RegularExpression func_regex,
lldb::LanguageType language, lldb::addr_t offset,
bool skip_prologue);
@@ -58,8 +58,8 @@ public:
~BreakpointResolverName() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Breakpoint/BreakpointResolverScripted.h b/include/lldb/Breakpoint/BreakpointResolverScripted.h
index 980bb4693d03..89a7d03ce93f 100644
--- a/include/lldb/Breakpoint/BreakpointResolverScripted.h
+++ b/include/lldb/Breakpoint/BreakpointResolverScripted.h
@@ -26,8 +26,7 @@ public:
BreakpointResolverScripted(Breakpoint *bkpt,
const llvm::StringRef class_name,
lldb::SearchDepth depth,
- StructuredDataImpl *args_data,
- ScriptInterpreter &script_interp);
+ StructuredDataImpl *args_data);
~BreakpointResolverScripted() override;
@@ -39,8 +38,8 @@ public:
StructuredData::ObjectSP SerializeToStructuredData() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Core/Address.h b/include/lldb/Core/Address.h
index 080c00e76328..07bb450d6092 100644
--- a/include/lldb/Core/Address.h
+++ b/include/lldb/Core/Address.h
@@ -338,6 +338,23 @@ public:
bool ResolveAddressUsingFileSections(lldb::addr_t addr,
const SectionList *sections);
+ /// Resolve this address to its containing function and optionally get
+ /// that function's address range.
+ ///
+ /// \param[out] sym_ctx
+ /// The symbol context describing the function in which this address lies
+ ///
+ /// \parm[out] addr_range_ptr
+ /// Pointer to the AddressRange to fill in with the function's address
+ /// range. Caller may pass null if they don't need the address range.
+ ///
+ /// \return
+ /// Returns \b false if the function/symbol could not be resolved
+ /// or if the address range was requested and could not be resolved;
+ /// returns \b true otherwise.
+ bool ResolveFunctionScope(lldb_private::SymbolContext &sym_ctx,
+ lldb_private::AddressRange *addr_range_ptr = nullptr);
+
/// Set the address to represent \a load_addr.
///
/// The address will attempt to find a loaded section within \a target that
diff --git a/include/lldb/Core/AddressResolverFileLine.h b/include/lldb/Core/AddressResolverFileLine.h
index b98e7d4c6338..efbe3de1f294 100644
--- a/include/lldb/Core/AddressResolverFileLine.h
+++ b/include/lldb/Core/AddressResolverFileLine.h
@@ -34,8 +34,8 @@ public:
~AddressResolverFileLine() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Core/AddressResolverName.h b/include/lldb/Core/AddressResolverName.h
index ad14ef6daeb1..8a039f9e1d92 100644
--- a/include/lldb/Core/AddressResolverName.h
+++ b/include/lldb/Core/AddressResolverName.h
@@ -31,7 +31,7 @@ public:
// Creates a function breakpoint by regular expression. Takes over control
// of the lifespan of func_regex.
- AddressResolverName(RegularExpression &func_regex);
+ AddressResolverName(RegularExpression func_regex);
AddressResolverName(const char *class_name, const char *method,
AddressResolver::MatchType type);
@@ -39,8 +39,8 @@ public:
~AddressResolverName() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h
index 8e608717a801..b2f696c22834 100644
--- a/include/lldb/Core/Debugger.h
+++ b/include/lldb/Core/Debugger.h
@@ -17,6 +17,7 @@
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Terminal.h"
@@ -113,20 +114,29 @@ public:
void SetAsyncExecution(bool async);
- lldb::StreamFileSP GetInputFile() { return m_input_file_sp; }
+ lldb::FileSP GetInputFileSP() { return m_input_file_sp; }
- lldb::StreamFileSP GetOutputFile() { return m_output_file_sp; }
+ lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; }
- lldb::StreamFileSP GetErrorFile() { return m_error_file_sp; }
+ lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
+
+ File &GetInputFile() { return *m_input_file_sp; }
+
+ File &GetOutputFile() { return m_output_stream_sp->GetFile(); }
+
+ File &GetErrorFile() { return m_error_stream_sp->GetFile(); }
+
+ StreamFile &GetOutputStream() { return *m_output_stream_sp; }
+
+ StreamFile &GetErrorStream() { return *m_error_stream_sp; }
repro::DataRecorder *GetInputRecorder();
- void SetInputFileHandle(FILE *fh, bool tranfer_ownership,
- repro::DataRecorder *recorder = nullptr);
+ void SetInputFile(lldb::FileSP file, repro::DataRecorder *recorder = nullptr);
- void SetOutputFileHandle(FILE *fh, bool tranfer_ownership);
+ void SetOutputFile(lldb::FileSP file);
- void SetErrorFileHandle(FILE *fh, bool tranfer_ownership);
+ void SetErrorFile(lldb::FileSP file);
void SaveInputTerminalState();
@@ -174,7 +184,7 @@ public:
// If any of the streams are not set, set them to the in/out/err stream of
// the top most input reader to ensure they at least have something
- void AdoptTopIOHandlerFilesIfInvalid(lldb::StreamFileSP &in,
+ void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in,
lldb::StreamFileSP &out,
lldb::StreamFileSP &err);
@@ -311,7 +321,7 @@ public:
// selected target, or if no target is present you want to prime the dummy
// target with entities that will be copied over to new targets.
Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
- Target *GetDummyTarget();
+ Target *GetDummyTarget() { return m_dummy_target_sp.get(); }
lldb::BroadcasterManagerSP GetBroadcasterManager() {
return m_broadcaster_manager_sp;
@@ -345,9 +355,10 @@ protected:
void HandleThreadEvent(const lldb::EventSP &event_sp);
- size_t GetProcessSTDOUT(Process *process, Stream *stream);
-
- size_t GetProcessSTDERR(Process *process, Stream *stream);
+ // Ensures two threads don't attempt to flush process output in parallel.
+ std::mutex m_output_flush_mutex;
+ void FlushProcessOutput(Process &process, bool flush_stdout,
+ bool flush_stderr);
SourceManager::SourceFileCache &GetSourceFileCache() {
return m_source_file_cache;
@@ -355,9 +366,10 @@ protected:
void InstanceInitialize();
- lldb::StreamFileSP m_input_file_sp;
- lldb::StreamFileSP m_output_file_sp;
- lldb::StreamFileSP m_error_file_sp;
+ // these should never be NULL
+ lldb::FileSP m_input_file_sp;
+ lldb::StreamFileSP m_output_stream_sp;
+ lldb::StreamFileSP m_error_stream_sp;
/// Used for shadowing the input file when capturing a reproducer.
repro::DataRecorder *m_input_recorder;
@@ -399,6 +411,7 @@ protected:
Broadcaster m_sync_broadcaster;
lldb::ListenerSP m_forward_listener_sp;
llvm::once_flag m_clear_once;
+ lldb::TargetSP m_dummy_target_sp;
// Events for m_sync_broadcaster
enum {
diff --git a/include/lldb/Core/FileLineResolver.h b/include/lldb/Core/FileLineResolver.h
index 1967ed58cd3b..d6525b71bfdf 100644
--- a/include/lldb/Core/FileLineResolver.h
+++ b/include/lldb/Core/FileLineResolver.h
@@ -37,8 +37,8 @@ public:
~FileLineResolver() override;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override;
diff --git a/include/lldb/Core/FileSpecList.h b/include/lldb/Core/FileSpecList.h
index 79623ef1fdca..8edc3280b01b 100644
--- a/include/lldb/Core/FileSpecList.h
+++ b/include/lldb/Core/FileSpecList.h
@@ -25,6 +25,9 @@ class Stream;
/// A class that contains a mutable list of FileSpec objects.
class FileSpecList {
public:
+ typedef std::vector<FileSpec> collection;
+ typedef collection::const_iterator const_iterator;
+
/// Default constructor.
///
/// Initialize this object with an empty file list.
@@ -76,6 +79,15 @@ public:
/// \b true if the file was appended, \b false otherwise.
bool AppendIfUnique(const FileSpec &file);
+ /// Inserts a new FileSpec into the FileSpecList constructed in-place with
+ /// the given arguments.
+ ///
+ /// \param[in] args
+ /// Arguments to create the FileSpec
+ template <class... Args> void EmplaceBack(Args &&... args) {
+ m_files.emplace_back(std::forward<Args>(args)...);
+ }
+
/// Clears the file list.
void Clear();
@@ -182,9 +194,10 @@ public:
static size_t GetFilesMatchingPartialPath(const char *path, bool dir_okay,
FileSpecList &matches);
+ const_iterator begin() const { return m_files.begin(); }
+ const_iterator end() const { return m_files.end(); }
+
protected:
- typedef std::vector<FileSpec>
- collection; ///< The collection type for the file list.
collection m_files; ///< A collection of FileSpec objects.
};
diff --git a/include/lldb/Core/FormatEntity.h b/include/lldb/Core/FormatEntity.h
index 634d9df2ad83..ae6c402a45be 100644
--- a/include/lldb/Core/FormatEntity.h
+++ b/include/lldb/Core/FormatEntity.h
@@ -199,7 +199,7 @@ public:
llvm::StringRef &variable_name,
llvm::StringRef &variable_format);
- static size_t AutoComplete(lldb_private::CompletionRequest &request);
+ static void AutoComplete(lldb_private::CompletionRequest &request);
// Format the current elements into the stream \a s.
//
diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h
index b7180675cf4e..37142a5a8396 100644
--- a/include/lldb/Core/IOHandler.h
+++ b/include/lldb/Core/IOHandler.h
@@ -10,6 +10,7 @@
#define liblldb_IOHandler_h_
#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Flags.h"
#include "lldb/Utility/Predicate.h"
@@ -57,8 +58,7 @@ public:
IOHandler(Debugger &debugger, IOHandler::Type type);
IOHandler(Debugger &debugger, IOHandler::Type type,
- const lldb::StreamFileSP &input_sp,
- const lldb::StreamFileSP &output_sp,
+ const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp, uint32_t flags,
repro::DataRecorder *data_recorder);
@@ -122,11 +122,11 @@ public:
FILE *GetErrorFILE();
- lldb::StreamFileSP &GetInputStreamFile();
+ lldb::FileSP &GetInputFileSP();
- lldb::StreamFileSP &GetOutputStreamFile();
+ lldb::StreamFileSP &GetOutputStreamFileSP();
- lldb::StreamFileSP &GetErrorStreamFile();
+ lldb::StreamFileSP &GetErrorStreamFileSP();
Debugger &GetDebugger() { return m_debugger; }
@@ -164,7 +164,7 @@ public:
protected:
Debugger &m_debugger;
- lldb::StreamFileSP m_input_sp;
+ lldb::FileSP m_input_sp;
lldb::StreamFileSP m_output_sp;
lldb::StreamFileSP m_error_sp;
repro::DataRecorder *m_data_recorder;
@@ -198,10 +198,8 @@ public:
virtual void IOHandlerDeactivated(IOHandler &io_handler) {}
- virtual int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
- const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions);
+ virtual void IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request);
virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; }
@@ -334,7 +332,7 @@ public:
repro::DataRecorder *data_recorder);
IOHandlerEditline(Debugger &debugger, IOHandler::Type type,
- const lldb::StreamFileSP &input_sp,
+ const lldb::FileSP &input_sp,
const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp, uint32_t flags,
const char *editline_name, // Used for saving history files
@@ -350,7 +348,7 @@ public:
const char *, bool, bool, uint32_t,
IOHandlerDelegate &) = delete;
- IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::StreamFileSP &,
+ IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::FileSP &,
const lldb::StreamFileSP &, const lldb::StreamFileSP &,
uint32_t, const char *, const char *, const char *, bool,
bool, uint32_t, IOHandlerDelegate &) = delete;
@@ -415,11 +413,7 @@ private:
static int FixIndentationCallback(Editline *editline, const StringList &lines,
int cursor_position, void *baton);
- static int AutoCompleteCallback(const char *current_line, const char *cursor,
- const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions,
- void *baton);
+ static void AutoCompleteCallback(CompletionRequest &request, void *baton);
#endif
protected:
@@ -437,6 +431,7 @@ protected:
bool m_interrupt_exits;
bool m_editing; // Set to true when fetching a line manually (not using
// libedit)
+ std::string m_line_buffer;
};
// The order of base classes is important. Look at the constructor of
@@ -450,10 +445,8 @@ public:
bool GetResponse() const { return m_user_response; }
- int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
- const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions) override;
+ void IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) override;
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override;
diff --git a/include/lldb/Core/LoadedModuleInfoList.h b/include/lldb/Core/LoadedModuleInfoList.h
index f7f83604fc1a..04e58fcdf313 100644
--- a/include/lldb/Core/LoadedModuleInfoList.h
+++ b/include/lldb/Core/LoadedModuleInfoList.h
@@ -84,9 +84,6 @@ public:
}
bool operator==(LoadedModuleInfo const &rhs) const {
- if (e_num != rhs.e_num)
- return false;
-
for (size_t i = 0; i < e_num; ++i) {
if (m_has[i] != rhs.m_has[i])
return false;
diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h
index fb52afd6ed34..63fa0f618dae 100644
--- a/include/lldb/Core/Mangled.h
+++ b/include/lldb/Core/Mangled.h
@@ -49,21 +49,7 @@ public:
/// Default constructor.
///
/// Initialize with both mangled and demangled names empty.
- Mangled();
-
- /// Construct with name.
- ///
- /// Constructor with an optional string and a boolean indicating if it is
- /// the mangled version.
- ///
- /// \param[in] name
- /// The already const name to copy into this object.
- ///
- /// \param[in] is_mangled
- /// If \b true then \a name is a mangled name, if \b false then
- /// \a name is demangled.
- Mangled(ConstString name, bool is_mangled);
- Mangled(llvm::StringRef name, bool is_mangled);
+ Mangled() = default;
/// Construct with name.
///
@@ -76,12 +62,6 @@ public:
explicit Mangled(llvm::StringRef name);
- /// Destructor
- ///
- /// Releases its ref counts on the mangled and demangled strings that live
- /// in the global string pool.
- ~Mangled();
-
/// Convert to pointer operator.
///
/// This allows code to check a Mangled object to see if it contains a valid
diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h
index 544895ea89e9..89b731427e3f 100644
--- a/include/lldb/Core/Module.h
+++ b/include/lldb/Core/Module.h
@@ -49,7 +49,6 @@ class Symbol;
class SymbolContext;
class SymbolContextList;
class SymbolFile;
-class SymbolVendor;
class Symtab;
class Target;
class TypeList;
@@ -67,8 +66,8 @@ class VariableList;
/// accessors are called. For example the object file (ObjectFile)
/// representation will only be parsed if the object file is requested using
/// the Module::GetObjectFile() is called. The debug symbols will only be
-/// parsed if the symbol vendor (SymbolVendor) is requested using the
-/// Module::GetSymbolVendor() is called.
+/// parsed if the symbol file (SymbolFile) is requested using the
+/// Module::GetSymbolFile() method.
///
/// The module will parse more detailed information as more queries are made.
class Module : public std::enable_shared_from_this<Module>,
@@ -247,13 +246,13 @@ public:
ConstString name,
lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);
- size_t FindSymbolsWithNameAndType(ConstString name,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list);
+ void FindSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
- size_t FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list);
+ void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
/// Find a function symbols in the object file's symbol table.
///
@@ -267,11 +266,8 @@ public:
///
/// \param[out] sc_list
/// A list to append any matching symbol contexts to.
- ///
- /// \return
- /// The number of symbol contexts that were added to \a sc_list
- size_t FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
- SymbolContextList &sc_list);
+ void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
+ SymbolContextList &sc_list);
/// Find compile units by partial or full path.
///
@@ -281,19 +277,10 @@ public:
/// \param[in] path
/// The name of the function we are looking for.
///
- /// \param[in] append
- /// If \b true, then append any compile units that were found
- /// to \a sc_list. If \b false, then the \a sc_list is cleared
- /// and the contents of \a sc_list are replaced.
- ///
/// \param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
- ///
- /// \return
- /// The number of matches added to \a sc_list.
- size_t FindCompileUnits(const FileSpec &path, bool append,
- SymbolContextList &sc_list);
+ void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list);
/// Find functions by name.
///
@@ -313,21 +300,13 @@ public:
/// names, base names, C++ methods, or ObjC selectors.
/// See FunctionNameType for more details.
///
- /// \param[in] append
- /// If \b true, any matches will be appended to \a sc_list, else
- /// matches replace the contents of \a sc_list.
- ///
/// \param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
- ///
- /// \return
- /// The number of matches added to \a sc_list.
- size_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool symbols_ok,
- bool inlines_ok, bool append,
- SymbolContextList &sc_list);
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask, bool symbols_ok,
+ bool inlines_ok, SymbolContextList &sc_list);
/// Find functions by name.
///
@@ -345,12 +324,8 @@ public:
/// \param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
- ///
- /// \return
- /// The number of matches added to \a sc_list.
- size_t FindFunctions(const RegularExpression &regex, bool symbols_ok,
- bool inlines_ok, bool append,
- SymbolContextList &sc_list);
+ void FindFunctions(const RegularExpression &regex, bool symbols_ok,
+ bool inlines_ok, SymbolContextList &sc_list);
/// Find addresses by file/line
///
@@ -395,11 +370,9 @@ public:
/// \param[in] variable_list
/// A list of variables that gets the matches appended to.
///
- /// \return
- /// The number of matches added to \a variable_list.
- size_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches, VariableList &variable_list);
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, VariableList &variable_list);
/// Find global and static variables by regular expression.
///
@@ -413,17 +386,14 @@ public:
/// \param[in] variable_list
/// A list of variables that gets the matches appended to.
///
- /// \return
- /// The number of matches added to \a variable_list.
- size_t FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
- VariableList &variable_list);
+ void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
+ VariableList &variable_list);
/// Find types by name.
///
- /// Type lookups in modules go through the SymbolVendor (which will use one
- /// or more SymbolFile subclasses). The SymbolFile needs to be able to
- /// lookup types by basename and not the fully qualified typename. This
- /// allows the type accelerator tables to stay small, even with heavily
+ /// Type lookups in modules go through the SymbolFile. The SymbolFile needs to
+ /// be able to lookup types by basename and not the fully qualified typename.
+ /// This allows the type accelerator tables to stay small, even with heavily
/// templatized C++. The type search will then narrow down the search
/// results. If "exact_match" is true, then the type search will only match
/// exact type name matches. If "exact_match" is false, the type will match
@@ -449,13 +419,19 @@ public:
/// \param[out] type_list
/// A type list gets populated with any matches.
///
- /// \return
- /// The number of matches added to \a type_list.
- size_t
+ void
FindTypes(ConstString type_name, bool exact_match, size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeList &types);
+ /// Find types by name.
+ ///
+ /// This behaves like the other FindTypes method but allows to
+ /// specify a DeclContext and a language for the type being searched
+ /// for.
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types);
+
lldb::TypeSP FindFirstType(const SymbolContext &sc,
ConstString type_name, bool exact_match);
@@ -473,11 +449,9 @@ public:
/// \param[out] type_list
/// A type list gets populated with any matches.
///
- /// \return
- /// The number of matches added to \a type_list.
- size_t FindTypesInNamespace(ConstString type_name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches, TypeList &type_list);
+ void FindTypesInNamespace(ConstString type_name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, TypeList &type_list);
/// Get const accessor for the module architecture.
///
@@ -638,27 +612,19 @@ public:
ObjectFile *GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr, Status &error,
size_t size_to_read = 512);
- /// Get the symbol vendor interface for the current architecture.
- ///
- /// If the symbol vendor file has not been located yet, this function will
- /// find the best SymbolVendor plug-in that can use the current object file.
- ///
- /// \return
- /// If this module does not have a valid object file, or no
- /// plug-in can be found that can use the object file, nullptr will
- /// be returned, else a valid symbol vendor plug-in interface
- /// will be returned. The returned pointer is owned by this
- /// object and remains valid as long as the object is around.
- virtual SymbolVendor *
- GetSymbolVendor(bool can_create = true,
- lldb_private::Stream *feedback_strm = nullptr);
- /// Get accessor the type list for this module.
+ /// Get the module's symbol file
///
- /// \return
- /// A valid type list pointer, or nullptr if there is no valid
- /// symbol vendor for this module.
- TypeList *GetTypeList();
+ /// If the symbol file has already been loaded, this function returns it. All
+ /// arguments are ignored. If the symbol file has not been located yet, and
+ /// the can_create argument is false, the function returns nullptr. If
+ /// can_create is true, this function will find the best SymbolFile plug-in
+ /// that can use the current object file. feedback_strm, if not null, is used
+ /// to report the details of the search process.
+ virtual SymbolFile *GetSymbolFile(bool can_create = true,
+ Stream *feedback_strm = nullptr);
+
+ Symtab *GetSymtab();
/// Get a reference to the UUID value contained in this object.
///
@@ -819,7 +785,8 @@ public:
bool GetIsDynamicLinkEditor();
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language);
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language);
// Special error functions that can do printf style formatting that will
// prepend the message with something appropriate for this module (like the
@@ -848,7 +815,7 @@ public:
// when the module first gets created.
bool FileHasChanged() const;
- // SymbolVendor, SymbolFile and ObjectFile member objects should lock the
+ // SymbolFile and ObjectFile member objects should lock the
// module mutex to avoid deadlocks.
std::recursive_mutex &GetMutex() const { return m_mutex; }
@@ -896,16 +863,19 @@ public:
bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const;
bool RemapSourceFile(const char *, std::string &) const = delete;
+ /// Update the ArchSpec to a more specific variant.
+ bool MergeArchitecture(const ArchSpec &arch_spec);
+
/// \class LookupInfo Module.h "lldb/Core/Module.h"
/// A class that encapsulates name lookup information.
///
/// Users can type a wide variety of partial names when setting breakpoints
- /// by name or when looking for functions by name. SymbolVendor and
- /// SymbolFile objects are only required to implement name lookup for
- /// function basenames and for fully mangled names. This means if the user
- /// types in a partial name, we must reduce this to a name lookup that will
- /// work with all SymbolFile objects. So we might reduce a name lookup to
- /// look for a basename, and then prune out any results that don't match.
+ /// by name or when looking for functions by name. The SymbolFile object is
+ /// only required to implement name lookup for function basenames and for
+ /// fully mangled names. This means if the user types in a partial name, we
+ /// must reduce this to a name lookup that will work with all SymbolFile
+ /// objects. So we might reduce a name lookup to look for a basename, and then
+ /// prune out any results that don't match.
///
/// The "m_name" member variable represents the name as it was typed by the
/// user. "m_lookup_name" will be the name we actually search for through
@@ -1012,7 +982,7 @@ protected:
/// ObjectFile instances for the debug info
std::atomic<bool> m_did_load_objfile{false};
- std::atomic<bool> m_did_load_symbol_vendor{false};
+ std::atomic<bool> m_did_load_symfile{false};
std::atomic<bool> m_did_set_uuid{false};
mutable bool m_file_has_changed : 1,
m_first_file_changed_log : 1; /// See if the module was modified after it
@@ -1072,9 +1042,9 @@ protected:
private:
Module(); // Only used internally by CreateJITModule ()
- size_t FindTypes_Impl(
+ void FindTypes_Impl(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches,
+ size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types);
diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h
index 1e26c35e4c15..e21655551b61 100644
--- a/include/lldb/Core/ModuleList.h
+++ b/include/lldb/Core/ModuleList.h
@@ -247,35 +247,24 @@ public:
/// \param[in] path
/// The name of the compile unit we are looking for.
///
- /// \param[in] append
- /// If \b true, then append any compile units that were found
- /// to \a sc_list. If \b false, then the \a sc_list is cleared
- /// and the contents of \a sc_list are replaced.
- ///
/// \param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
- ///
- /// \return
- /// The number of matches added to \a sc_list.
- size_t FindCompileUnits(const FileSpec &path, bool append,
- SymbolContextList &sc_list) const;
+ void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const;
/// \see Module::FindFunctions ()
- size_t FindFunctions(ConstString name,
- lldb::FunctionNameType name_type_mask,
- bool include_symbols, bool include_inlines, bool append,
- SymbolContextList &sc_list) const;
+ void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask,
+ bool include_symbols, bool include_inlines,
+ SymbolContextList &sc_list) const;
/// \see Module::FindFunctionSymbols ()
- size_t FindFunctionSymbols(ConstString name,
- lldb::FunctionNameType name_type_mask,
- SymbolContextList &sc_list);
+ void FindFunctionSymbols(ConstString name,
+ lldb::FunctionNameType name_type_mask,
+ SymbolContextList &sc_list);
/// \see Module::FindFunctions ()
- size_t FindFunctions(const RegularExpression &name, bool include_symbols,
- bool include_inlines, bool append,
- SymbolContextList &sc_list);
+ void FindFunctions(const RegularExpression &name, bool include_symbols,
+ bool include_inlines, SymbolContextList &sc_list);
/// Find global and static variables by name.
///
@@ -289,11 +278,8 @@ public:
///
/// \param[in] variable_list
/// A list of variables that gets the matches appended to.
- ///
- /// \return
- /// The number of matches added to \a variable_list.
- size_t FindGlobalVariables(ConstString name, size_t max_matches,
- VariableList &variable_list) const;
+ void FindGlobalVariables(ConstString name, size_t max_matches,
+ VariableList &variable_list) const;
/// Find global and static variables by regular expression.
///
@@ -306,11 +292,8 @@ public:
///
/// \param[in] variable_list
/// A list of variables that gets the matches appended to.
- ///
- /// \return
- /// The number of matches added to \a variable_list.
- size_t FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
- VariableList &variable_list) const;
+ void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
+ VariableList &variable_list) const;
/// Finds the first module whose file specification matches \a file_spec.
///
@@ -337,11 +320,8 @@ public:
/// \param[out] matching_module_list
/// A module list that gets filled in with any modules that
/// match the search criteria.
- ///
- /// \return
- /// The number of matching modules found by the search.
- size_t FindModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) const;
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const;
lldb::ModuleSP FindModule(const Module *module_ptr) const;
@@ -354,15 +334,13 @@ public:
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const;
- size_t FindSymbolsWithNameAndType(ConstString name,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list,
- bool append = false) const;
+ void FindSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list) const;
- size_t FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list,
- bool append = false) const;
+ void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list) const;
/// Find types by name.
///
@@ -393,12 +371,10 @@ public:
/// \param[out] type_list
/// A type list gets populated with any matches.
///
- /// \return
- /// The number of matches added to \a type_list.
- size_t FindTypes(Module *search_first, ConstString name,
- bool name_is_fully_qualified, size_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeList &types) const;
+ void FindTypes(Module *search_first, ConstString name,
+ bool name_is_fully_qualified, size_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeList &types) const;
bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
@@ -476,6 +452,7 @@ public:
/// \return
/// The number of modules in the module list.
size_t GetSize() const;
+ bool IsEmpty() const { return !GetSize(); }
bool LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors,
Stream *feedback_stream = nullptr,
@@ -494,8 +471,8 @@ public:
static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
- static size_t FindSharedModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list);
+ static void FindSharedModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list);
static size_t RemoveOrphanSharedModules(bool mandatory);
diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h
index ab0f4e9912a8..651d0dc869bc 100644
--- a/include/lldb/Core/ModuleSpec.h
+++ b/include/lldb/Core/ModuleSpec.h
@@ -380,8 +380,8 @@ public:
return false;
}
- size_t FindMatchingModuleSpecs(const ModuleSpec &module_spec,
- ModuleSpecList &matching_list) const {
+ void FindMatchingModuleSpecs(const ModuleSpec &module_spec,
+ ModuleSpecList &matching_list) const {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
bool exact_arch_match = true;
const size_t initial_match_count = matching_list.GetSize();
@@ -400,7 +400,6 @@ public:
matching_list.Append(spec);
}
}
- return matching_list.GetSize() - initial_match_count;
}
void Dump(Stream &strm) {
diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h
index 1bac1e5df694..5b859752b3c7 100644
--- a/include/lldb/Core/PluginManager.h
+++ b/include/lldb/Core/PluginManager.h
@@ -10,6 +10,8 @@
#define liblldb_PluginManager_h_
#include "lldb/Core/Architecture.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
@@ -228,8 +230,8 @@ public:
static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx);
- static size_t AutoCompletePlatformName(llvm::StringRef partial_name,
- StringList &matches);
+ static void AutoCompletePlatformName(llvm::StringRef partial_name,
+ CompletionRequest &request);
// Process
static bool
RegisterPlugin(ConstString name, const char *description,
@@ -383,10 +385,10 @@ public:
GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name);
// TypeSystem
- static bool RegisterPlugin(
- ConstString name, const char *description,
- TypeSystemCreateInstance create_callback,
- TypeSystemEnumerateSupportedLanguages enumerate_languages_callback);
+ static bool RegisterPlugin(ConstString name, const char *description,
+ TypeSystemCreateInstance create_callback,
+ LanguageSet supported_languages_for_types,
+ LanguageSet supported_languages_for_expressions);
static bool UnregisterPlugin(TypeSystemCreateInstance create_callback);
@@ -396,18 +398,14 @@ public:
static TypeSystemCreateInstance
GetTypeSystemCreateCallbackForPluginName(ConstString name);
- static TypeSystemEnumerateSupportedLanguages
- GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx);
+ static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes();
- static TypeSystemEnumerateSupportedLanguages
- GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
- ConstString name);
+ static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions();
// REPL
- static bool
- RegisterPlugin(ConstString name, const char *description,
- REPLCreateInstance create_callback,
- REPLEnumerateSupportedLanguages enumerate_languages_callback);
+ static bool RegisterPlugin(ConstString name, const char *description,
+ REPLCreateInstance create_callback,
+ LanguageSet supported_languages);
static bool UnregisterPlugin(REPLCreateInstance create_callback);
@@ -416,12 +414,7 @@ public:
static REPLCreateInstance
GetREPLCreateCallbackForPluginName(ConstString name);
- static REPLEnumerateSupportedLanguages
- GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx);
-
- static REPLEnumerateSupportedLanguages
- GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
- ConstString name);
+ static LanguageSet GetREPLAllTypeSystemSupportedLanguages();
// Some plug-ins might register a DebuggerInitializeCallback callback when
// registering the plug-in. After a new Debugger instance is created, this
@@ -439,32 +432,28 @@ public:
ConstString description, bool is_global_property);
static lldb::OptionValuePropertiesSP
- GetSettingForPlatformPlugin(Debugger &debugger,
- ConstString setting_name);
+ GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name);
static bool CreateSettingForPlatformPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);
static lldb::OptionValuePropertiesSP
- GetSettingForProcessPlugin(Debugger &debugger,
- ConstString setting_name);
+ GetSettingForProcessPlugin(Debugger &debugger, ConstString setting_name);
static bool CreateSettingForProcessPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);
static lldb::OptionValuePropertiesSP
- GetSettingForSymbolFilePlugin(Debugger &debugger,
- ConstString setting_name);
+ GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name);
static bool CreateSettingForSymbolFilePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
ConstString description, bool is_global_property);
static lldb::OptionValuePropertiesSP
- GetSettingForJITLoaderPlugin(Debugger &debugger,
- ConstString setting_name);
+ GetSettingForJITLoaderPlugin(Debugger &debugger, ConstString setting_name);
static bool CreateSettingForJITLoaderPlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
diff --git a/include/lldb/Core/PropertiesBase.td b/include/lldb/Core/PropertiesBase.td
new file mode 100644
index 000000000000..be97d44ae8e4
--- /dev/null
+++ b/include/lldb/Core/PropertiesBase.td
@@ -0,0 +1,49 @@
+// Base class for all options.
+class Property<string name, string type> {
+ string Name = name;
+ string Type = type;
+ string Definition;
+}
+
+// Sets the description for the property that should be displayed to the user.
+class Desc<string description> {
+ string Description = description;
+}
+
+// Marks the property as global.
+class Global {
+ bit Global = 1;
+}
+
+class DefaultTrue {
+ int DefaultUnsignedValue = 1;
+ bit HasDefaultUnsignedValue = 1;
+}
+
+class DefaultFalse {
+ int DefaultUnsignedValue = 0;
+ bit HasDefaultUnsignedValue = 1;
+}
+
+// Gives the property a default string value.
+class DefaultStringValue<string value> {
+ string DefaultStringValue = value;
+ bit HasDefaultStringValue = 1;
+}
+
+// Gives the property a default enum value.
+class DefaultEnumValue<string value> {
+ string DefaultEnumValue = value;
+ bit HasDefaultEnumValue = 1;
+}
+
+// Gives the property a default string value.
+class DefaultUnsignedValue<int value> {
+ int DefaultUnsignedValue = value;
+ bit HasDefaultUnsignedValue = 1;
+}
+
+// Gives the property enum values.
+class EnumValues<string enum> {
+ string EnumValues = enum;
+}
diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h
index f38690c95f52..6823daf9e3ed 100644
--- a/include/lldb/Core/SearchFilter.h
+++ b/include/lldb/Core/SearchFilter.h
@@ -52,8 +52,8 @@ public:
virtual ~Searcher();
virtual CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool complete) = 0;
+ SymbolContext &context,
+ Address *addr) = 0;
virtual lldb::SearchDepth GetDepth() = 0;
diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h
index 881d43702cee..509a0767be1d 100644
--- a/include/lldb/Core/Section.h
+++ b/include/lldb/Core/Section.h
@@ -43,9 +43,8 @@ public:
const_iterator begin() { return m_sections.begin(); }
const_iterator end() { return m_sections.end(); }
- SectionList();
-
- ~SectionList();
+ /// Create an empty list.
+ SectionList() = default;
SectionList &operator=(const SectionList &rhs);
diff --git a/include/lldb/Core/StreamFile.h b/include/lldb/Core/StreamFile.h
index 54aeab16b3f1..712b289aa8d9 100644
--- a/include/lldb/Core/StreamFile.h
+++ b/include/lldb/Core/StreamFile.h
@@ -30,23 +30,27 @@ public:
StreamFile(const char *path);
- StreamFile(const char *path, uint32_t options,
+ StreamFile(const char *path, File::OpenOptions options,
uint32_t permissions = lldb::eFilePermissionsFileDefault);
StreamFile(FILE *fh, bool transfer_ownership);
+ StreamFile(std::shared_ptr<File> file) : m_file_sp(file) { assert(file); };
+
~StreamFile() override;
- File &GetFile() { return m_file; }
+ File &GetFile() { return *m_file_sp; }
+
+ const File &GetFile() const { return *m_file_sp; }
- const File &GetFile() const { return m_file; }
+ std::shared_ptr<File> GetFileSP() { return m_file_sp; }
void Flush() override;
protected:
// Classes that inherit from StreamFile can see and modify these
- File m_file;
+ std::shared_ptr<File> m_file_sp; // never NULL
size_t WriteImpl(const void *s, size_t length) override;
private:
diff --git a/include/lldb/Core/StructuredDataImpl.h b/include/lldb/Core/StructuredDataImpl.h
index 79a709af7ca3..c66e4736dc26 100644
--- a/include/lldb/Core/StructuredDataImpl.h
+++ b/include/lldb/Core/StructuredDataImpl.h
@@ -54,7 +54,8 @@ public:
return error;
}
- m_data_sp->Dump(stream);
+ llvm::json::OStream s(stream.AsRawOstream());
+ m_data_sp->Serialize(s);
return error;
}
diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h
index b786e4866f6c..7b4cc3b71c28 100644
--- a/include/lldb/Core/Value.h
+++ b/include/lldb/Core/Value.h
@@ -210,7 +210,6 @@ public:
uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
- uint32_t data_offset,
Module *module); // Can be nullptr
static const char *GetValueTypeAsCString(ValueType context_type);
diff --git a/include/lldb/Core/dwarf.h b/include/lldb/Core/dwarf.h
index afe62e09fe16..832109e55c70 100644
--- a/include/lldb/Core/dwarf.h
+++ b/include/lldb/Core/dwarf.h
@@ -22,7 +22,7 @@ typedef uint32_t dw_uleb128_t;
typedef int32_t dw_sleb128_t;
typedef uint16_t dw_attr_t;
typedef uint16_t dw_form_t;
-typedef uint16_t dw_tag_t;
+typedef llvm::dwarf::Tag dw_tag_t;
typedef uint64_t dw_addr_t; // Dwarf address define that must be big enough for
// any addresses in the compile units that get
// parsed
diff --git a/include/lldb/DataFormatters/FormattersContainer.h b/include/lldb/DataFormatters/FormattersContainer.h
index 9d7d37343ac2..de2edb103151 100644
--- a/include/lldb/DataFormatters/FormattersContainer.h
+++ b/include/lldb/DataFormatters/FormattersContainer.h
@@ -47,7 +47,7 @@ static inline ConstString GetValidTypeName_Impl(ConstString type) {
return type;
std::string type_cstr(type.AsCString());
- lldb_utility::StringLexer type_lexer(type_cstr);
+ StringLexer type_lexer(type_cstr);
type_lexer.AdvanceIf("class ");
type_lexer.AdvanceIf("enum ");
@@ -65,9 +65,9 @@ template <typename KeyType, typename ValueType> class FormattersContainer;
template <typename KeyType, typename ValueType> class FormatMap {
public:
typedef typename ValueType::SharedPointer ValueSP;
- typedef std::map<KeyType, ValueSP> MapType;
+ typedef std::vector<std::pair<KeyType, ValueSP>> MapType;
typedef typename MapType::iterator MapIterator;
- typedef std::function<bool(KeyType, const ValueSP &)> ForEachCallback;
+ typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback;
FormatMap(IFormatChangeListener *lst)
: m_map(), m_map_mutex(), listener(lst) {}
@@ -79,20 +79,22 @@ public:
entry->GetRevision() = 0;
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- m_map[name] = entry;
+ Delete(name);
+ m_map.emplace_back(std::move(name), std::move(entry));
if (listener)
listener->Changed();
}
- bool Delete(KeyType name) {
+ bool Delete(const KeyType &name) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- m_map.erase(name);
- if (listener)
- listener->Changed();
- return true;
+ for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter)
+ if (iter->first == name) {
+ m_map.erase(iter);
+ if (listener)
+ listener->Changed();
+ return true;
+ }
+ return false;
}
void Clear() {
@@ -102,22 +104,22 @@ public:
listener->Changed();
}
- bool Get(KeyType name, ValueSP &entry) {
+ bool Get(const KeyType &name, ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- entry = iter->second;
- return true;
+ for (const auto &pos : m_map)
+ if (pos.first == name) {
+ entry = pos.second;
+ return true;
+ }
+ return false;
}
void ForEach(ForEachCallback callback) {
if (callback) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator pos, end = m_map.end();
- for (pos = m_map.begin(); pos != end; pos++) {
- KeyType type = pos->first;
- if (!callback(type, pos->second))
+ for (const auto &pos : m_map) {
+ const KeyType &type = pos.first;
+ if (!callback(type, pos.second))
break;
}
}
@@ -127,28 +129,17 @@ public:
ValueSP GetValueAtIndex(size_t index) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator iter = m_map.begin();
- MapIterator end = m_map.end();
- while (index > 0) {
- iter++;
- index--;
- if (end == iter)
- return ValueSP();
- }
- return iter->second;
+ if (index >= m_map.size())
+ return ValueSP();
+ return m_map[index].second;
}
+ // If caller holds the mutex we could return a reference without copy ctor.
KeyType GetKeyAtIndex(size_t index) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator iter = m_map.begin();
- MapIterator end = m_map.end();
- while (index > 0) {
- iter++;
- index--;
- if (end == iter)
- return KeyType();
- }
- return iter->first;
+ if (index >= m_map.size())
+ return {};
+ return m_map[index].first;
}
protected:
@@ -171,8 +162,8 @@ protected:
public:
typedef typename BackEndType::MapType MapType;
typedef typename MapType::iterator MapIterator;
- typedef typename MapType::key_type MapKeyType;
- typedef typename MapType::mapped_type MapValueType;
+ typedef KeyType MapKeyType;
+ typedef std::shared_ptr<ValueType> MapValueType;
typedef typename BackEndType::ForEachCallback ForEachCallback;
typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>>
SharedPointer;
@@ -182,8 +173,8 @@ public:
FormattersContainer(std::string name, IFormatChangeListener *lst)
: m_format_map(lst), m_name(name) {}
- void Add(const MapKeyType &type, const MapValueType &entry) {
- Add_Impl(type, entry, static_cast<KeyType *>(nullptr));
+ void Add(MapKeyType type, const MapValueType &entry) {
+ Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr));
}
bool Delete(ConstString type) {
@@ -233,9 +224,9 @@ protected:
DISALLOW_COPY_AND_ASSIGN(FormattersContainer);
- void Add_Impl(const MapKeyType &type, const MapValueType &entry,
- lldb::RegularExpressionSP *dummy) {
- m_format_map.Add(type, entry);
+ void Add_Impl(MapKeyType type, const MapValueType &entry,
+ RegularExpression *dummy) {
+ m_format_map.Add(std::move(type), entry);
}
void Add_Impl(ConstString type, const MapValueType &entry,
@@ -247,12 +238,12 @@ protected:
return m_format_map.Delete(type);
}
- bool Delete_Impl(ConstString type, lldb::RegularExpressionSP *dummy) {
+ bool Delete_Impl(ConstString type, RegularExpression *dummy) {
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
MapIterator pos, end = m_format_map.map().end();
for (pos = m_format_map.map().begin(); pos != end; pos++) {
- lldb::RegularExpressionSP regex = pos->first;
- if (type.GetStringRef() == regex->GetText()) {
+ const RegularExpression &regex = pos->first;
+ if (type.GetStringRef() == regex.GetText()) {
m_format_map.map().erase(pos);
if (m_format_map.listener)
m_format_map.listener->Changed();
@@ -282,24 +273,23 @@ protected:
}
lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex_Impl(size_t index,
- lldb::RegularExpressionSP *dummy) {
- lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
- if (regex.get() == nullptr)
+ GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) {
+ RegularExpression regex = m_format_map.GetKeyAtIndex(index);
+ if (regex == RegularExpression())
return lldb::TypeNameSpecifierImplSP();
return lldb::TypeNameSpecifierImplSP(
- new TypeNameSpecifierImpl(regex->GetText().str().c_str(), true));
+ new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true));
}
bool Get_Impl(ConstString key, MapValueType &value,
- lldb::RegularExpressionSP *dummy) {
+ RegularExpression *dummy) {
llvm::StringRef key_str = key.GetStringRef();
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++) {
- lldb::RegularExpressionSP regex = pos->first;
- if (regex->Execute(key_str)) {
- value = pos->second;
+ // Patterns are matched in reverse-chronological order.
+ for (const auto &pos : llvm::reverse(m_format_map.map())) {
+ const RegularExpression &regex = pos.first;
+ if (regex.Execute(key_str)) {
+ value = pos.second;
return true;
}
}
@@ -307,13 +297,12 @@ protected:
}
bool GetExact_Impl(ConstString key, MapValueType &value,
- lldb::RegularExpressionSP *dummy) {
+ RegularExpression *dummy) {
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++) {
- lldb::RegularExpressionSP regex = pos->first;
- if (regex->GetText() == key.GetStringRef()) {
- value = pos->second;
+ for (const auto &pos : m_format_map.map()) {
+ const RegularExpression &regex = pos.first;
+ if (regex.GetText() == key.GetStringRef()) {
+ value = pos.second;
return true;
}
}
diff --git a/include/lldb/DataFormatters/StringPrinter.h b/include/lldb/DataFormatters/StringPrinter.h
index 41d5edd88021..43b92019e6fd 100644
--- a/include/lldb/DataFormatters/StringPrinter.h
+++ b/include/lldb/DataFormatters/StringPrinter.h
@@ -24,238 +24,121 @@ public:
enum class GetPrintableElementType { ASCII, UTF8 };
- class ReadStringAndDumpToStreamOptions {
+ class DumpToStreamOptions {
public:
- ReadStringAndDumpToStreamOptions()
- : m_location(0), m_process_sp(), m_stream(nullptr), m_prefix_token(),
- m_suffix_token(), m_quote('"'), m_source_size(0),
- m_needs_zero_termination(true), m_escape_non_printables(true),
- m_ignore_max_length(false), m_zero_is_terminator(true),
- m_language_type(lldb::eLanguageTypeUnknown) {}
+ DumpToStreamOptions() = default;
- ReadStringAndDumpToStreamOptions(ValueObject &valobj);
-
- ReadStringAndDumpToStreamOptions &SetLocation(uint64_t l) {
- m_location = l;
- return *this;
- }
-
- uint64_t GetLocation() const { return m_location; }
-
- ReadStringAndDumpToStreamOptions &SetProcessSP(lldb::ProcessSP p) {
- m_process_sp = p;
- return *this;
- }
-
- lldb::ProcessSP GetProcessSP() const { return m_process_sp; }
-
- ReadStringAndDumpToStreamOptions &SetStream(Stream *s) {
- m_stream = s;
- return *this;
- }
+ void SetStream(Stream *s) { m_stream = s; }
Stream *GetStream() const { return m_stream; }
- ReadStringAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
- m_prefix_token = p;
- return *this;
- }
+ void SetPrefixToken(const std::string &p) { m_prefix_token = p; }
- ReadStringAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
- m_prefix_token.clear();
- return *this;
- }
+ void SetPrefixToken(std::nullptr_t) { m_prefix_token.clear(); }
const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
- ReadStringAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
- m_suffix_token = p;
- return *this;
- }
+ void SetSuffixToken(const std::string &p) { m_suffix_token = p; }
- ReadStringAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
- m_suffix_token.clear();
- return *this;
- }
+ void SetSuffixToken(std::nullptr_t) { m_suffix_token.clear(); }
const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
- ReadStringAndDumpToStreamOptions &SetQuote(char q) {
- m_quote = q;
- return *this;
- }
+ void SetQuote(char q) { m_quote = q; }
char GetQuote() const { return m_quote; }
- ReadStringAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
- m_source_size = s;
- return *this;
- }
+ void SetSourceSize(uint32_t s) { m_source_size = s; }
uint32_t GetSourceSize() const { return m_source_size; }
- ReadStringAndDumpToStreamOptions &SetNeedsZeroTermination(bool z) {
- m_needs_zero_termination = z;
- return *this;
- }
+ void SetNeedsZeroTermination(bool z) { m_needs_zero_termination = z; }
bool GetNeedsZeroTermination() const { return m_needs_zero_termination; }
- ReadStringAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
- m_zero_is_terminator = e;
- return *this;
- }
+ void SetBinaryZeroIsTerminator(bool e) { m_zero_is_terminator = e; }
bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
- ReadStringAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
- m_escape_non_printables = e;
- return *this;
- }
+ void SetEscapeNonPrintables(bool e) { m_escape_non_printables = e; }
bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
- ReadStringAndDumpToStreamOptions &SetIgnoreMaxLength(bool e) {
- m_ignore_max_length = e;
- return *this;
- }
+ void SetIgnoreMaxLength(bool e) { m_ignore_max_length = e; }
bool GetIgnoreMaxLength() const { return m_ignore_max_length; }
- ReadStringAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
- m_language_type = l;
- return *this;
- }
-
- lldb::LanguageType GetLanguage() const
+ void SetLanguage(lldb::LanguageType l) { m_language_type = l; }
- {
- return m_language_type;
- }
+ lldb::LanguageType GetLanguage() const { return m_language_type; }
private:
- uint64_t m_location;
- lldb::ProcessSP m_process_sp;
- Stream *m_stream;
+ /// The used output stream.
+ Stream *m_stream = nullptr;
+ /// String that should be printed before the heading quote character.
std::string m_prefix_token;
+ /// String that should be printed after the trailing quote character.
std::string m_suffix_token;
- char m_quote;
- uint32_t m_source_size;
- bool m_needs_zero_termination;
- bool m_escape_non_printables;
- bool m_ignore_max_length;
- bool m_zero_is_terminator;
- lldb::LanguageType m_language_type;
+ /// The quote character that should surround the string.
+ char m_quote = '"';
+ /// The length of the memory region that should be dumped in bytes.
+ uint32_t m_source_size = 0;
+ bool m_needs_zero_termination = true;
+ /// True iff non-printable characters should be escaped when dumping
+ /// them to the stream.
+ bool m_escape_non_printables = true;
+ /// True iff the max-string-summary-length setting of the target should
+ /// be ignored.
+ bool m_ignore_max_length = false;
+ /// True iff a zero bytes ('\0') should terminate the memory region that
+ /// is being dumped.
+ bool m_zero_is_terminator = true;
+ /// The language that the generated string literal is supposed to be valid
+ /// for. This changes for example what and how certain characters are
+ /// escaped.
+ /// For example, printing the a string containing only a quote (") char
+ /// with eLanguageTypeC would escape the quote character.
+ lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
};
- class ReadBufferAndDumpToStreamOptions {
+ class ReadStringAndDumpToStreamOptions : public DumpToStreamOptions {
public:
- ReadBufferAndDumpToStreamOptions()
- : m_data(), m_stream(nullptr), m_prefix_token(), m_suffix_token(),
- m_quote('"'), m_source_size(0), m_escape_non_printables(true),
- m_zero_is_terminator(true), m_is_truncated(false),
- m_language_type(lldb::eLanguageTypeUnknown) {}
+ ReadStringAndDumpToStreamOptions() = default;
- ReadBufferAndDumpToStreamOptions(ValueObject &valobj);
-
- ReadBufferAndDumpToStreamOptions(
- const ReadStringAndDumpToStreamOptions &options);
-
- ReadBufferAndDumpToStreamOptions &SetData(DataExtractor d) {
- m_data = d;
- return *this;
- }
-
- lldb_private::DataExtractor GetData() const { return m_data; }
-
- ReadBufferAndDumpToStreamOptions &SetStream(Stream *s) {
- m_stream = s;
- return *this;
- }
-
- Stream *GetStream() const { return m_stream; }
-
- ReadBufferAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
- m_prefix_token = p;
- return *this;
- }
-
- ReadBufferAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
- m_prefix_token.clear();
- return *this;
- }
-
- const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
-
- ReadBufferAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
- m_suffix_token = p;
- return *this;
- }
+ ReadStringAndDumpToStreamOptions(ValueObject &valobj);
- ReadBufferAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
- m_suffix_token.clear();
- return *this;
- }
+ void SetLocation(uint64_t l) { m_location = l; }
- const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
+ uint64_t GetLocation() const { return m_location; }
- ReadBufferAndDumpToStreamOptions &SetQuote(char q) {
- m_quote = q;
- return *this;
- }
+ void SetProcessSP(lldb::ProcessSP p) { m_process_sp = p; }
- char GetQuote() const { return m_quote; }
+ lldb::ProcessSP GetProcessSP() const { return m_process_sp; }
- ReadBufferAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
- m_source_size = s;
- return *this;
- }
+ private:
+ uint64_t m_location = 0;
+ lldb::ProcessSP m_process_sp;
+ };
- uint32_t GetSourceSize() const { return m_source_size; }
+ class ReadBufferAndDumpToStreamOptions : public DumpToStreamOptions {
+ public:
+ ReadBufferAndDumpToStreamOptions() = default;
- ReadBufferAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
- m_escape_non_printables = e;
- return *this;
- }
+ ReadBufferAndDumpToStreamOptions(ValueObject &valobj);
- bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
+ ReadBufferAndDumpToStreamOptions(
+ const ReadStringAndDumpToStreamOptions &options);
- ReadBufferAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
- m_zero_is_terminator = e;
- return *this;
- }
+ void SetData(DataExtractor d) { m_data = d; }
- bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
+ lldb_private::DataExtractor GetData() const { return m_data; }
- ReadBufferAndDumpToStreamOptions &SetIsTruncated(bool t) {
- m_is_truncated = t;
- return *this;
- }
+ void SetIsTruncated(bool t) { m_is_truncated = t; }
bool GetIsTruncated() const { return m_is_truncated; }
-
- ReadBufferAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
- m_language_type = l;
- return *this;
- }
-
- lldb::LanguageType GetLanguage() const
-
- {
- return m_language_type;
- }
-
private:
DataExtractor m_data;
- Stream *m_stream;
- std::string m_prefix_token;
- std::string m_suffix_token;
- char m_quote;
- uint32_t m_source_size;
- bool m_escape_non_printables;
- bool m_zero_is_terminator;
- bool m_is_truncated;
- lldb::LanguageType m_language_type;
+ bool m_is_truncated = false;
};
// I can't use a std::unique_ptr for this because the Deleter is a template
diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h
index bdb393abd848..a5438226bbbb 100644
--- a/include/lldb/DataFormatters/TypeCategory.h
+++ b/include/lldb/DataFormatters/TypeCategory.h
@@ -26,7 +26,7 @@ namespace lldb_private {
template <typename FormatterImpl> class FormatterContainerPair {
public:
typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
- typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl>
+ typedef FormattersContainer<RegularExpression, FormatterImpl>
RegexMatchContainer;
typedef typename ExactMatchContainer::MapType ExactMatchMap;
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
index 21830a562800..44015b4e418f 100644
--- a/include/lldb/Expression/DWARFExpression.h
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -50,15 +50,8 @@ public:
/// \param[in] data
/// A data extractor configured to read the DWARF location expression's
/// bytecode.
- ///
- /// \param[in] data_offset
- /// The offset of the location expression in the extractor.
- ///
- /// \param[in] data_length
- /// The byte length of the location expression.
DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
- const DWARFUnit *dwarf_cu, lldb::offset_t data_offset,
- lldb::offset_t data_length);
+ const DWARFUnit *dwarf_cu);
/// Destructor
virtual ~DWARFExpression();
@@ -211,12 +204,6 @@ public:
/// in the case where an expression needs to be evaluated while building
/// the stack frame list, this short-cut is available.
///
- /// \param[in] offset
- /// The offset of the location expression in the data extractor.
- ///
- /// \param[in] length
- /// The length in bytes of the location expression.
- ///
/// \param[in] reg_set
/// The call-frame-info style register kind.
///
@@ -236,8 +223,7 @@ public:
/// details of the failure are provided through it.
static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
- const DWARFUnit *dwarf_cu, const lldb::offset_t offset,
- const lldb::offset_t length,
+ const DWARFUnit *dwarf_cu,
const lldb::RegisterKind reg_set,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
@@ -252,10 +238,6 @@ public:
lldb::addr_t loclist_base_load_addr,
lldb::addr_t address, ABI *abi);
- static size_t LocationListSize(const DWARFUnit *dwarf_cu,
- const DataExtractor &debug_loc_data,
- lldb::offset_t offset);
-
static bool PrintDWARFExpression(Stream &s, const DataExtractor &data,
int address_size, int dwarf_ref_size,
bool location_expression);
diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h
index 7e3e2bb8606a..e5aecce08727 100644
--- a/include/lldb/Expression/DiagnosticManager.h
+++ b/include/lldb/Expression/DiagnosticManager.h
@@ -12,6 +12,7 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -23,7 +24,6 @@ enum DiagnosticOrigin {
eDiagnosticOriginUnknown = 0,
eDiagnosticOriginLLDB,
eDiagnosticOriginClang,
- eDiagnosticOriginGo,
eDiagnosticOriginSwift,
eDiagnosticOriginLLVM
};
@@ -47,7 +47,6 @@ public:
switch (kind) {
case eDiagnosticOriginUnknown:
case eDiagnosticOriginLLDB:
- case eDiagnosticOriginGo:
case eDiagnosticOriginLLVM:
return true;
case eDiagnosticOriginClang:
@@ -89,7 +88,7 @@ protected:
uint32_t m_compiler_id; // Compiler-specific diagnostic ID
};
-typedef std::vector<Diagnostic *> DiagnosticList;
+typedef std::vector<std::unique_ptr<Diagnostic>> DiagnosticList;
class DiagnosticManager {
public:
@@ -98,45 +97,33 @@ public:
m_fixed_expression.clear();
}
- // The diagnostic manager holds a list of diagnostics, which are owned by the
- // manager.
const DiagnosticList &Diagnostics() { return m_diagnostics; }
- ~DiagnosticManager() {
- for (Diagnostic *diag : m_diagnostics) {
- delete diag;
- }
- }
-
- bool HasFixIts() {
- for (Diagnostic *diag : m_diagnostics) {
- if (diag->HasFixIts())
- return true;
- }
- return false;
+ bool HasFixIts() const {
+ return llvm::any_of(m_diagnostics,
+ [](const std::unique_ptr<Diagnostic> &diag) {
+ return diag->HasFixIts();
+ });
}
void AddDiagnostic(llvm::StringRef message, DiagnosticSeverity severity,
DiagnosticOrigin origin,
uint32_t compiler_id = LLDB_INVALID_COMPILER_ID) {
- m_diagnostics.push_back(
- new Diagnostic(message, severity, origin, compiler_id));
+ m_diagnostics.emplace_back(
+ std::make_unique<Diagnostic>(message, severity, origin, compiler_id));
}
- void AddDiagnostic(Diagnostic *diagnostic) {
- m_diagnostics.push_back(diagnostic);
+ void AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic) {
+ m_diagnostics.push_back(std::move(diagnostic));
}
- void CopyDiagnostics(DiagnosticManager &otherDiagnostics);
-
size_t Printf(DiagnosticSeverity severity, const char *format, ...)
__attribute__((format(printf, 3, 4)));
- size_t PutString(DiagnosticSeverity severity, llvm::StringRef str);
+ void PutString(DiagnosticSeverity severity, llvm::StringRef str);
void AppendMessageToDiagnostic(llvm::StringRef str) {
- if (!m_diagnostics.empty()) {
+ if (!m_diagnostics.empty())
m_diagnostics.back()->AppendMessage(str);
- }
}
// Returns a string containing errors in this format:
@@ -153,7 +140,6 @@ public:
// Moves fixed_expression to the internal storage.
void SetFixedExpression(std::string fixed_expression) {
m_fixed_expression = std::move(fixed_expression);
- fixed_expression.clear();
}
protected:
diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h
index d0d01b5f9b59..e7d39e7ca24a 100644
--- a/include/lldb/Expression/ExpressionSourceCode.h
+++ b/include/lldb/Expression/ExpressionSourceCode.h
@@ -17,20 +17,27 @@
namespace lldb_private {
class ExpressionSourceCode {
+protected:
+ enum Wrapping : bool {
+ Wrap = true,
+ NoWrap = false,
+ };
+
public:
- bool NeedsWrapping() const { return m_wrap; }
+ bool NeedsWrapping() const { return m_wrap == Wrap; }
const char *GetName() const { return m_name.c_str(); }
protected:
- ExpressionSourceCode(const char *name, const char *prefix, const char *body,
- bool wrap)
- : m_name(name), m_prefix(prefix), m_body(body), m_wrap(wrap) {}
+ ExpressionSourceCode(llvm::StringRef name, llvm::StringRef prefix,
+ llvm::StringRef body, Wrapping wrap)
+ : m_name(name.str()), m_prefix(prefix.str()), m_body(body.str()),
+ m_wrap(wrap) {}
std::string m_name;
std::string m_prefix;
std::string m_body;
- bool m_wrap;
+ Wrapping m_wrap;
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h
index c2af7239951b..c3b8ed506f17 100644
--- a/include/lldb/Expression/LLVMUserExpression.h
+++ b/include/lldb/Expression/LLVMUserExpression.h
@@ -103,22 +103,6 @@ protected:
/// when running the
/// expression.
lldb::ModuleWP m_jit_module_wp;
- bool m_enforce_valid_object; ///< True if the expression parser should enforce
- ///the presence of a valid class pointer
- /// in order to generate the expression as a method.
- bool m_in_cplusplus_method; ///< True if the expression is compiled as a C++
- ///member function (true if it was parsed
- /// when exe_ctx was in a C++ method).
- bool m_in_objectivec_method; ///< True if the expression is compiled as an
- ///Objective-C method (true if it was parsed
- /// when exe_ctx was in an Objective-C method).
- bool m_in_static_method; ///< True if the expression is compiled as a static
- ///(or class) method (currently true if it
- /// was parsed when exe_ctx was in an Objective-C class method).
- bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and
- ///passed in. False if the expression
- /// doesn't really use them and they can be NULL.
- bool m_const_object; ///< True if "this" is const.
Target *m_target; ///< The target for storing persistent data like types and
///variables.
diff --git a/include/lldb/Expression/Materializer.h b/include/lldb/Expression/Materializer.h
index 603b4e0066cd..70f622e7850b 100644
--- a/include/lldb/Expression/Materializer.h
+++ b/include/lldb/Expression/Materializer.h
@@ -115,8 +115,6 @@ public:
void SetOffset(uint32_t offset) { m_offset = offset; }
protected:
- void SetSizeAndAlignmentFromType(CompilerType &type);
-
uint32_t m_alignment;
uint32_t m_size;
uint32_t m_offset;
diff --git a/include/lldb/Expression/REPL.h b/include/lldb/Expression/REPL.h
index 850d2f6f961a..d34a792f58f1 100644
--- a/include/lldb/Expression/REPL.h
+++ b/include/lldb/Expression/REPL.h
@@ -103,10 +103,8 @@ public:
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &line) override;
- int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
- const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions) override;
+ void IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) override;
protected:
static int CalculateActualIndentation(const StringList &lines);
diff --git a/include/lldb/Host/Config.h.cmake b/include/lldb/Host/Config.h.cmake
index b8fb9e9de868..662c07668d14 100644
--- a/include/lldb/Host/Config.h.cmake
+++ b/include/lldb/Host/Config.h.cmake
@@ -19,6 +19,8 @@
#define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}"
+#cmakedefine01 HAVE_SYS_TYPES_H
+
#cmakedefine01 HAVE_SYS_EVENT_H
#cmakedefine01 HAVE_PPOLL
@@ -33,4 +35,6 @@
#cmakedefine HAVE_LIBCOMPRESSION
#endif
+#cmakedefine01 LLDB_ENABLE_LZMA
+
#endif // #ifndef LLDB_HOST_CONFIG_H
diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h
index a942ede05ce5..65bf15531bc4 100644
--- a/include/lldb/Host/Editline.h
+++ b/include/lldb/Host/Editline.h
@@ -53,6 +53,7 @@
#include <vector>
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Predicate.h"
@@ -97,11 +98,7 @@ typedef int (*FixIndentationCallbackType)(Editline *editline,
const StringList &lines,
int cursor_position, void *baton);
-typedef int (*CompleteCallbackType)(const char *current_line,
- const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches,
- StringList &descriptions, void *baton);
+typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton);
/// Status used to decide when and how to start editing another line in
/// multi-line sessions
diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h
index eb28c4ada0e7..0102beb141ee 100644
--- a/include/lldb/Host/File.h
+++ b/include/lldb/Host/File.h
@@ -13,6 +13,7 @@
#include "lldb/Utility/IOObject.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private.h"
+#include "llvm/ADT/BitmaskEnum.h"
#include <mutex>
#include <stdarg.h>
@@ -21,11 +22,15 @@
namespace lldb_private {
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
/// \class File File.h "lldb/Host/File.h"
-/// A file class.
+/// An abstract base class for files.
///
-/// A file class that divides abstracts the LLDB core from host file
-/// functionality.
+/// Files will often be NativeFiles, which provides a wrapper
+/// around host OS file functionality. But it
+/// is also possible to subclass file to provide objects that have file
+/// or stream functionality but are not backed by any host OS file.
class File : public IOObject {
public:
static int kInvalidDescriptor;
@@ -33,7 +38,12 @@ public:
// NB this enum is used in the lldb platform gdb-remote packet
// vFile:open: and existing values cannot be modified.
- enum OpenOptions {
+ //
+ // FIXME
+ // These values do not match the values used by GDB
+ // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
+ // * rdar://problem/46788934
+ enum OpenOptions : uint32_t {
eOpenOptionRead = (1u << 0), // Open file for reading
eOpenOptionWrite = (1u << 1), // Open file for writing
eOpenOptionAppend =
@@ -45,128 +55,105 @@ public:
(1u << 6), // Can create file only if it doesn't already exist
eOpenOptionDontFollowSymlinks = (1u << 7),
eOpenOptionCloseOnExec =
- (1u << 8) // Close the file when executing a new process
+ (1u << 8), // Close the file when executing a new process
+ LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec)
};
- static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options);
+ static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options);
+ static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode);
+ static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
+ static llvm::Expected<const char *>
+ GetStreamOpenModeFromOptions(OpenOptions options);
File()
- : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
- m_stream(kInvalidStream), m_options(0), m_own_stream(false),
- m_is_interactive(eLazyBoolCalculate),
+ : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate),
m_is_real_terminal(eLazyBoolCalculate),
- m_supports_colors(eLazyBoolCalculate) {}
-
- File(FILE *fh, bool transfer_ownership)
- : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
- m_stream(fh), m_options(0), m_own_stream(transfer_ownership),
- m_is_interactive(eLazyBoolCalculate),
- m_is_real_terminal(eLazyBoolCalculate),
- m_supports_colors(eLazyBoolCalculate) {}
-
- File(int fd, bool transfer_ownership)
- : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd),
- m_stream(kInvalidStream), m_options(0), m_own_stream(false),
- m_is_interactive(eLazyBoolCalculate),
- m_is_real_terminal(eLazyBoolCalculate) {}
+ m_supports_colors(eLazyBoolCalculate){};
- /// Destructor.
+ /// Read bytes from a file from the current file position into buf.
///
- /// The destructor is virtual in case this class is subclassed.
- ~File() override;
-
- bool IsValid() const override {
- return DescriptorIsValid() || StreamIsValid();
- }
-
- /// Convert to pointer operator.
+ /// NOTE: This function is NOT thread safe. Use the read function
+ /// that takes an "off_t &offset" to ensure correct operation in multi-
+ /// threaded environments.
///
- /// This allows code to check a File object to see if it contains anything
- /// valid using code such as:
+ /// \param[out] buf
///
- /// \code
- /// File file(...);
- /// if (file)
- /// { ...
- /// \endcode
+ /// \param[in,out] num_bytes.
+ /// Pass in the size of buf. Read will pass out the number
+ /// of bytes read. Zero bytes read with no error indicates
+ /// EOF.
///
/// \return
- /// A pointer to this object if either the directory or filename
- /// is valid, nullptr otherwise.
- operator bool() const { return DescriptorIsValid() || StreamIsValid(); }
+ /// success, ENOTSUP, or another error.
+ Status Read(void *buf, size_t &num_bytes) override;
- /// Logical NOT operator.
+ /// Write bytes from buf to a file at the current file position.
///
- /// This allows code to check a File object to see if it is invalid using
- /// code such as:
+ /// NOTE: This function is NOT thread safe. Use the write function
+ /// that takes an "off_t &offset" to ensure correct operation in multi-
+ /// threaded environments.
+ ///
+ /// \param[in] buf
///
- /// \code
- /// File file(...);
- /// if (!file)
- /// { ...
- /// \endcode
+ /// \param[in,out] num_bytes
+ /// Pass in the size of buf. Write will pass out the number
+ /// of bytes written. Write will attempt write the full number
+ /// of bytes and will not return early except on error.
///
/// \return
- /// Returns \b true if the object has an empty directory and
- /// filename, \b false otherwise.
- bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); }
+ /// success, ENOTSUP, or another error.
+ Status Write(const void *buf, size_t &num_bytes) override;
- /// Get the file spec for this file.
+ /// IsValid
///
/// \return
- /// A reference to the file specification object.
- Status GetFileSpec(FileSpec &file_spec) const;
+ /// true iff the file is valid.
+ bool IsValid() const override;
+ /// Flush any buffers and release any resources owned by the file.
+ /// After Close() the file will be invalid.
+ ///
+ /// \return
+ /// success or an error.
Status Close() override;
- void Clear();
-
- int GetDescriptor() const;
-
+ /// Get a handle that can be used for OS polling interfaces, such
+ /// as WaitForMultipleObjects, select, or epoll. This may return
+ /// IOObject::kInvalidHandleValue if none is available. This will
+ /// generally be the same as the file descriptor, this function
+ /// is not interchangeable with GetDescriptor(). A WaitableHandle
+ /// must only be used for polling, not actual I/O.
+ ///
+ /// \return
+ /// a valid handle or IOObject::kInvalidHandleValue
WaitableHandle GetWaitableHandle() override;
- void SetDescriptor(int fd, bool transfer_ownership);
-
- FILE *GetStream();
-
- void SetStream(FILE *fh, bool transfer_ownership);
-
- /// Read bytes from a file from the current file position.
- ///
- /// NOTE: This function is NOT thread safe. Use the read function
- /// that takes an "off_t &offset" to ensure correct operation in multi-
- /// threaded environments.
- ///
- /// \param[in] buf
- /// A buffer where to put the bytes that are read.
- ///
- /// \param[in,out] num_bytes
- /// The number of bytes to read form the current file position
- /// which gets modified with the number of bytes that were read.
+ /// Get the file specification for this file, if possible.
///
+ /// \param[out] file_spec
+ /// the file specification.
/// \return
- /// An error object that indicates success or the reason for
- /// failure.
- Status Read(void *buf, size_t &num_bytes) override;
+ /// ENOTSUP, success, or another error.
+ virtual Status GetFileSpec(FileSpec &file_spec) const;
- /// Write bytes to a file at the current file position.
- ///
- /// NOTE: This function is NOT thread safe. Use the write function
- /// that takes an "off_t &offset" to ensure correct operation in multi-
- /// threaded environments.
+ /// Get underlying OS file descriptor for this file, or kInvalidDescriptor.
+ /// If the descriptor is valid, then it may be used directly for I/O
+ /// However, the File may also perform it's own buffering, so avoid using
+ /// this if it is not necessary, or use Flush() appropriately.
///
- /// \param[in] buf
- /// A buffer where to put the bytes that are read.
+ /// \return
+ /// a valid file descriptor for this file or kInvalidDescriptor
+ virtual int GetDescriptor() const;
+
+ /// Get the underlying libc stream for this file, or NULL.
///
- /// \param[in,out] num_bytes
- /// The number of bytes to write to the current file position
- /// which gets modified with the number of bytes that were
- /// written.
+ /// Not all valid files will have a FILE* stream. This should only be
+ /// used if absolutely necessary, such as to interact with 3rd party
+ /// libraries that need FILE* streams.
///
/// \return
- /// An error object that indicates success or the reason for
- /// failure.
- Status Write(const void *buf, size_t &num_bytes) override;
+ /// a valid stream or NULL;
+ virtual FILE *GetStream();
/// Seek to an offset relative to the beginning of the file.
///
@@ -186,7 +173,7 @@ public:
///
/// \return
/// The resulting seek offset, or -1 on error.
- off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
+ virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr);
/// Seek to an offset relative to the current file position.
///
@@ -206,7 +193,7 @@ public:
///
/// \return
/// The resulting seek offset, or -1 on error.
- off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
+ virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr);
/// Seek to an offset relative to the end of the file.
///
@@ -227,7 +214,7 @@ public:
///
/// \return
/// The resulting seek offset, or -1 on error.
- off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
+ virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr);
/// Read bytes from a file from the specified file offset.
///
@@ -250,37 +237,7 @@ public:
/// \return
/// An error object that indicates success or the reason for
/// failure.
- Status Read(void *dst, size_t &num_bytes, off_t &offset);
-
- /// Read bytes from a file from the specified file offset.
- ///
- /// NOTE: This function is thread safe in that clients manager their
- /// own file position markers and reads on other threads won't mess up the
- /// current read.
- ///
- /// \param[in,out] num_bytes
- /// The number of bytes to read form the current file position
- /// which gets modified with the number of bytes that were read.
- ///
- /// \param[in,out] offset
- /// The offset within the file from which to read \a num_bytes
- /// bytes. This offset gets incremented by the number of bytes
- /// that were read.
- ///
- /// \param[in] null_terminate
- /// Ensure that the data that is read is terminated with a NULL
- /// character so that the data can be used as a C string.
- ///
- /// \param[out] data_buffer_sp
- /// A data buffer to create and fill in that will contain any
- /// data that is read from the file. This buffer will be reset
- /// if an error occurs.
- ///
- /// \return
- /// An error object that indicates success or the reason for
- /// failure.
- Status Read(size_t &num_bytes, off_t &offset, bool null_terminate,
- lldb::DataBufferSP &data_buffer_sp);
+ virtual Status Read(void *dst, size_t &num_bytes, off_t &offset);
/// Write bytes to a file at the specified file offset.
///
@@ -305,21 +262,67 @@ public:
/// \return
/// An error object that indicates success or the reason for
/// failure.
- Status Write(const void *src, size_t &num_bytes, off_t &offset);
+ virtual Status Write(const void *src, size_t &num_bytes, off_t &offset);
/// Flush the current stream
///
/// \return
/// An error object that indicates success or the reason for
/// failure.
- Status Flush();
+ virtual Status Flush();
/// Sync to disk.
///
/// \return
/// An error object that indicates success or the reason for
/// failure.
- Status Sync();
+ virtual Status Sync();
+
+ /// Output printf formatted output to the stream.
+ ///
+ /// NOTE: this is not virtual, because it just calls the va_list
+ /// version of the function.
+ ///
+ /// Print some formatted output to the stream.
+ ///
+ /// \param[in] format
+ /// A printf style format string.
+ ///
+ /// \param[in] ...
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
+
+ /// Output printf formatted output to the stream.
+ ///
+ /// Print some formatted output to the stream.
+ ///
+ /// \param[in] format
+ /// A printf style format string.
+ ///
+ /// \param[in] args
+ /// Variable arguments that are needed for the printf style
+ /// format string \a format.
+ virtual size_t PrintfVarArg(const char *format, va_list args);
+
+ /// Return the OpenOptions for this file.
+ ///
+ /// Some options like eOpenOptionDontFollowSymlinks only make
+ /// sense when a file is being opened (or not at all)
+ /// and may not be preserved for this method. But any valid
+ /// File should return either or both of eOpenOptionRead and
+ /// eOpenOptionWrite here.
+ ///
+ /// \return
+ /// OpenOptions flags for this file, or an error.
+ virtual llvm::Expected<OpenOptions> GetOptions() const;
+
+ llvm::Expected<const char *> GetOpenMode() const {
+ auto opts = GetOptions();
+ if (!opts)
+ return opts.takeError();
+ return GetStreamOpenModeFromOptions(opts.get());
+ }
/// Get the permissions for a this file.
///
@@ -346,45 +349,90 @@ public:
/// a non-zero width and height, false otherwise.
bool GetIsRealTerminal();
- bool GetIsTerminalWithColors();
-
- /// Output printf formatted output to the stream.
- ///
- /// Print some formatted output to the stream.
+ /// Return true if this file is a terminal which supports colors.
///
- /// \param[in] format
- /// A printf style format string.
- ///
- /// \param[in] ...
- /// Variable arguments that are needed for the printf style
- /// format string \a format.
- size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
+ /// \return
+ /// True iff this is a terminal and it supports colors.
+ bool GetIsTerminalWithColors();
- size_t PrintfVarArg(const char *format, va_list args);
+ operator bool() const { return IsValid(); };
- void SetOptions(uint32_t options) { m_options = options; }
+ bool operator!() const { return !IsValid(); };
- static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; };
+ static char ID;
+ virtual bool isA(const void *classID) const { return classID == &ID; }
+ static bool classof(const File *file) { return file->isA(&ID); }
protected:
- bool DescriptorIsValid() const { return DescriptorIsValid(m_descriptor); }
-
- bool StreamIsValid() const { return m_stream != kInvalidStream; }
+ LazyBool m_is_interactive;
+ LazyBool m_is_real_terminal;
+ LazyBool m_supports_colors;
void CalculateInteractiveAndTerminal();
+private:
+ DISALLOW_COPY_AND_ASSIGN(File);
+};
+
+class NativeFile : public File {
+public:
+ NativeFile()
+ : m_descriptor(kInvalidDescriptor), m_own_descriptor(false),
+ m_stream(kInvalidStream), m_options(), m_own_stream(false) {}
+
+ NativeFile(FILE *fh, bool transfer_ownership)
+ : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh),
+ m_options(), m_own_stream(transfer_ownership) {}
+
+ NativeFile(int fd, OpenOptions options, bool transfer_ownership)
+ : m_descriptor(fd), m_own_descriptor(transfer_ownership),
+ m_stream(kInvalidStream), m_options(options), m_own_stream(false) {}
+
+ ~NativeFile() override { Close(); }
+
+ bool IsValid() const override {
+ return DescriptorIsValid() || StreamIsValid();
+ }
+
+ Status Read(void *buf, size_t &num_bytes) override;
+ Status Write(const void *buf, size_t &num_bytes) override;
+ Status Close() override;
+ WaitableHandle GetWaitableHandle() override;
+ Status GetFileSpec(FileSpec &file_spec) const override;
+ int GetDescriptor() const override;
+ FILE *GetStream() override;
+ off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override;
+ off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override;
+ off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override;
+ Status Read(void *dst, size_t &num_bytes, off_t &offset) override;
+ Status Write(const void *src, size_t &num_bytes, off_t &offset) override;
+ Status Flush() override;
+ Status Sync() override;
+ size_t PrintfVarArg(const char *format, va_list args) override;
+ llvm::Expected<OpenOptions> GetOptions() const override;
+
+ static char ID;
+ virtual bool isA(const void *classID) const override {
+ return classID == &ID || File::isA(classID);
+ }
+ static bool classof(const File *file) { return file->isA(&ID); }
+
+protected:
+ bool DescriptorIsValid() const {
+ return File::DescriptorIsValid(m_descriptor);
+ }
+ bool StreamIsValid() const { return m_stream != kInvalidStream; }
+
// Member variables
int m_descriptor;
+ bool m_own_descriptor;
FILE *m_stream;
- uint32_t m_options;
+ OpenOptions m_options;
bool m_own_stream;
- LazyBool m_is_interactive;
- LazyBool m_is_real_terminal;
- LazyBool m_supports_colors;
std::mutex offset_access_mutex;
private:
- DISALLOW_COPY_AND_ASSIGN(File);
+ DISALLOW_COPY_AND_ASSIGN(NativeFile);
};
} // namespace lldb_private
diff --git a/include/lldb/Host/FileCache.h b/include/lldb/Host/FileCache.h
index 0c1ef1961645..c76916701ebb 100644
--- a/include/lldb/Host/FileCache.h
+++ b/include/lldb/Host/FileCache.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
+#include "lldb/Host/File.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
@@ -22,12 +23,12 @@ class FileCache {
private:
FileCache() {}
- typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap;
+ typedef std::map<lldb::user_id_t, lldb::FileUP> FDToFileMap;
public:
static FileCache &GetInstance();
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
uint32_t mode, Status &error);
bool CloseFile(lldb::user_id_t fd, Status &error);
diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h
index 865b09b23103..528c43519a32 100644
--- a/include/lldb/Host/FileSystem.h
+++ b/include/lldb/Host/FileSystem.h
@@ -11,12 +11,12 @@
#include "lldb/Host/File.h"
#include "lldb/Utility/DataBufferLLVM.h"
-#include "lldb/Utility/FileCollector.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Chrono.h"
+#include "llvm/Support/FileCollector.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "lldb/lldb-types.h"
@@ -34,8 +34,8 @@ public:
FileSystem()
: m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr),
m_mapped(false) {}
- FileSystem(FileCollector &collector)
- : m_fs(llvm::vfs::getRealFileSystem()), m_collector(&collector),
+ FileSystem(std::shared_ptr<llvm::FileCollector> collector)
+ : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector),
m_mapped(false) {}
FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
bool mapped = false)
@@ -47,7 +47,7 @@ public:
static FileSystem &Instance();
static void Initialize();
- static void Initialize(FileCollector &collector);
+ static void Initialize(std::shared_ptr<llvm::FileCollector> collector);
static llvm::Error Initialize(const FileSpec &mapping);
static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs);
static void Terminate();
@@ -63,9 +63,10 @@ public:
/// Wraps ::open in a platform-independent way.
int Open(const char *path, int flags, int mode);
- Status Open(File &File, const FileSpec &file_spec, uint32_t options,
- uint32_t permissions = lldb::eFilePermissionsFileDefault,
- bool should_close_fd = true);
+ llvm::Expected<std::unique_ptr<File>>
+ Open(const FileSpec &file_spec, File::OpenOptions options,
+ uint32_t permissions = lldb::eFilePermissionsFileDefault,
+ bool should_close_fd = true);
/// Get a directory iterator.
/// \{
@@ -188,7 +189,7 @@ public:
private:
static llvm::Optional<FileSystem> &InstanceImpl();
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
- FileCollector *m_collector;
+ std::shared_ptr<llvm::FileCollector> m_collector;
bool m_mapped;
};
} // namespace lldb_private
diff --git a/include/lldb/Host/LZMA.h b/include/lldb/Host/LZMA.h
new file mode 100644
index 000000000000..c741cc3bbde1
--- /dev/null
+++ b/include/lldb/Host/LZMA.h
@@ -0,0 +1,34 @@
+//===-- LZMA.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_Host_LZMA_h_
+#define liblldb_Host_LZMA_h_
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+class Error;
+} // End of namespace llvm
+
+namespace lldb_private {
+
+namespace lzma {
+
+bool isAvailable();
+
+llvm::Expected<uint64_t>
+getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer);
+
+llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
+ llvm::SmallVectorImpl<uint8_t> &Uncompressed);
+
+} // End of namespace lzma
+
+} // End of namespace lldb_private
+
+#endif // liblldb_Host_LZMA_h_
diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h
index 6f96bd73e753..c6df5634e24e 100644
--- a/include/lldb/Host/Socket.h
+++ b/include/lldb/Host/Socket.h
@@ -31,7 +31,7 @@ class StringRef;
namespace lldb_private {
-#if defined(_MSC_VER)
+#if defined(_WIN32)
typedef SOCKET NativeSocket;
#else
typedef int NativeSocket;
@@ -122,6 +122,7 @@ protected:
SocketProtocol m_protocol;
NativeSocket m_socket;
bool m_child_processes_inherit;
+ bool m_should_close_fd;
};
} // namespace lldb_private
diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h
index f05b8d01a1c9..2d48717c4fbb 100644
--- a/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/include/lldb/Host/common/NativeProcessProtocol.h
@@ -32,6 +32,14 @@ namespace lldb_private {
class MemoryRegionInfo;
class ResumeActionList;
+struct SVR4LibraryInfo {
+ std::string name;
+ lldb::addr_t link_map;
+ lldb::addr_t base_addr;
+ lldb::addr_t ld_addr;
+ lldb::addr_t next;
+};
+
// NativeProcessProtocol
class NativeProcessProtocol {
public:
@@ -76,6 +84,31 @@ public:
Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
size_t &bytes_read);
+ /// Reads a null terminated string from memory.
+ ///
+ /// Reads up to \p max_size bytes of memory until it finds a '\0'.
+ /// If a '\0' is not found then it reads max_size-1 bytes as a string and a
+ /// '\0' is added as the last character of the \p buffer.
+ ///
+ /// \param[in] addr
+ /// The address in memory to read from.
+ ///
+ /// \param[in] buffer
+ /// An allocated buffer with at least \p max_size size.
+ ///
+ /// \param[in] max_size
+ /// The maximum number of bytes to read from memory until it reads the
+ /// string.
+ ///
+ /// \param[out] total_bytes_read
+ /// The number of bytes read from memory into \p buffer.
+ ///
+ /// \return
+ /// Returns a StringRef backed up by the \p buffer passed in.
+ llvm::Expected<llvm::StringRef>
+ ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
+ size_t &total_bytes_read);
+
virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
size_t &bytes_written) = 0;
@@ -86,6 +119,12 @@ public:
virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
+ virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
+ GetLoadedSVR4Libraries() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Not implemented");
+ }
+
virtual bool IsAlive() const;
virtual size_t UpdateThreads() = 0;
@@ -391,6 +430,8 @@ protected:
NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
NativeDelegate &delegate);
+ void SetID(lldb::pid_t pid) { m_pid = pid; }
+
// interface for state handling
void SetState(lldb::StateType state, bool notify_delegates = true);
diff --git a/include/lldb/Interpreter/CommandAlias.h b/include/lldb/Interpreter/CommandAlias.h
index c2a7a383f35a..1e186d77f8e6 100644
--- a/include/lldb/Interpreter/CommandAlias.h
+++ b/include/lldb/Interpreter/CommandAlias.h
@@ -36,11 +36,11 @@ public:
bool WantsCompletion() override;
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override;
Options *GetOptions() override;
diff --git a/include/lldb/Interpreter/CommandCompletions.h b/include/lldb/Interpreter/CommandCompletions.h
index 3d09db5ce5e7..275cc7e7c145 100644
--- a/include/lldb/Interpreter/CommandCompletions.h
+++ b/include/lldb/Interpreter/CommandCompletions.h
@@ -26,10 +26,10 @@ public:
// This is the command completion callback that is used to complete the
// argument of the option it is bound to (in the OptionDefinition table
// below). Return the total number of matches.
- typedef int (*CompletionCallback)(CommandInterpreter &interpreter,
- CompletionRequest &request,
- // A search filter to limit the search...
- lldb_private::SearchFilter *searcher);
+ typedef void (*CompletionCallback)(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ // A search filter to limit the search...
+ lldb_private::SearchFilter *searcher);
enum CommonCompletionTypes {
eNoCompletion = 0u,
eSourceFileCompletion = (1u << 0),
@@ -57,42 +57,42 @@ public:
lldb_private::CompletionRequest &request, SearchFilter *searcher);
// These are the generic completer functions:
- static int DiskFiles(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void DiskFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
- static int DiskFiles(const llvm::Twine &partial_file_name,
- StringList &matches, TildeExpressionResolver &Resolver);
+ static void DiskFiles(const llvm::Twine &partial_file_name,
+ StringList &matches, TildeExpressionResolver &Resolver);
- static int DiskDirectories(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher);
+ static void DiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
- static int DiskDirectories(const llvm::Twine &partial_file_name,
- StringList &matches,
- TildeExpressionResolver &Resolver);
+ static void DiskDirectories(const llvm::Twine &partial_file_name,
+ StringList &matches,
+ TildeExpressionResolver &Resolver);
- static int SourceFiles(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void SourceFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
- static int Modules(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void Modules(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
- static int Symbols(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void Symbols(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
- static int SettingsNames(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void SettingsNames(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
- static int PlatformPluginNames(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher);
+ static void PlatformPluginNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
- static int ArchitectureNames(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher);
+ static void ArchitectureNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
- static int VariablePath(CommandInterpreter &interpreter,
- CompletionRequest &request, SearchFilter *searcher);
+ static void VariablePath(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
// The Completer class is a convenient base class for building searchers that
// go along with the SearchFilter passed to the standard Completer functions.
@@ -103,11 +103,11 @@ public:
~Completer() override;
CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context,
- Address *addr, bool complete) override = 0;
+ Address *addr) override = 0;
lldb::SearchDepth GetDepth() override = 0;
- virtual size_t DoCompletion(SearchFilter *filter) = 0;
+ virtual void DoCompletion(SearchFilter *filter) = 0;
protected:
CommandInterpreter &m_interpreter;
@@ -127,10 +127,9 @@ public:
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
SymbolContext &context,
- Address *addr,
- bool complete) override;
+ Address *addr) override;
- size_t DoCompletion(SearchFilter *filter) override;
+ void DoCompletion(SearchFilter *filter) override;
private:
bool m_include_support_files;
@@ -151,10 +150,9 @@ public:
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
SymbolContext &context,
- Address *addr,
- bool complete) override;
+ Address *addr) override;
- size_t DoCompletion(SearchFilter *filter) override;
+ void DoCompletion(SearchFilter *filter) override;
private:
const char *m_file_name;
@@ -173,20 +171,11 @@ public:
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
SymbolContext &context,
- Address *addr,
- bool complete) override;
+ Address *addr) override;
- size_t DoCompletion(SearchFilter *filter) override;
+ void DoCompletion(SearchFilter *filter) override;
private:
- // struct NameCmp {
- // bool operator() (const ConstString& lhs, const ConstString&
- // rhs) const
- // {
- // return lhs < rhs;
- // }
- // };
-
RegularExpression m_regex;
typedef std::set<ConstString> collection;
collection m_match_set;
diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h
index c3dd6606e0db..3b98b2a521dd 100644
--- a/include/lldb/Interpreter/CommandInterpreter.h
+++ b/include/lldb/Interpreter/CommandInterpreter.h
@@ -308,31 +308,12 @@ public:
CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line);
- // This handles command line completion. You are given a pointer to the
- // command string buffer, to the current cursor, and to the end of the string
- // (in case it is not NULL terminated). You also passed in an StringList
- // object to fill with the returns. The first element of the array will be
- // filled with the string that you would need to insert at the cursor point
- // to complete the cursor point to the longest common matching prefix. If you
- // want to limit the number of elements returned, set max_return_elements to
- // the number of elements you want returned. Otherwise set
- // max_return_elements to -1. If you want to start some way into the match
- // list, then set match_start_point to the desired start point. Returns: -1
- // if the completion character should be inserted -2 if the entire command
- // line should be deleted and replaced with matches.GetStringAtIndex(0)
- // INT_MAX if the number of matches is > max_return_elements, but it is
- // expensive to compute. Otherwise, returns the number of matches.
- //
- // FIXME: Only max_return_elements == -1 is supported at present.
- int HandleCompletion(const char *current_line, const char *cursor,
- const char *last_char, int match_start_point,
- int max_return_elements, StringList &matches,
- StringList &descriptions);
-
- // This version just returns matches, and doesn't compute the substring. It
- // is here so the Help command can call it for the first argument. It uses
- // a CompletionRequest for simplicity reasons.
- int HandleCompletionMatches(CompletionRequest &request);
+ // This handles command line completion.
+ void HandleCompletion(CompletionRequest &request);
+
+ // This version just returns matches, and doesn't compute the substring. It
+ // is here so the Help command can call it for the first argument.
+ void HandleCompletionMatches(CompletionRequest &request);
int GetCommandNamesMatchingPartialString(const char *cmd_cstr,
bool include_aliases,
@@ -519,7 +500,9 @@ protected:
bool IOHandlerInterrupt(IOHandler &io_handler) override;
- size_t GetProcessOutput();
+ void GetProcessOutput();
+
+ bool DidProcessStopAbnormally() const;
void SetSynchronous(bool value);
diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h
index 31f7f126a9fe..2dad84f036c0 100644
--- a/include/lldb/Interpreter/CommandObject.h
+++ b/include/lldb/Interpreter/CommandObject.h
@@ -228,36 +228,18 @@ public:
///
/// \param[in/out] request
/// The completion request that needs to be answered.
- ///
- /// FIXME: This is the wrong return value, since we also need to make a
- /// distinction between
- /// total number of matches, and the window the user wants returned.
- ///
- /// \return
- /// \btrue if we were in an option, \bfalse otherwise.
- virtual int HandleCompletion(CompletionRequest &request);
+ virtual void HandleCompletion(CompletionRequest &request);
- /// The input array contains a parsed version of the line. The insertion
- /// point is given by cursor_index (the index in input of the word containing
- /// the cursor) and cursor_char_position (the position of the cursor in that
- /// word.)
+ /// The input array contains a parsed version of the line.
+ ///
/// We've constructed the map of options and their arguments as well if that
/// is helpful for the completion.
///
/// \param[in/out] request
/// The completion request that needs to be answered.
- ///
- /// FIXME: This is the wrong return value, since we also need to make a
- /// distinction between
- /// total number of matches, and the window the user wants returned.
- ///
- /// \return
- /// The number of completions.
- virtual int
+ virtual void
HandleArgumentCompletion(CompletionRequest &request,
- OptionElementVector &opt_element_vector) {
- return 0;
- }
+ OptionElementVector &opt_element_vector) {}
bool HelpTextContainsWord(llvm::StringRef search_word,
bool search_short_help = true,
@@ -348,8 +330,9 @@ protected:
// This is for use in the command interpreter, when you either want the
// selected target, or if no target is present you want to prime the dummy
// target with entities that will be copied over to new targets.
- Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
- Target *GetDummyTarget();
+ Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
+ Target &GetSelectedTarget();
+ Target &GetDummyTarget();
// If a command needs to use the "current" thread, use this call. Command
// objects will have an ExecutionContext to use, and that may or may not have
diff --git a/include/lldb/Interpreter/CommandObjectMultiword.h b/include/lldb/Interpreter/CommandObjectMultiword.h
index 660e9d49d977..72ec8a9c5ca9 100644
--- a/include/lldb/Interpreter/CommandObjectMultiword.h
+++ b/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -50,7 +50,7 @@ public:
bool WantsRawCommandString() override { return false; }
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override;
@@ -112,11 +112,11 @@ public:
Options *GetOptions() override;
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override;
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override;
diff --git a/include/lldb/Interpreter/CommandObjectRegexCommand.h b/include/lldb/Interpreter/CommandObjectRegexCommand.h
index 7f06e269d64f..7800d5de1b38 100644
--- a/include/lldb/Interpreter/CommandObjectRegexCommand.h
+++ b/include/lldb/Interpreter/CommandObjectRegexCommand.h
@@ -34,7 +34,7 @@ public:
bool HasRegexEntries() const { return !m_entries.empty(); }
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
protected:
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
diff --git a/include/lldb/Interpreter/CommandReturnObject.h b/include/lldb/Interpreter/CommandReturnObject.h
index a5f61261455e..61e57fb798a1 100644
--- a/include/lldb/Interpreter/CommandReturnObject.h
+++ b/include/lldb/Interpreter/CommandReturnObject.h
@@ -62,13 +62,13 @@ public:
return m_err_stream;
}
- void SetImmediateOutputFile(FILE *fh, bool transfer_fh_ownership = false) {
- lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership));
+ void SetImmediateOutputFile(lldb::FileSP file_sp) {
+ lldb::StreamSP stream_sp(new StreamFile(file_sp));
m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
}
- void SetImmediateErrorFile(FILE *fh, bool transfer_fh_ownership = false) {
- lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership));
+ void SetImmediateErrorFile(lldb::FileSP file_sp) {
+ lldb::StreamSP stream_sp(new StreamFile(file_sp));
m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
}
@@ -144,14 +144,6 @@ public:
void SetInteractive(bool b);
- bool GetAbnormalStopWasExpected() const {
- return m_abnormal_stop_was_expected;
- }
-
- void SetAbnormalStopWasExpected(bool signal_was_expected) {
- m_abnormal_stop_was_expected = signal_was_expected;
- }
-
private:
enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 };
@@ -162,14 +154,6 @@ private:
bool m_did_change_process_state;
bool m_interactive; // If true, then the input handle from the debugger will
// be hooked up
- bool m_abnormal_stop_was_expected; // This is to support
- // eHandleCommandFlagStopOnCrash vrs.
- // attach.
- // The attach command often ends up with the process stopped due to a signal.
- // Normally that would mean stop on crash should halt batch execution, but we
- // obviously don't want that for attach. Using this flag, the attach command
- // (and anything else for which this is relevant) can say that the signal is
- // expected, and batch command execution can continue.
};
} // namespace lldb_private
diff --git a/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h b/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h
new file mode 100644
index 000000000000..6aec7eb0f0b8
--- /dev/null
+++ b/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h
@@ -0,0 +1,65 @@
+//===-- OptionGroupPythonClassWithDict.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_OptionGroupPythonClassWithDict_h_
+#define liblldb_OptionGroupPythonClassWithDict_h_
+
+#include "lldb/lldb-types.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Utility/StructuredData.h"
+
+namespace lldb_private {
+
+// Use this Option group if you have a python class that implements some
+// Python extension point, and you pass a SBStructuredData to the class
+// __init__ method.
+// class_option specifies the class name
+// the key and value options are read in in pairs, and a
+// StructuredData::Dictionary is constructed with those pairs.
+class OptionGroupPythonClassWithDict : public OptionGroup {
+public:
+ OptionGroupPythonClassWithDict(const char *class_use,
+ int class_option = 'C',
+ int key_option = 'k',
+ int value_option = 'v',
+ const char *class_long_option = "python-class",
+ const char *key_long_option = "python-class-key",
+ const char *value_long_option = "python-class-value",
+ bool required = false);
+
+ ~OptionGroupPythonClassWithDict() override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::ArrayRef<OptionDefinition>(m_option_definition);
+ }
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+ Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+ Status OptionParsingFinished(ExecutionContext *execution_context) override;
+
+ const StructuredData::DictionarySP GetStructuredData() {
+ return m_dict_sp;
+ }
+ const std::string &GetClassName() {
+ return m_class_name;
+ }
+
+protected:
+ std::string m_class_name;
+ std::string m_current_key;
+ StructuredData::DictionarySP m_dict_sp;
+ std::string m_class_usage_text, m_key_usage_text, m_value_usage_text;
+ OptionDefinition m_option_definition[3];
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionGroupPythonClassWithDict_h_
diff --git a/include/lldb/Interpreter/OptionValue.h b/include/lldb/Interpreter/OptionValue.h
index 0b85bc19dd2a..9fc18551c26a 100644
--- a/include/lldb/Interpreter/OptionValue.h
+++ b/include/lldb/Interpreter/OptionValue.h
@@ -93,8 +93,8 @@ public:
virtual lldb::OptionValueSP DeepCopy() const = 0;
- virtual size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request);
+ virtual void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request);
// Subclasses can override these functions
virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx,
diff --git a/include/lldb/Interpreter/OptionValueArch.h b/include/lldb/Interpreter/OptionValueArch.h
index f8f406890841..3923e3d3dba4 100644
--- a/include/lldb/Interpreter/OptionValueArch.h
+++ b/include/lldb/Interpreter/OptionValueArch.h
@@ -55,8 +55,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
- size_t AutoComplete(CommandInterpreter &interpreter,
- lldb_private::CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ lldb_private::CompletionRequest &request) override;
// Subclass specific functions
diff --git a/include/lldb/Interpreter/OptionValueBoolean.h b/include/lldb/Interpreter/OptionValueBoolean.h
index 2fc97d494988..42b2ca4d2845 100644
--- a/include/lldb/Interpreter/OptionValueBoolean.h
+++ b/include/lldb/Interpreter/OptionValueBoolean.h
@@ -43,8 +43,8 @@ public:
return true;
}
- size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
// Subclass specific functions
diff --git a/include/lldb/Interpreter/OptionValueEnumeration.h b/include/lldb/Interpreter/OptionValueEnumeration.h
index 71f3ab53b2ff..eb19737f8653 100644
--- a/include/lldb/Interpreter/OptionValueEnumeration.h
+++ b/include/lldb/Interpreter/OptionValueEnumeration.h
@@ -55,8 +55,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
- size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
// Subclass specific functions
diff --git a/include/lldb/Interpreter/OptionValueFileSpec.h b/include/lldb/Interpreter/OptionValueFileSpec.h
index aa1022a4fe2c..a6df18149076 100644
--- a/include/lldb/Interpreter/OptionValueFileSpec.h
+++ b/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -51,8 +51,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
- size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
// Subclass specific functions
diff --git a/include/lldb/Interpreter/OptionValueFormatEntity.h b/include/lldb/Interpreter/OptionValueFormatEntity.h
index b05be959f3d4..419ff5c03e3a 100644
--- a/include/lldb/Interpreter/OptionValueFormatEntity.h
+++ b/include/lldb/Interpreter/OptionValueFormatEntity.h
@@ -38,8 +38,8 @@ public:
lldb::OptionValueSP DeepCopy() const override;
- size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
// Subclass specific functions
diff --git a/include/lldb/Interpreter/OptionValueRegex.h b/include/lldb/Interpreter/OptionValueRegex.h
index f5b2557634df..8c10dacb0313 100644
--- a/include/lldb/Interpreter/OptionValueRegex.h
+++ b/include/lldb/Interpreter/OptionValueRegex.h
@@ -36,7 +36,7 @@ public:
VarSetOperationType = eVarSetOperationAssign) = delete;
bool Clear() override {
- m_regex.Clear();
+ m_regex = RegularExpression();
m_value_was_set = false;
return true;
}
@@ -50,9 +50,9 @@ public:
void SetCurrentValue(const char *value) {
if (value && value[0])
- m_regex.Compile(llvm::StringRef(value));
+ m_regex = RegularExpression(llvm::StringRef(value));
else
- m_regex.Clear();
+ m_regex = RegularExpression();
}
bool IsValid() const { return m_regex.IsValid(); }
diff --git a/include/lldb/Interpreter/OptionValueUUID.h b/include/lldb/Interpreter/OptionValueUUID.h
index 7273e35bd75b..576440d80519 100644
--- a/include/lldb/Interpreter/OptionValueUUID.h
+++ b/include/lldb/Interpreter/OptionValueUUID.h
@@ -52,8 +52,8 @@ public:
void SetCurrentValue(const UUID &value) { m_uuid = value; }
- size_t AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) override;
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
protected:
UUID m_uuid;
diff --git a/include/lldb/Interpreter/Options.h b/include/lldb/Interpreter/Options.h
index a008d51d721e..b6c824d5a199 100644
--- a/include/lldb/Interpreter/Options.h
+++ b/include/lldb/Interpreter/Options.h
@@ -187,14 +187,7 @@ public:
///
/// \param[in] interpreter
/// The command interpreter doing the completion.
- ///
- /// FIXME: This is the wrong return value, since we also need to
- /// make a distinction between total number of matches, and the window the
- /// user wants returned.
- ///
- /// \return
- /// \btrue if we were in an option, \bfalse otherwise.
- virtual bool
+ virtual void
HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
OptionElementVector &opt_element_vector,
int opt_element_index,
diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h
index c8fa3901350d..23fadf02e591 100644
--- a/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/include/lldb/Interpreter/ScriptInterpreter.h
@@ -65,6 +65,9 @@ public:
bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
+ // If this is true then any exceptions raised by the script will be
+ // cleared with PyErr_Clear(). If false then they will be left for
+ // the caller to clean up
bool GetMaskoutErrors() const { return m_maskout_errors; }
ExecuteScriptOptions &SetEnableIO(bool enable) {
@@ -208,6 +211,8 @@ public:
virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ StructuredDataImpl *args_data,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan_sp) {
return StructuredData::ObjectSP();
}
@@ -463,8 +468,6 @@ public:
static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
- virtual void ResetOutputFileHandle(FILE *new_fh) {} // By default, do nothing.
-
lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
protected:
diff --git a/include/lldb/Symbol/CallFrameInfo.h b/include/lldb/Symbol/CallFrameInfo.h
new file mode 100644
index 000000000000..765ddb41ab0c
--- /dev/null
+++ b/include/lldb/Symbol/CallFrameInfo.h
@@ -0,0 +1,28 @@
+//===-- CallFrameInfo.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_CallFrameInfo_h_
+#define liblldb_CallFrameInfo_h_
+
+#include "lldb/Core/Address.h"
+
+namespace lldb_private {
+
+class CallFrameInfo {
+public:
+ virtual ~CallFrameInfo() = default;
+
+ virtual bool GetAddressRange(Address addr, AddressRange &range) = 0;
+
+ virtual bool GetUnwindPlan(const Address &addr, UnwindPlan &unwind_plan) = 0;
+ virtual bool GetUnwindPlan(const AddressRange &range, UnwindPlan &unwind_plan) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CallFrameInfo_h_
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
index d0a834e01f3a..c5d840973ae6 100644
--- a/include/lldb/Symbol/ClangASTContext.h
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -26,8 +26,8 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/ConstString.h"
@@ -52,7 +52,14 @@ public:
}
// Constructors and Destructors
- ClangASTContext(const char *triple = nullptr);
+ explicit ClangASTContext(llvm::StringRef triple = "");
+ explicit ClangASTContext(ArchSpec arch);
+
+ /// Constructs a ClangASTContext that uses an existing ASTContext internally.
+ /// Useful when having an existing ASTContext created by Clang.
+ ///
+ /// \param existing_ctxt An existing ASTContext.
+ explicit ClangASTContext(clang::ASTContext &existing_ctxt);
~ClangASTContext() override;
@@ -68,9 +75,8 @@ public:
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
Module *module, Target *target);
- static void EnumerateSupportedLanguages(
- std::set<lldb::LanguageType> &languages_for_types,
- std::set<lldb::LanguageType> &languages_for_expressions);
+ static LanguageSet GetSupportedLanguagesForTypes();
+ static LanguageSet GetSupportedLanguagesForExpressions();
static void Initialize();
@@ -80,8 +86,6 @@ public:
clang::ASTContext *getASTContext();
- void setASTContext(clang::ASTContext *ast_ctx);
-
clang::Builtin::Context *getBuiltinContext();
clang::IdentifierTable *getIdentifierTable();
@@ -107,21 +111,11 @@ public:
void setSema(clang::Sema *s);
clang::Sema *getSema() { return m_sema; }
- void Clear();
-
const char *GetTargetTriple();
- void SetTargetTriple(const char *target_triple);
-
- void SetArchitecture(const ArchSpec &arch);
-
- bool HasExternalSource();
-
void SetExternalSource(
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up);
- void RemoveExternalSource();
-
bool GetCompleteDecl(clang::Decl *decl) {
return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
}
@@ -229,7 +223,8 @@ public:
if (const RecordDeclType *record_decl =
llvm::dyn_cast<RecordDeclType>(named_decl))
compiler_type.SetCompilerType(
- ast, clang::QualType(record_decl->getTypeForDecl(), 0));
+ this, clang::QualType(record_decl->getTypeForDecl(), 0)
+ .getAsOpaquePtr());
}
}
}
@@ -249,7 +244,7 @@ public:
&type_fields,
bool packed = false);
- static bool IsOperator(const char *name,
+ static bool IsOperator(llvm::StringRef name,
clang::OverloadedOperatorKind &op_kind);
// Structure, Unions, Classes
@@ -395,7 +390,8 @@ public:
clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
const char *name,
const CompilerType &param_type,
- int storage);
+ int storage,
+ bool add_decl=false);
void SetFunctionParameters(clang::FunctionDecl *function_decl,
clang::ParmVarDecl **params, unsigned num_params);
@@ -464,6 +460,8 @@ public:
CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx) override;
+ CompilerType GetTypeForDecl(void *opaque_decl) override;
+
// CompilerDeclContext override functions
std::vector<CompilerDecl>
@@ -605,9 +603,6 @@ public:
static bool GetCXXClassName(const CompilerType &type,
std::string &class_name);
- static bool GetObjCClassName(const CompilerType &type,
- std::string &class_name);
-
// Type Completion
bool GetCompleteType(lldb::opaque_compiler_type_t type) override;
@@ -691,6 +686,8 @@ public:
// 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))
@@ -707,7 +704,9 @@ public:
lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override;
- size_t GetTypeBitAlign(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,
@@ -855,7 +854,6 @@ public:
static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
bool has_extern);
- static bool GetHasExternalStorage(const CompilerType &type);
// Tag Declarations
static bool StartTagDeclarationDefinition(const CompilerType &type);
@@ -878,12 +876,6 @@ public:
static CompilerType CreateMemberPointerType(const CompilerType &type,
const CompilerType &pointee_type);
- // Converts "s" to a floating point value and place resulting floating point
- // bytes in the "dst" buffer.
- size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
- const char *s, uint8_t *dst,
- size_t dst_size) override;
-
// Dumping types
#ifndef NDEBUG
/// Convenience LLVM-style dump method for use in the debugger only.
@@ -894,6 +886,14 @@ public:
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,
@@ -977,43 +977,45 @@ protected:
GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
// Classes that inherit from ClangASTContext can see and modify these
- // clang-format off
- 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<DWARFASTParserClang> m_dwarf_ast_parser_up;
- std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
- std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
- std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
- CompleteTagDeclCallback m_callback_tag_decl;
- CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
- void * m_callback_baton;
- clang::ExternalASTMerger::OriginMap m_origins;
- uint32_t m_pointer_byte_size;
- bool m_ast_owned;
- /// 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;
- // clang-format on
+ 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<DWARFASTParserClang> m_dwarf_ast_parser_up;
+ std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
+ std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
+ std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
+ CompleteTagDeclCallback m_callback_tag_decl = nullptr;
+ CompleteObjCInterfaceDeclCallback m_callback_objc_decl = nullptr;
+ void *m_callback_baton = nullptr;
+ clang::ExternalASTMerger::OriginMap m_origins;
+ uint32_t m_pointer_byte_size = 0;
+ bool m_ast_owned = false;
+ /// 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;
+
private:
// For ClangASTContext only
ClangASTContext(const ClangASTContext &);
const ClangASTContext &operator=(const ClangASTContext &);
+ /// Creates the internal ASTContext.
+ void CreateASTContext();
+ void SetTargetTriple(llvm::StringRef target_triple);
};
class ClangASTContextForExpressions : public ClangASTContext {
public:
- ClangASTContextForExpressions(Target &target);
+ ClangASTContextForExpressions(Target &target, ArchSpec arch);
~ClangASTContextForExpressions() override = default;
@@ -1041,13 +1043,9 @@ public:
}
private:
lldb::TargetWP m_target_wp;
- lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the
- ///persistent
- ///variables
- ///associated with
- ///this process for
- ///the expression
- ///parser.
+ std::unique_ptr<PersistentExpressionState>
+ m_persistent_variables; // These are the persistent variables associated
+ // with this process for the expression parser
};
} // namespace lldb_private
diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h
index 353b1232d940..f963f9b2b1dc 100644
--- a/include/lldb/Symbol/ClangASTImporter.h
+++ b/include/lldb/Symbol/ClangASTImporter.h
@@ -210,7 +210,7 @@ public:
void ForgetDestination(clang::ASTContext *dst_ctx);
void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
-private:
+public:
struct DeclOrigin {
DeclOrigin() : ctx(nullptr), decl(nullptr) {}
@@ -235,24 +235,32 @@ private:
typedef std::map<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 and complete declarations that have been
- /// imported in a certain interval.
+ /// 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.
- class ASTImporterDelegate : public clang::ASTImporter {
- public:
+ 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_decls_to_deport(nullptr), m_decls_already_deported(nullptr),
- m_master(master), m_source_ctx(source_ctx) {}
+ 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
@@ -285,43 +293,32 @@ private:
}
};
- protected:
- llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override;
-
- public:
- // A call to "InitDeportWorkQueues" puts the delegate into deport mode.
- // In deport mode, every copied Decl that could require completion is
- // recorded and placed into the decls_to_deport set.
- //
- // A call to "ExecuteDeportWorkQueues" completes all the Decls that
- // are in decls_to_deport, adding any Decls it sees along the way that it
- // hasn't already deported. It proceeds until decls_to_deport is empty.
- //
- // These calls must be paired. Leaving a delegate in deport mode or trying
- // to start deport delegate with a new pair of queues will result in an
- // assertion failure.
-
- void
- InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport,
- std::set<clang::NamedDecl *> *decls_already_deported);
- void ExecuteDeportWorkQueues();
-
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.
std::set<clang::Decl *> m_decls_to_ignore;
- std::set<clang::NamedDecl *> *m_decls_to_deport;
- std::set<clang::NamedDecl *> *m_decls_already_deported;
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;
@@ -387,6 +384,7 @@ private:
}
}
+public:
DeclOrigin GetDeclOrigin(const clang::Decl *decl);
clang::FileManager m_file_manager;
diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h
index c3ba2e2176e7..d132c367b999 100644
--- a/include/lldb/Symbol/CompileUnit.h
+++ b/include/lldb/Symbol/CompileUnit.h
@@ -225,6 +225,14 @@ public:
DebugMacros *GetDebugMacros();
+ /// Apply a lambda to each external lldb::Module referenced by this
+ /// compilation unit. Recursively also descends into the referenced external
+ /// modules of any encountered compilation unit.
+ ///
+ /// \param[in] lambda
+ /// The lambda that should be applied to every module.
+ void ForEachExternalModule(llvm::function_ref<void(lldb::ModuleSP)> f);
+
/// Get the compile unit's support file list.
///
/// The support file list is used by the line table, and any objects that
@@ -298,6 +306,8 @@ public:
/// A line table object pointer that this object now owns.
void SetLineTable(LineTable *line_table);
+ void SetSupportFiles(const FileSpecList &support_files);
+
void SetDebugMacros(const DebugMacrosSP &debug_macros);
/// Set accessor for the variable list.
diff --git a/include/lldb/Symbol/CompilerType.h b/include/lldb/Symbol/CompilerType.h
index 98d916597f42..bb9881c0bae3 100644
--- a/include/lldb/Symbol/CompilerType.h
+++ b/include/lldb/Symbol/CompilerType.h
@@ -13,7 +13,6 @@
#include <string>
#include <vector>
-#include "lldb/Core/ClangForward.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/APSInt.h"
@@ -32,7 +31,6 @@ class CompilerType {
public:
// Constructors and Destructors
CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type);
- CompilerType(clang::ASTContext *ast_context, clang::QualType qual_type);
CompilerType(const CompilerType &rhs)
: m_type(rhs.m_type), m_type_system(rhs.m_type_system) {}
@@ -169,8 +167,6 @@ public:
void SetCompilerType(TypeSystem *type_system,
lldb::opaque_compiler_type_t type);
- void SetCompilerType(clang::ASTContext *ast, clang::QualType qual_type);
-
unsigned GetTypeQualifiers() const;
// Creating related types
@@ -257,7 +253,7 @@ public:
lldb::Format GetFormat() const;
- size_t GetTypeBitAlign() const;
+ llvm::Optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const;
uint32_t GetNumChildren(bool omit_empty_base_classes,
const ExecutionContext *exe_ctx) const;
@@ -336,13 +332,6 @@ public:
bool IsMeaninglessWithoutDynamicResolution() const;
- // Pointers & References
-
- // Converts "s" to a floating point value and place resulting floating point
- // bytes in the "dst" buffer.
- size_t ConvertStringToFloatValue(const char *s, uint8_t *dst,
- size_t dst_size) const;
-
// Dumping types
#ifndef NDEBUG
diff --git a/include/lldb/Symbol/DeclVendor.h b/include/lldb/Symbol/DeclVendor.h
index 9c10fe1177fb..748c0c8ac961 100644
--- a/include/lldb/Symbol/DeclVendor.h
+++ b/include/lldb/Symbol/DeclVendor.h
@@ -9,11 +9,8 @@
#ifndef liblldb_DeclVendor_h_
#define liblldb_DeclVendor_h_
-#include "lldb/Core/ClangForward.h"
#include "lldb/lldb-defines.h"
-#include "clang/AST/ExternalASTMerger.h"
-
#include <vector>
namespace lldb_private {
@@ -22,11 +19,19 @@ namespace lldb_private {
// declarations that are not necessarily backed by a specific symbol file.
class DeclVendor {
public:
+ enum DeclVendorKind {
+ eClangDeclVendor,
+ eClangModuleDeclVendor,
+ eAppleObjCDeclVendor,
+ eLastClangDeclVendor,
+ };
// Constructors and Destructors
- DeclVendor() {}
+ DeclVendor(DeclVendorKind kind) : m_kind(kind) {}
virtual ~DeclVendor() {}
+ DeclVendorKind GetKind() const { return m_kind; }
+
/// Look up the set of Decls that the DeclVendor currently knows about
/// matching a given name.
///
@@ -45,7 +50,7 @@ public:
/// max_matches.
virtual uint32_t FindDecls(ConstString name, bool append,
uint32_t max_matches,
- std::vector<clang::NamedDecl *> &decls) = 0;
+ std::vector<CompilerDecl> &decls) = 0;
/// Look up the types that the DeclVendor currently knows about matching a
/// given name.
@@ -60,16 +65,11 @@ public:
/// The vector of CompilerTypes that was found.
std::vector<CompilerType> FindTypes(ConstString name, uint32_t max_matches);
- /// Interface for ExternalASTMerger. Returns an ImporterSource
- /// allowing type completion.
- ///
- /// \return
- /// An ImporterSource for this DeclVendor.
- virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0;
-
private:
// For DeclVendor only
DISALLOW_COPY_AND_ASSIGN(DeclVendor);
+
+ const DeclVendorKind m_kind;
};
} // namespace lldb_private
diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h
index cc767d4e1e82..c49f6b0fa942 100644
--- a/include/lldb/Symbol/FuncUnwinders.h
+++ b/include/lldb/Symbol/FuncUnwinders.h
@@ -76,6 +76,11 @@ public:
lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread);
+ lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target);
+
+ lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target,
+ Thread &thread);
+
lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);
lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
@@ -113,10 +118,12 @@ private:
std::recursive_mutex m_mutex;
lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
+ lldb::UnwindPlanSP m_unwind_plan_object_file_sp;
lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
// augmented by assembly inspection so it's valid everywhere
+ lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp;
lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
@@ -130,7 +137,9 @@ private:
// Fetching the UnwindPlans can be expensive - if we've already attempted to
// get one & failed, don't try again.
bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1,
+ m_tried_unwind_plan_object_file : 1,
m_tried_unwind_plan_debug_frame : 1,
+ m_tried_unwind_plan_object_file_augmented : 1,
m_tried_unwind_plan_eh_frame_augmented : 1,
m_tried_unwind_plan_debug_frame_augmented : 1,
m_tried_unwind_plan_compact_unwind : 1,
diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h
index f68a16705d93..1b23a99373ca 100644
--- a/include/lldb/Symbol/Function.h
+++ b/include/lldb/Symbol/Function.h
@@ -140,7 +140,7 @@ public:
/// \param[in] call_decl_ptr
/// Optional calling location declaration information that
/// describes from where this inlined function was called.
- InlineFunctionInfo(const char *name, const char *mangled,
+ InlineFunctionInfo(const char *name, llvm::StringRef mangled,
const Declaration *decl_ptr,
const Declaration *call_decl_ptr);
@@ -246,10 +246,22 @@ private:
class Function;
+/// \class CallSiteParameter Function.h "lldb/Symbol/Function.h"
+///
+/// Represent the locations of a parameter at a call site, both in the caller
+/// and in the callee.
+struct CallSiteParameter {
+ DWARFExpression LocationInCallee;
+ DWARFExpression LocationInCaller;
+};
+
+/// A vector of \c CallSiteParameter.
+using CallSiteParameterArray = llvm::SmallVector<CallSiteParameter, 0>;
+
/// \class CallEdge Function.h "lldb/Symbol/Function.h"
///
/// Represent a call made within a Function. This can be used to find a path
-/// in the call graph between two functions.
+/// in the call graph between two functions, or to evaluate DW_OP_entry_value.
class CallEdge {
public:
/// Construct a call edge using a symbol name to identify the calling
@@ -259,7 +271,8 @@ public:
/// TODO: A symbol name may not be globally unique. To disambiguate ODR
/// conflicts, it's necessary to determine the \c Target a call edge is
/// associated with before resolving it.
- CallEdge(const char *symbol_name, lldb::addr_t return_pc);
+ CallEdge(const char *symbol_name, lldb::addr_t return_pc,
+ CallSiteParameterArray parameters);
CallEdge(CallEdge &&) = default;
CallEdge &operator=(CallEdge &&) = default;
@@ -279,6 +292,9 @@ public:
/// offset.
lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; }
+ /// Get the call site parameters available at this call edge.
+ llvm::ArrayRef<CallSiteParameter> GetCallSiteParameters() const;
+
private:
void ParseSymbolFileAndResolve(ModuleList &images);
@@ -294,6 +310,8 @@ private:
/// gives the return PC for the call.
lldb::addr_t return_pc;
+ CallSiteParameterArray parameters;
+
/// Whether or not an attempt was made to find the callee's definition.
bool resolved;
@@ -402,6 +420,11 @@ public:
/// return None.
llvm::MutableArrayRef<CallEdge> GetTailCallingEdges();
+ /// Get the outgoing call edge from this function which has the given return
+ /// address \p return_pc, or return nullptr. Note that this will not return a
+ /// tail-calling edge.
+ CallEdge *GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target);
+
/// Get accessor for the block list.
///
/// \return
@@ -564,6 +587,8 @@ protected:
uint32_t
m_prologue_byte_size; ///< Compute the prologue size once and cache it
+ // TODO: Use a layer of indirection to point to call edges, to save space
+ // when call info hasn't been parsed.
bool m_call_edges_resolved = false; ///< Whether call site info has been
/// parsed.
std::vector<CallEdge> m_call_edges; ///< Outgoing call edges.
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
index 84683e3f2a3f..4d04f23a8286 100644
--- a/include/lldb/Symbol/ObjectFile.h
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -63,16 +63,22 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
public:
enum Type {
eTypeInvalid = 0,
- eTypeCoreFile, /// A core file that has a checkpoint of a program's
- /// execution state
- eTypeExecutable, /// A normal executable
- eTypeDebugInfo, /// An object file that contains only debug information
- eTypeDynamicLinker, /// The platform's dynamic linker executable
- eTypeObjectFile, /// An intermediate object file
- eTypeSharedLibrary, /// A shared library that can be used during execution
- eTypeStubLibrary, /// A library that can be linked against but not used for
- /// execution
- eTypeJIT, /// JIT code that has symbols, sections and possibly debug info
+ /// A core file that has a checkpoint of a program's execution state.
+ eTypeCoreFile,
+ /// A normal executable.
+ eTypeExecutable,
+ /// An object file that contains only debug information.
+ eTypeDebugInfo,
+ /// The platform's dynamic linker executable.
+ eTypeDynamicLinker,
+ /// An intermediate object file.
+ eTypeObjectFile,
+ /// A shared library that can be used during execution.
+ eTypeSharedLibrary,
+ /// A library that can be linked against but not used for execution.
+ eTypeStubLibrary,
+ /// JIT code that has symbols, sections and possibly debug info.
+ eTypeJIT,
eTypeUnknown
};
@@ -201,9 +207,13 @@ public:
/// \b false otherwise and \a archive_file and \a archive_object
/// are guaranteed to be remain unchanged.
static bool SplitArchivePathWithObject(
- const char *path_with_object, lldb_private::FileSpec &archive_file,
+ llvm::StringRef path_with_object, lldb_private::FileSpec &archive_file,
lldb_private::ConstString &archive_object, bool must_exist);
+ // LLVM RTTI support
+ static char ID;
+ virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+
/// Gets the address size in bytes for the current object file.
///
/// \return
@@ -366,17 +376,6 @@ public:
/// returned.
virtual UUID GetUUID() = 0;
- /// Gets the symbol file spec list for this object file.
- ///
- /// If the object file format contains a debug symbol file link, the values
- /// will be returned in the FileSpecList.
- ///
- /// \return
- /// Returns filespeclist.
- virtual lldb_private::FileSpecList GetDebugSymbolFilePaths() {
- return FileSpecList();
- }
-
/// Gets the file spec list of libraries re-exported by this object file.
///
/// If the object file format has the notion of one library re-exporting the
@@ -657,6 +656,9 @@ public:
/// \return
virtual std::vector<LoadableData> GetLoadableData(Target &target);
+ /// Creates a plugin-specific call frame info
+ virtual std::unique_ptr<CallFrameInfo> CreateCallFrameInfo();
+
protected:
// Member variables.
FileSpec m_file;
diff --git a/include/lldb/Symbol/PostfixExpression.h b/include/lldb/Symbol/PostfixExpression.h
index e3a8587a5f84..fa7793315899 100644
--- a/include/lldb/Symbol/PostfixExpression.h
+++ b/include/lldb/Symbol/PostfixExpression.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include <vector>
namespace lldb_private {
@@ -211,7 +212,10 @@ inline T *MakeNode(llvm::BumpPtrAllocator &alloc, Args &&... args) {
/// Parse the given postfix expression. The parsed nodes are placed into the
/// provided allocator.
-Node *Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);
+Node *ParseOneExpression(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);
+
+std::vector<std::pair<llvm::StringRef, Node *>>
+ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc);
/// Serialize the given expression tree as DWARF. The result is written into the
/// given stream. The AST should not contain any SymbolNodes. If the expression
diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h
index 1cbc2f5492f4..b7f179d1449b 100644
--- a/include/lldb/Symbol/Symbol.h
+++ b/include/lldb/Symbol/Symbol.h
@@ -24,9 +24,8 @@ public:
// drastically different meanings and sorting requirements.
Symbol();
- Symbol(uint32_t symID, const char *name, bool name_is_mangled,
- lldb::SymbolType type, bool external, bool is_debug,
- bool is_trampoline, bool is_artificial,
+ Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type,
+ bool external, bool is_debug, bool is_trampoline, bool is_artificial,
const lldb::SectionSP &section_sp, lldb::addr_t value,
lldb::addr_t size, bool size_is_valid,
bool contains_linker_annotations, uint32_t flags);
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
index 55a345489358..76ec1a7de68e 100644
--- a/include/lldb/Symbol/SymbolContext.h
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -470,6 +470,8 @@ public:
/// Returns the number of symbol context objects in the list.
uint32_t GetSize() const;
+ bool IsEmpty() const;
+
uint32_t NumLineEntriesWithLine(uint32_t line) const;
void GetDescription(Stream *s, lldb::DescriptionLevel level,
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
index dbb723e9d369..6724b425abf3 100644
--- a/include/lldb/Symbol/SymbolFile.h
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -16,9 +16,11 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/lldb-private.h"
-
#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/Errc.h"
#include <mutex>
@@ -49,11 +51,12 @@ public:
kAllAbilities = ((1u << 7) - 1u)
};
- static SymbolFile *FindPlugin(ObjectFile *obj_file);
+ static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFile(ObjectFile *obj_file)
- : m_obj_file(obj_file), m_abilities(0), m_calculated_abilities(false) {}
+ SymbolFile(lldb::ObjectFileSP objfile_sp)
+ : m_objfile_sp(std::move(objfile_sp)), m_abilities(0),
+ m_calculated_abilities(false) {}
~SymbolFile() override {}
@@ -110,13 +113,18 @@ public:
// Compile Unit function calls
// Approach 1 - iterator
- virtual uint32_t GetNumCompileUnits() = 0;
- virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0;
+ uint32_t GetNumCompileUnits();
+ lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx);
+
+ Symtab *GetSymtab();
virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;
+ virtual void
+ ForEachExternalModule(CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) {}
virtual bool ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) = 0;
virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
@@ -165,43 +173,41 @@ public:
SymbolContextList &sc_list);
virtual void DumpClangAST(Stream &s) {}
- virtual uint32_t
+ virtual void
FindGlobalVariables(ConstString name,
const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables);
- virtual uint32_t FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables);
- virtual uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list);
- virtual uint32_t FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list);
- virtual uint32_t
+ virtual void FindGlobalVariables(const RegularExpression &regex,
+ uint32_t max_matches,
+ VariableList &variables);
+ virtual void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list);
+ virtual void FindFunctions(const RegularExpression &regex,
+ bool include_inlines, SymbolContextList &sc_list);
+ virtual void
FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types);
- virtual size_t FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types);
+
+ /// Find types specified by a CompilerContextPattern.
+ /// \param languages Only return results in these languages.
+ virtual void FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types);
virtual void
GetMangledNamesForFunction(const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names);
- // virtual uint32_t FindTypes (const SymbolContext& sc, const
- // RegularExpression& regex, bool append, uint32_t max_matches, TypeList&
- // types) = 0;
- virtual TypeList *GetTypeList();
- virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) = 0;
+
+ virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) = 0;
virtual void PreloadSymbols();
- virtual lldb_private::TypeSystem *
+ virtual llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language);
virtual CompilerDeclContext
@@ -210,8 +216,9 @@ public:
return CompilerDeclContext();
}
- ObjectFile *GetObjectFile() { return m_obj_file; }
- const ObjectFile *GetObjectFile() const { return m_obj_file; }
+ ObjectFile *GetObjectFile() { return m_objfile_sp.get(); }
+ const ObjectFile *GetObjectFile() const { return m_objfile_sp.get(); }
+ ObjectFile *GetMainObjectFile();
virtual std::vector<CallEdge> ParseCallEdgesInFunction(UserID func_id) {
return {};
@@ -221,7 +228,7 @@ public:
/// Notify the SymbolFile that the file addresses in the Sections
/// for this module have been changed.
- virtual void SectionFileAddressesChanged() {}
+ virtual void SectionFileAddressesChanged();
struct RegisterInfoResolver {
virtual ~RegisterInfoResolver(); // anchor
@@ -235,12 +242,30 @@ public:
return nullptr;
}
- virtual void Dump(Stream &s) {}
+ /// Return the number of stack bytes taken up by the parameters to this
+ /// function.
+ virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) {
+ return llvm::createStringError(make_error_code(llvm::errc::not_supported),
+ "Operation not supported.");
+ }
+
+ virtual void Dump(Stream &s);
protected:
void AssertModuleLock();
-
- ObjectFile *m_obj_file; // The object file that symbols can be extracted from.
+ virtual uint32_t CalculateNumCompileUnits() = 0;
+ virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
+ virtual TypeList &GetTypeList() { return m_type_list; }
+
+ void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp);
+
+ lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in
+ // case it isn't the same as the module
+ // object file (debug symbols in a separate
+ // file)
+ llvm::Optional<std::vector<lldb::CompUnitSP>> m_compile_units;
+ TypeList m_type_list;
+ Symtab *m_symtab = nullptr;
uint32_t m_abilities;
bool m_calculated_abilities;
diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h
index c4015ff03492..96c6ea5c7332 100644
--- a/include/lldb/Symbol/SymbolVendor.h
+++ b/include/lldb/Symbol/SymbolVendor.h
@@ -14,7 +14,6 @@
#include "lldb/Core/ModuleChild.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/SourceModule.h"
-#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/DenseSet.h"
@@ -40,123 +39,16 @@ public:
void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp);
- virtual void Dump(Stream *s);
-
- virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit);
-
- virtual size_t ParseFunctions(CompileUnit &comp_unit);
-
- virtual bool ParseLineTable(CompileUnit &comp_unit);
-
- virtual bool ParseDebugMacros(CompileUnit &comp_unit);
-
- virtual bool ParseSupportFiles(CompileUnit &comp_unit,
- FileSpecList &support_files);
-
- virtual bool ParseIsOptimized(CompileUnit &comp_unit);
-
- virtual size_t ParseTypes(CompileUnit &comp_unit);
-
- virtual bool
- ParseImportedModules(const SymbolContext &sc,
- std::vector<SourceModule> &imported_modules);
-
- virtual size_t ParseBlocksRecursive(Function &func);
-
- virtual size_t ParseVariablesForContext(const SymbolContext &sc);
-
- virtual Type *ResolveTypeUID(lldb::user_id_t type_uid);
-
- virtual uint32_t ResolveSymbolContext(const Address &so_addr,
- lldb::SymbolContextItem resolve_scope,
- SymbolContext &sc);
-
- virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec,
- uint32_t line, bool check_inlines,
- lldb::SymbolContextItem resolve_scope,
- SymbolContextList &sc_list);
-
- virtual size_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches,
- VariableList &variables);
-
- virtual size_t FindGlobalVariables(const RegularExpression &regex,
- size_t max_matches,
- VariableList &variables);
-
- virtual size_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list);
-
- virtual size_t FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list);
-
- virtual size_t
- FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
-
- virtual size_t FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types);
-
- virtual CompilerDeclContext
- FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx);
-
- virtual size_t GetNumCompileUnits();
-
- virtual bool SetCompileUnitAtIndex(size_t cu_idx,
- const lldb::CompUnitSP &cu_sp);
-
- virtual lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx);
-
- TypeList &GetTypeList() { return m_type_list; }
-
- const TypeList &GetTypeList() const { return m_type_list; }
-
- virtual size_t GetTypes(SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask, TypeList &type_list);
-
SymbolFile *GetSymbolFile() { return m_sym_file_up.get(); }
- FileSpec GetMainFileSpec() const;
-
- // Get module unified section list symbol table.
- virtual Symtab *GetSymtab();
-
- // Clear module unified section list symbol table.
- virtual void ClearSymtab();
-
- /// Notify the SymbolVendor that the file addresses in the Sections
- /// for this module have been changed.
- virtual void SectionFileAddressesChanged();
-
// PluginInterface protocol
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
protected:
- // Classes that inherit from SymbolVendor can see and modify these
- typedef std::vector<lldb::CompUnitSP> CompileUnits;
- typedef CompileUnits::iterator CompileUnitIter;
- typedef CompileUnits::const_iterator CompileUnitConstIter;
-
- TypeList m_type_list; // Uniqued types for all parsers owned by this module
- CompileUnits m_compile_units; // The current compile units
- lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in
- // case it isn't the same as the module
- // object file (debug symbols in a separate
- // file)
std::unique_ptr<SymbolFile> m_sym_file_up; // A single symbol file. Subclasses
// can add more of these if needed.
- Symtab *m_symtab; // Save a symtab once to not pass it through `AddSymbols` of
- // the symbol file each time when it is needed
private:
// For SymbolVendor only
diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h
index 868edcdc9290..99d15771ccc5 100644
--- a/include/lldb/Symbol/Symtab.h
+++ b/include/lldb/Symbol/Symtab.h
@@ -92,15 +92,15 @@ public:
const RegularExpression &regex, lldb::SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &indexes);
- size_t FindAllSymbolsWithNameAndType(ConstString name,
- lldb::SymbolType symbol_type,
- std::vector<uint32_t> &symbol_indexes);
- size_t FindAllSymbolsWithNameAndType(ConstString name,
- lldb::SymbolType symbol_type,
- Debug symbol_debug_type,
- Visibility symbol_visibility,
- std::vector<uint32_t> &symbol_indexes);
- size_t FindAllSymbolsMatchingRexExAndType(
+ void FindAllSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ std::vector<uint32_t> &symbol_indexes);
+ void FindAllSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ Debug symbol_debug_type,
+ Visibility symbol_visibility,
+ std::vector<uint32_t> &symbol_indexes);
+ void FindAllSymbolsMatchingRexExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &symbol_indexes);
@@ -112,8 +112,8 @@ public:
Symbol *FindSymbolContainingFileAddress(lldb::addr_t file_addr);
void ForEachSymbolContainingFileAddress(
lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
- size_t FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
- SymbolContextList &sc_list);
+ void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
+ SymbolContextList &sc_list);
void CalculateSymbolSizes();
void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
index efc9bf049a35..446e043a95ee 100644
--- a/include/lldb/Symbol/Type.h
+++ b/include/lldb/Symbol/Type.h
@@ -9,7 +9,6 @@
#ifndef liblldb_Type_h_
#define liblldb_Type_h_
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Declaration.h"
@@ -22,22 +21,28 @@
#include <set>
namespace lldb_private {
-// CompilerContext allows an array of these items to be passed to perform
-// detailed lookups in SymbolVendor and SymbolFile functions.
+
+/// CompilerContext allows an array of these items to be passed to perform
+/// detailed lookups in SymbolVendor and SymbolFile functions.
struct CompilerContext {
- CompilerContext(CompilerContextKind t, ConstString n)
- : type(t), name(n) {}
+ CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {}
bool operator==(const CompilerContext &rhs) const {
- return type == rhs.type && name == rhs.name;
+ return kind == rhs.kind && name == rhs.name;
}
+ bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); }
void Dump() const;
- CompilerContextKind type;
+ CompilerContextKind kind;
ConstString name;
};
+/// Match \p context_chain against \p pattern, which may contain "Any"
+/// kinds. The \p context_chain should *not* contain any "Any" kinds.
+bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain,
+ llvm::ArrayRef<CompilerContext> pattern);
+
class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
public UserID {
public:
@@ -117,8 +122,6 @@ public:
SymbolFile *GetSymbolFile() { return m_symbol_file; }
const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
- TypeList *GetTypeList();
-
ConstString GetName();
llvm::Optional<uint64_t> GetByteSize();
diff --git a/include/lldb/Symbol/TypeList.h b/include/lldb/Symbol/TypeList.h
index 982f673fff6e..38342b6d6f4f 100644
--- a/include/lldb/Symbol/TypeList.h
+++ b/include/lldb/Symbol/TypeList.h
@@ -28,15 +28,14 @@ public:
void Dump(Stream *s, bool show_context);
- // lldb::TypeSP
- // FindType(lldb::user_id_t uid);
-
TypeList FindTypes(ConstString name);
void Insert(const lldb::TypeSP &type);
uint32_t GetSize() const;
+ bool Empty() const { return !GetSize(); }
+
lldb::TypeSP GetTypeAtIndex(uint32_t idx);
typedef std::vector<lldb::TypeSP> collection;
diff --git a/include/lldb/Symbol/TypeSystem.h b/include/lldb/Symbol/TypeSystem.h
index 4bef2a4446eb..07295c244a5d 100644
--- a/include/lldb/Symbol/TypeSystem.h
+++ b/include/lldb/Symbol/TypeSystem.h
@@ -14,8 +14,11 @@
#include <mutex>
#include <string>
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Expression/Expression.h"
@@ -29,7 +32,24 @@ class PDBASTParser;
namespace lldb_private {
-// Interface for representing the Type Systems in different languages.
+/// A SmallBitVector that represents a set of source languages (\p
+/// lldb::LanguageType). Each lldb::LanguageType is represented by
+/// the bit with the position of its enumerator. The largest
+/// LanguageType is < 64, so this is space-efficient and on 64-bit
+/// architectures a LanguageSet can be completely stack-allocated.
+struct LanguageSet {
+ llvm::SmallBitVector bitvector;
+ LanguageSet();
+
+ /// If the set contains a single language only, return it.
+ llvm::Optional<lldb::LanguageType> GetSingularLanguage();
+ void Insert(lldb::LanguageType language);
+ bool Empty() const;
+ size_t Size() const;
+ bool operator[](unsigned i) const;
+};
+
+/// Interface for representing the Type Systems in different languages.
class TypeSystem : public PluginInterface {
public:
// Intrusive type system that allows us to use llvm casting.
@@ -107,6 +127,8 @@ public:
virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx);
+ virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0;
+
// CompilerDeclContext functions
virtual std::vector<CompilerDecl>
@@ -255,6 +277,8 @@ public:
// Exploring the type
+ virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0;
+
virtual llvm::Optional<uint64_t>
GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) = 0;
@@ -375,12 +399,6 @@ public:
lldb::offset_t data_offset,
size_t data_byte_size) = 0;
- // Converts "s" to a floating point value and place resulting floating point
- // bytes in the "dst" buffer.
- virtual size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
- const char *s, uint8_t *dst,
- size_t dst_size) = 0;
-
// TODO: Determine if these methods should move to ClangASTContext.
virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
@@ -391,7 +409,9 @@ public:
virtual bool IsCStringType(lldb::opaque_compiler_type_t type,
uint32_t &length) = 0;
- virtual size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) = 0;
+ virtual llvm::Optional<size_t>
+ GetTypeBitAlign(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) = 0;
virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0;
@@ -491,18 +511,15 @@ public:
// callback to keep iterating, false to stop iterating.
void ForEach(std::function<bool(TypeSystem *)> const &callback);
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language,
- Module *module, bool can_create);
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language, Module *module,
+ bool can_create);
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language,
- Target *target, bool can_create);
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language, Target *target,
+ bool can_create);
protected:
- // This function does not take the map mutex, and should only be called from
- // functions that do take the mutex.
- void AddToMap(lldb::LanguageType language,
- lldb::TypeSystemSP const &type_system_sp);
-
typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection;
mutable std::mutex m_mutex; ///< A mutex to keep this object happy in
///multi-threaded environments.
diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h
index 2b49acaafa04..fa41ba5d056a 100644
--- a/include/lldb/Symbol/UnwindPlan.h
+++ b/include/lldb/Symbol/UnwindPlan.h
@@ -201,7 +201,8 @@ public:
unspecified, // not specified
isRegisterPlusOffset, // FA = register + offset
isRegisterDereferenced, // FA = [reg]
- isDWARFExpression // FA = eval(dwarf_expr)
+ isDWARFExpression, // FA = eval(dwarf_expr)
+ isRaSearch, // FA = SP + offset + ???
};
FAValue() : m_type(unspecified), m_value() {}
@@ -214,6 +215,11 @@ public:
bool IsUnspecified() const { return m_type == unspecified; }
+ void SetRaSearch(int32_t offset) {
+ m_type = isRaSearch;
+ m_value.ra_search_offset = offset;
+ }
+
bool IsRegisterPlusOffset() const {
return m_type == isRegisterPlusOffset;
}
@@ -250,9 +256,14 @@ public:
ValueType GetValueType() const { return m_type; }
int32_t GetOffset() const {
- if (m_type == isRegisterPlusOffset)
- return m_value.reg.offset;
- return 0;
+ switch (m_type) {
+ case isRegisterPlusOffset:
+ return m_value.reg.offset;
+ case isRaSearch:
+ return m_value.ra_search_offset;
+ default:
+ return 0;
+ }
}
void IncOffset(int32_t delta) {
@@ -304,6 +315,8 @@ public:
const uint8_t *opcodes;
uint16_t length;
} expr;
+ // For m_type == isRaSearch
+ int32_t ra_search_offset;
} m_value;
}; // class FAValue
@@ -370,6 +383,7 @@ public:
m_return_addr_register(LLDB_INVALID_REGNUM), m_source_name(),
m_plan_is_sourced_from_compiler(eLazyBoolCalculate),
m_plan_is_valid_at_all_instruction_locations(eLazyBoolCalculate),
+ m_plan_is_for_signal_trap(eLazyBoolCalculate),
m_lsda_address(), m_personality_func_addr() {}
// Performs a deep copy of the plan, including all the rows (expensive).
@@ -463,6 +477,17 @@ public:
m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
}
+ // Is this UnwindPlan for a signal trap frame? If so, then its saved pc
+ // may have been set manually by the signal dispatch code and therefore
+ // not follow a call to the child frame.
+ lldb_private::LazyBool GetUnwindPlanForSignalTrap() const {
+ return m_plan_is_for_signal_trap;
+ }
+
+ void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap) {
+ m_plan_is_for_signal_trap = is_for_signal_trap;
+ }
+
int GetRowCount() const;
void Clear() {
@@ -472,6 +497,7 @@ public:
m_source_name.Clear();
m_plan_is_sourced_from_compiler = eLazyBoolCalculate;
m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate;
+ m_plan_is_for_signal_trap = eLazyBoolCalculate;
m_lsda_address.Clear();
m_personality_func_addr.Clear();
}
@@ -502,6 +528,7 @@ private:
m_source_name; // for logging, where this UnwindPlan originated from
lldb_private::LazyBool m_plan_is_sourced_from_compiler;
lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
+ lldb_private::LazyBool m_plan_is_for_signal_trap;
Address m_lsda_address; // Where the language specific data area exists in the
// module - used
diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h
index b4d7f0661d5b..c1dc519c4b20 100644
--- a/include/lldb/Symbol/UnwindTable.h
+++ b/include/lldb/Symbol/UnwindTable.h
@@ -27,6 +27,8 @@ public:
~UnwindTable();
+ lldb_private::CallFrameInfo *GetObjectFileUnwindInfo();
+
lldb_private::DWARFCallFrameInfo *GetEHFrameInfo();
lldb_private::DWARFCallFrameInfo *GetDebugFrameInfo();
@@ -71,6 +73,7 @@ private:
bool m_initialized; // delay some initialization until ObjectFile is set up
std::mutex m_mutex;
+ std::unique_ptr<CallFrameInfo> m_object_file_unwind_up;
std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up;
std::unique_ptr<DWARFCallFrameInfo> m_debug_frame_up;
std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up;
diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h
index 12daecfc04e6..30f57f1f9110 100644
--- a/include/lldb/Symbol/Variable.h
+++ b/include/lldb/Symbol/Variable.h
@@ -26,15 +26,14 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
public:
typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList;
- // Constructors and Destructors
- Variable(lldb::user_id_t uid, const char *name,
- const char
- *mangled, // The mangled or fully qualified name of the variable.
- const lldb::SymbolFileTypeSP &symfile_type_sp,
- lldb::ValueType scope, SymbolContextScope *owner_scope,
- const RangeList &scope_range, Declaration *decl,
- const DWARFExpression &location, bool external, bool artificial,
- bool static_member = false);
+ /// Constructors and Destructors.
+ ///
+ /// \param mangled The mangled or fully qualified name of the variable.
+ Variable(lldb::user_id_t uid, const char *name, const char *mangled,
+ const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope,
+ SymbolContextScope *owner_scope, const RangeList &scope_range,
+ Declaration *decl, const DWARFExpression &location, bool external,
+ bool artificial, bool static_member = false);
virtual ~Variable();
@@ -50,11 +49,11 @@ public:
SymbolContextScope *GetSymbolContextScope() const { return m_owner_scope; }
- // Since a variable can have a basename "i" and also a mangled named
- // "_ZN12_GLOBAL__N_11iE" and a demangled mangled name "(anonymous
- // namespace)::i", this function will allow a generic match function that can
- // be called by commands and expression parsers to make sure we match
- // anything we come across.
+ /// Since a variable can have a basename "i" and also a mangled named
+ /// "_ZN12_GLOBAL__N_11iE" and a demangled mangled name "(anonymous
+ /// namespace)::i", this function will allow a generic match function that can
+ /// be called by commands and expression parsers to make sure we match
+ /// anything we come across.
bool NameMatches(ConstString name) const;
bool NameMatches(const RegularExpression &regex) const;
@@ -99,34 +98,42 @@ public:
GetVariableCallback callback, void *baton, VariableList &variable_list,
ValueObjectList &valobj_list);
- static size_t AutoComplete(const ExecutionContext &exe_ctx,
- CompletionRequest &request);
+ static void AutoComplete(const ExecutionContext &exe_ctx,
+ CompletionRequest &request);
CompilerDeclContext GetDeclContext();
CompilerDecl GetDecl();
protected:
- ConstString m_name; // The basename of the variable (no namespaces)
- Mangled m_mangled; // The mangled name of the variable
- lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable
- // (int, struct, class, etc)
- lldb::ValueType m_scope; // global, parameter, local
- SymbolContextScope
- *m_owner_scope; // The symbol file scope that this variable was defined in
- RangeList m_scope_range; // The list of ranges inside the owner's scope where
- // this variable is valid
- Declaration m_declaration; // Declaration location for this item.
- DWARFExpression m_location; // The location of this variable that can be fed
- // to DWARFExpression::Evaluate()
- uint8_t m_external : 1, // Visible outside the containing compile unit?
- m_artificial : 1, // Non-zero if the variable is not explicitly declared
- // in source
- m_loc_is_const_data : 1, // The m_location expression contains the
- // constant variable value data, not a DWARF
- // location
- m_static_member : 1; // Non-zero if variable is static member of a class
- // or struct.
+ /// The basename of the variable (no namespaces).
+ ConstString m_name;
+ /// The mangled name of the variable.
+ Mangled m_mangled;
+ /// The type pointer of the variable (int, struct, class, etc)
+ /// global, parameter, local.
+ lldb::SymbolFileTypeSP m_symfile_type_sp;
+ lldb::ValueType m_scope;
+ /// The symbol file scope that this variable was defined in
+ SymbolContextScope *m_owner_scope;
+ /// The list of ranges inside the owner's scope where this variable
+ /// is valid.
+ RangeList m_scope_range;
+ /// Declaration location for this item.
+ Declaration m_declaration;
+ /// The location of this variable that can be fed to
+ /// DWARFExpression::Evaluate().
+ DWARFExpression m_location;
+ /// Visible outside the containing compile unit?
+ unsigned m_external : 1;
+ /// Non-zero if the variable is not explicitly declared in source.
+ unsigned m_artificial : 1;
+ /// The m_location expression contains the constant variable value
+ /// data, not a DWARF location.
+ unsigned m_loc_is_const_data : 1;
+ /// Non-zero if variable is static member of a class or struct.
+ unsigned m_static_member : 1;
+
private:
Variable(const Variable &rhs) = delete;
Variable &operator=(const Variable &rhs) = delete;
diff --git a/include/lldb/Symbol/VerifyDecl.h b/include/lldb/Symbol/VerifyDecl.h
deleted file mode 100644
index f412b94a7859..000000000000
--- a/include/lldb/Symbol/VerifyDecl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- VerifyDecl.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_VariableList_h_
-#define lldb_VariableList_h_
-
-#include "lldb/Core/ClangForward.h"
-
-namespace lldb_private {
-void VerifyDecl(clang::Decl *decl);
-}
-
-#endif
diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h
index f254839fc975..93378abc2ac2 100644
--- a/include/lldb/Target/ABI.h
+++ b/include/lldb/Target/ABI.h
@@ -15,8 +15,8 @@
#include "lldb/lldb-private.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/MC/MCRegisterInfo.h"
-// forward define the llvm::Type class
namespace llvm {
class Type;
}
@@ -124,6 +124,8 @@ public:
return pc;
}
+ llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; }
+
virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0;
bool GetRegisterInfoByName(ConstString name, RegisterInfo &info);
@@ -136,13 +138,19 @@ public:
static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch);
protected:
- // Classes that inherit from ABI can see and modify these
- ABI(lldb::ProcessSP process_sp) {
- if (process_sp.get())
- m_process_wp = process_sp;
+ ABI(lldb::ProcessSP process_sp, std::unique_ptr<llvm::MCRegisterInfo> info_up)
+ : m_process_wp(process_sp), m_mc_register_info_up(std::move(info_up)) {
+ assert(m_mc_register_info_up && "ABI must have MCRegisterInfo");
}
+ /// Utility function to construct a MCRegisterInfo using the ArchSpec triple.
+ /// Plugins wishing to customize the construction can construct the
+ /// MCRegisterInfo themselves.
+ static std::unique_ptr<llvm::MCRegisterInfo>
+ MakeMCRegisterInfo(const ArchSpec &arch);
+
lldb::ProcessWP m_process_wp;
+ std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up;
private:
DISALLOW_COPY_AND_ASSIGN(ABI);
diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h
index 2bf3f32b5eef..ac72b98e5e1a 100644
--- a/include/lldb/Target/DynamicLoader.h
+++ b/include/lldb/Target/DynamicLoader.h
@@ -148,13 +148,9 @@ public:
/// The equivalent symbol list - any equivalent symbols found are appended
/// to this list.
///
- /// \return
- /// Number of equivalent symbols found.
- virtual size_t FindEquivalentSymbols(Symbol *original_symbol,
- ModuleList &module_list,
- SymbolContextList &equivalent_symbols) {
- return 0;
- }
+ virtual void FindEquivalentSymbols(Symbol *original_symbol,
+ ModuleList &module_list,
+ SymbolContextList &equivalent_symbols) {}
/// Ask if it is ok to try and load or unload an shared library (image).
///
diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h
index 6ea6029bdace..b49e96eeac17 100644
--- a/include/lldb/Target/Language.h
+++ b/include/lldb/Target/Language.h
@@ -20,6 +20,7 @@
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/StringPrinter.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-public.h"
@@ -266,12 +267,9 @@ public:
static std::set<lldb::LanguageType> GetSupportedLanguages();
- static void GetLanguagesSupportingTypeSystems(
- std::set<lldb::LanguageType> &languages,
- std::set<lldb::LanguageType> &languages_for_expressions);
-
- static void
- GetLanguagesSupportingREPLs(std::set<lldb::LanguageType> &languages);
+ static LanguageSet GetLanguagesSupportingTypeSystems();
+ static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
+ static LanguageSet GetLanguagesSupportingREPLs();
protected:
// Classes that inherit from Language can see and modify these
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index 3ba58c0ec741..6f643df53d1e 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -18,6 +18,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Host/File.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
@@ -257,19 +258,6 @@ public:
virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir);
- /// Retrieve the system include directories on this platform for the
- /// given language.
- ///
- /// \param[in] lang
- /// The language for which the include directories should be queried.
- ///
- /// \param[out] directories
- /// The include directories for this system.
- virtual std::vector<std::string>
- GetSystemIncludeDirectories(lldb::LanguageType lang) {
- return {};
- }
-
virtual UserIDResolver &GetUserIDResolver() = 0;
/// Locate a file for a platform.
@@ -518,8 +506,9 @@ public:
virtual Status SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions);
- virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
- uint32_t mode, Status &error) {
+ virtual lldb::user_id_t OpenFile(const FileSpec &file_spec,
+ File::OpenOptions flags, uint32_t mode,
+ Status &error) {
return UINT64_MAX;
}
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index f85069ea0906..a4ef1cc40414 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -50,6 +50,7 @@
#include "lldb/lldb-private.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Support/VersionTuple.h"
namespace lldb_private {
@@ -680,10 +681,19 @@ public:
/// shared library load state.
///
/// \return
- /// The number of shared libraries that were loaded
- virtual size_t LoadModules() { return 0; }
+ /// A status object indicating if the operation was sucessful or not.
+ virtual llvm::Error LoadModules() {
+ return llvm::make_error<llvm::StringError>("Not implemented.",
+ llvm::inconvertibleErrorCode());
+ }
- virtual size_t LoadModules(LoadedModuleInfoList &) { return 0; }
+ /// Query remote GDBServer for a detailed loaded library list
+ /// \return
+ /// The list of modules currently loaded by the process, or an error.
+ virtual llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Not implemented");
+ }
protected:
virtual JITLoaderList &GetJITLoaders();
@@ -1186,6 +1196,9 @@ public:
/// VersionTuple is returner.
virtual llvm::VersionTuple GetHostOSVersion() { return llvm::VersionTuple(); }
+ /// \return the macCatalyst version of the host OS.
+ virtual llvm::VersionTuple GetHostMacCatalystVersion() { return {}; }
+
/// Get the target object pointer for this module.
///
/// \return
@@ -2259,6 +2272,8 @@ public:
void ClearPreResumeAction(PreResumeActionCallback callback, void *baton);
ProcessRunLock &GetRunLock();
+
+ bool CurrentThreadIsPrivateStateThread();
virtual Status SendEventData(const char *data) {
Status return_error("Sending an event is not supported for this process.");
@@ -2453,6 +2468,11 @@ public:
return Status("Not implemented");
}
+ // This calls a function of the form "void * (*)(void)".
+ bool CallVoidArgVoidPtrReturn(const Address *address,
+ lldb::addr_t &returned_func,
+ bool trap_exceptions = false);
+
protected:
void SetState(lldb::EventSP &event_sp);
@@ -2732,7 +2752,7 @@ protected:
enum { eCanJITDontKnow = 0, eCanJITYes, eCanJITNo } m_can_jit;
std::unique_ptr<UtilityFunction> m_dlopen_utility_func_up;
- std::once_flag m_dlopen_utility_func_flag_once;
+ llvm::once_flag m_dlopen_utility_func_flag_once;
size_t RemoveBreakpointOpcodesFromBuffer(lldb::addr_t addr, size_t size,
uint8_t *buf) const;
diff --git a/include/lldb/Target/RemoteAwarePlatform.h b/include/lldb/Target/RemoteAwarePlatform.h
index 524332f948a5..55d5ff673f1d 100644
--- a/include/lldb/Target/RemoteAwarePlatform.h
+++ b/include/lldb/Target/RemoteAwarePlatform.h
@@ -22,7 +22,7 @@ public:
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
ModuleSpec &module_spec) override;
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
uint32_t mode, Status &error) override;
bool CloseFile(lldb::user_id_t fd, Status &error) override;
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h
index 4e6e79befc6a..d2e5795162cf 100644
--- a/include/lldb/Target/StackFrame.h
+++ b/include/lldb/Target/StackFrame.h
@@ -108,17 +108,19 @@ public:
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa,
bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind,
- const SymbolContext *sc_ptr);
+ bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr);
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
lldb::user_id_t concrete_frame_idx,
const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa,
- lldb::addr_t pc, const SymbolContext *sc_ptr);
+ lldb::addr_t pc, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr);
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx,
lldb::user_id_t concrete_frame_idx,
const lldb::RegisterContextSP &reg_context_sp, lldb::addr_t cfa,
- const Address &pc, const SymbolContext *sc_ptr);
+ const Address &pc, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr);
~StackFrame() override;
@@ -367,6 +369,12 @@ public:
/// may have limited support for inspecting variables.
bool IsArtificial() const;
+ /// Query whether this frame behaves like the zeroth frame, in the sense
+ /// that its pc value might not immediately follow a call (and thus might
+ /// be the first address of its function). True for actual frame zero as
+ /// well as any other frame with the same trait.
+ bool BehavesLikeZerothFrame() const;
+
/// Query this frame to find what frame it is in this Thread's
/// StackFrameList.
///
@@ -511,6 +519,7 @@ private:
bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA ==
// LLDB_INVALID_ADDRESS
Kind m_stack_frame_kind;
+ bool m_behaves_like_zeroth_frame;
lldb::VariableListSP m_variable_list_sp;
ValueObjectList m_variable_list_value_objects; // Value objects for each
// variable in
diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h
index 59033b1b6441..61e1fbd4bd46 100644
--- a/include/lldb/Target/StopInfo.h
+++ b/include/lldb/Target/StopInfo.h
@@ -33,10 +33,13 @@ public:
lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
- // The value of the StopInfo depends on the StopReason. StopReason
- // Meaning ----------------------------------------------
- // eStopReasonBreakpoint BreakpointSiteID eStopReasonSignal
- // Signal number eStopReasonWatchpoint WatchpointLocationID
+ // The value of the StopInfo depends on the StopReason.
+ //
+ // StopReason Meaning
+ // ------------------------------------------------
+ // eStopReasonBreakpoint BreakpointSiteID
+ // eStopReasonSignal Signal number
+ // eStopReasonWatchpoint WatchpointLocationID
// eStopReasonPlanComplete No significance
uint64_t GetValue() const { return m_value; }
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
index 4ed11afc31ba..e465046959f2 100644
--- a/include/lldb/Target/Target.h
+++ b/include/lldb/Target/Target.h
@@ -121,7 +121,7 @@ public:
FileSpecList GetExecutableSearchPaths();
- void AppendExecutableSearchPaths(const FileSpec&);
+ void AppendExecutableSearchPaths(const FileSpec &);
FileSpecList GetDebugFileSearchPaths();
@@ -139,6 +139,8 @@ public:
bool GetEnableSyntheticValue() const;
+ uint32_t GetMaxZeroPaddingInFloatFormat() const;
+
uint32_t GetMaximumNumberOfChildrenToDisplay() const;
uint32_t GetMaximumSizeOfStringSummary() const;
@@ -495,7 +497,7 @@ public:
static void SetDefaultArchitecture(const ArchSpec &arch);
- /// Find a binary on the system and return its Module,
+ /// Find a binary on the system and return its Module,
/// or return an existing Module that is already in the Target.
///
/// Given a ModuleSpec, find a binary satisifying that specification,
@@ -507,34 +509,33 @@ public:
/// e.g. UUID, architecture, file path.
///
/// \param[in] notify
- /// If notify is true, and the Module is new to this Target,
- /// Target::ModulesDidLoad will be called.
- /// If notify is false, it is assumed that the caller is adding
- /// multiple Modules and will call ModulesDidLoad with the
+ /// If notify is true, and the Module is new to this Target,
+ /// Target::ModulesDidLoad will be called.
+ /// If notify is false, it is assumed that the caller is adding
+ /// multiple Modules and will call ModulesDidLoad with the
/// full list at the end.
/// ModulesDidLoad must be called when a Module/Modules have
/// been added to the target, one way or the other.
///
/// \param[out] error_ptr
- /// Optional argument, pointing to a Status object to fill in
+ /// Optional argument, pointing to a Status object to fill in
/// with any results / messages while attempting to find/load
/// this binary. Many callers will be internal functions that
/// will handle / summarize the failures in a custom way and
/// don't use these messages.
///
- /// \return
+ /// \return
/// An empty ModuleSP will be returned if no matching file
/// was found. If error_ptr was non-nullptr, an error message
/// will likely be provided.
- lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec,
- bool notify,
+ lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
Status *error_ptr = nullptr);
// Settings accessors
static const lldb::TargetPropertiesSP &GetGlobalProperties();
- std::recursive_mutex &GetAPIMutex() { return m_mutex; }
+ std::recursive_mutex &GetAPIMutex();
void DeleteCurrentProcess();
@@ -599,7 +600,7 @@ public:
const FileSpecList *containingModules,
const FileSpecList *source_file_list,
const std::unordered_set<std::string> &function_names,
- RegularExpression &source_regex, bool internal, bool request_hardware,
+ RegularExpression source_regex, bool internal, bool request_hardware,
LazyBool move_to_nearest_code);
// Use this to create a breakpoint from a load address
@@ -622,7 +623,7 @@ public:
// target setting, else we use the values passed in
lldb::BreakpointSP CreateFuncRegexBreakpoint(
const FileSpecList *containingModules,
- const FileSpecList *containingSourceFiles, RegularExpression &func_regexp,
+ const FileSpecList *containingSourceFiles, RegularExpression func_regexp,
lldb::LanguageType requested_language, LazyBool skip_prologue,
bool internal, bool request_hardware);
@@ -644,14 +645,11 @@ public:
Args *additional_args = nullptr,
Status *additional_args_error = nullptr);
- lldb::BreakpointSP
- CreateScriptedBreakpoint(const llvm::StringRef class_name,
- const FileSpecList *containingModules,
- const FileSpecList *containingSourceFiles,
- bool internal,
- bool request_hardware,
- StructuredData::ObjectSP extra_args_sp,
- Status *creation_error = nullptr);
+ lldb::BreakpointSP CreateScriptedBreakpoint(
+ const llvm::StringRef class_name, const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles, bool internal,
+ bool request_hardware, StructuredData::ObjectSP extra_args_sp,
+ Status *creation_error = nullptr);
// This is the same as the func_name breakpoint except that you can specify a
// vector of names. This is cheaper than a regular expression breakpoint in
@@ -690,43 +688,42 @@ public:
}
WatchpointList &GetWatchpointList() { return m_watchpoint_list; }
-
+
// Manages breakpoint names:
void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error);
-
- void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name,
+
+ void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name,
Status &error);
-
- void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
- ConstString name);
-
- BreakpointName *FindBreakpointName(ConstString name, bool can_create,
+
+ void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, ConstString name);
+
+ BreakpointName *FindBreakpointName(ConstString name, bool can_create,
Status &error);
-
+
void DeleteBreakpointName(ConstString name);
-
+
void ConfigureBreakpointName(BreakpointName &bp_name,
const BreakpointOptions &options,
const BreakpointName::Permissions &permissions);
- void ApplyNameToBreakpoints(BreakpointName &bp_name);
-
+ void ApplyNameToBreakpoints(BreakpointName &bp_name);
+
// This takes ownership of the name obj passed in.
void AddBreakpointName(BreakpointName *bp_name);
-
+
void GetBreakpointNames(std::vector<std::string> &names);
-
- //This call removes ALL breakpoints regardless of permission.
+
+ // This call removes ALL breakpoints regardless of permission.
void RemoveAllBreakpoints(bool internal_also = false);
-
+
// This removes all the breakpoints, but obeys the ePermDelete on them.
void RemoveAllowedBreakpoints();
void DisableAllBreakpoints(bool internal_also = false);
-
+
void DisableAllowedBreakpoints();
void EnableAllBreakpoints(bool internal_also = false);
-
+
void EnableAllowedBreakpoints();
bool DisableBreakpointByID(lldb::break_id_t break_id);
@@ -1027,9 +1024,11 @@ public:
PathMappingList &GetImageSearchPathList();
- TypeSystem *GetScratchTypeSystemForLanguage(Status *error,
- lldb::LanguageType language,
- bool create_on_demand = true);
+ llvm::Expected<TypeSystem &>
+ GetScratchTypeSystemForLanguage(lldb::LanguageType language,
+ bool create_on_demand = true);
+
+ std::vector<TypeSystem *> GetScratchTypeSystems(bool create_on_demand = true);
PersistentExpressionState *
GetPersistentExpressionStateForLanguage(lldb::LanguageType language);
@@ -1038,11 +1037,12 @@ public:
// parameters have the same meaning as for the UserExpression constructor.
// Returns a new-ed object which the caller owns.
- UserExpression *GetUserExpressionForLanguage(
- llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
- Expression::ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ValueObject *ctx_obj, Status &error);
+ UserExpression *
+ GetUserExpressionForLanguage(llvm::StringRef expr, llvm::StringRef prefix,
+ lldb::LanguageType language,
+ Expression::ResultType desired_type,
+ const EvaluateExpressionOptions &options,
+ ValueObject *ctx_obj, Status &error);
// Creates a FunctionCaller for the given language, the rest of the
// parameters have the same meaning as for the FunctionCaller constructor.
@@ -1104,8 +1104,7 @@ public:
llvm::StringRef expression, ExecutionContextScope *exe_scope,
lldb::ValueObjectSP &result_valobj_sp,
const EvaluateExpressionOptions &options = EvaluateExpressionOptions(),
- std::string *fixed_expression = nullptr,
- ValueObject *ctx_obj = nullptr);
+ std::string *fixed_expression = nullptr, ValueObject *ctx_obj = nullptr);
lldb::ExpressionVariableSP GetPersistentVariable(ConstString name);
@@ -1116,6 +1115,24 @@ public:
lldb::addr_t GetPersistentSymbol(ConstString name);
+ /// This method will return the address of the starting function for
+ /// this binary, e.g. main() or its equivalent. This can be used as
+ /// an address of a function that is not called once a binary has
+ /// started running - e.g. as a return address for inferior function
+ /// calls that are unambiguous completion of the function call, not
+ /// called during the course of the inferior function code running.
+ ///
+ /// If no entry point can be found, an invalid address is returned.
+ ///
+ /// \param [out] err
+ /// This object will be set to failure if no entry address could
+ /// be found, and may contain a helpful error message.
+ //
+ /// \return
+ /// Returns the entry address for this program, or an error
+ /// if none can be found.
+ llvm::Expected<lldb_private::Address> GetEntryPointAddress();
+
// Target Stop Hooks
class StopHook : public UserID {
public:
@@ -1147,7 +1164,9 @@ public:
void SetIsActive(bool is_active) { m_active = is_active; }
- void SetAutoContinue(bool auto_continue) {m_auto_continue = auto_continue;}
+ void SetAutoContinue(bool auto_continue) {
+ m_auto_continue = auto_continue;
+ }
bool GetAutoContinue() const { return m_auto_continue; }
@@ -1242,7 +1261,7 @@ protected:
const lldb::ModuleSP &module_sp) override;
void NotifyModuleRemoved(const ModuleList &module_list,
- const lldb::ModuleSP &module_sp) override;
+ const lldb::ModuleSP &module_sp) override;
void NotifyModuleUpdated(const ModuleList &module_list,
const lldb::ModuleSP &old_module_sp,
@@ -1269,6 +1288,12 @@ protected:
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB*
/// classes make the SB interface thread safe
+ /// When the private state thread calls SB API's - usually because it is
+ /// running OS plugin or Python ThreadPlan code - it should not block on the
+ /// API mutex that is held by the code that kicked off the sequence of events
+ /// that led us to run the code. We hand out this mutex instead when we
+ /// detect that code is running on the private state thread.
+ std::recursive_mutex m_private_mutex;
Arch m_arch;
ModuleList m_images; ///< The list of images for this process (shared
/// libraries and anything dynamically loaded).
@@ -1277,7 +1302,7 @@ protected:
BreakpointList m_internal_breakpoint_list;
using BreakpointNameList = std::map<ConstString, BreakpointName *>;
BreakpointNameList m_breakpoint_names;
-
+
lldb::BreakpointSP m_last_created_breakpoint;
WatchpointList m_watchpoint_list;
lldb::WatchpointSP m_last_created_watchpoint;
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index 7aeaece5b5d5..7c5ff6093baf 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -899,6 +899,7 @@ public:
virtual lldb::ThreadPlanSP
QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name,
+ StructuredData::ObjectSP extra_args_sp,
bool stop_other_threads, Status &status);
// Thread Plan accessors:
@@ -1101,6 +1102,17 @@ public:
// right even if you have not calculated this yourself, or if it disagrees
// with what you might have calculated.
virtual lldb::StopInfoSP GetPrivateStopInfo();
+
+ // Calculate the stop info that will be shown to lldb clients. For instance,
+ // a "step out" is implemented by running to a breakpoint on the function
+ // return PC, so the process plugin initially sets the stop info to a
+ // StopInfoBreakpoint. But once we've run the ShouldStop machinery, we
+ // discover that there's a completed ThreadPlanStepOut, and that's really
+ // the StopInfo we want to show. That will happen naturally the next
+ // time GetStopInfo is called, but if you want to force the replacement,
+ // you can call this.
+
+ void CalculatePublicStopInfo();
// Ask the thread subclass to set its stop info.
//
diff --git a/include/lldb/Target/ThreadPlanPython.h b/include/lldb/Target/ThreadPlanPython.h
index 3825bf6ee4f3..0ee559b12960 100644
--- a/include/lldb/Target/ThreadPlanPython.h
+++ b/include/lldb/Target/ThreadPlanPython.h
@@ -12,6 +12,8 @@
#include <string>
+#include "lldb/lldb-forward.h"
+
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
@@ -29,7 +31,8 @@ namespace lldb_private {
class ThreadPlanPython : public ThreadPlan {
public:
- ThreadPlanPython(Thread &thread, const char *class_name);
+ ThreadPlanPython(Thread &thread, const char *class_name,
+ StructuredDataImpl *args_data);
~ThreadPlanPython() override;
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -55,6 +58,11 @@ protected:
private:
std::string m_class_name;
+ StructuredDataImpl *m_args_data; // We own this, but the implementation
+ // has to manage the UP (since that is
+ // how it gets stored in the
+ // SBStructuredData).
+ std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h
index a648e063e34b..652918ddad43 100644
--- a/include/lldb/Target/Unwind.h
+++ b/include/lldb/Target/Unwind.h
@@ -37,9 +37,10 @@ public:
lldb::addr_t cfa;
lldb::addr_t pc;
uint32_t idx;
+ bool behaves_like_zeroth_frame = (end_idx == 0);
for (idx = 0; idx < end_idx; idx++) {
- if (!DoGetFrameInfoAtIndex(idx, cfa, pc)) {
+ if (!DoGetFrameInfoAtIndex(idx, cfa, pc, behaves_like_zeroth_frame)) {
break;
}
}
@@ -47,9 +48,9 @@ public:
}
bool GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) {
+ lldb::addr_t &pc, bool &behaves_like_zeroth_frame) {
std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
- return DoGetFrameInfoAtIndex(frame_idx, cfa, pc);
+ return DoGetFrameInfoAtIndex(frame_idx, cfa, pc, behaves_like_zeroth_frame);
}
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) {
@@ -66,7 +67,8 @@ protected:
virtual uint32_t DoGetFrameCount() = 0;
virtual bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) = 0;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) = 0;
virtual lldb::RegisterContextSP
DoCreateRegisterContextForFrame(StackFrame *frame) = 0;
diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h
index 1473c60eeaf2..21375e3821ca 100644
--- a/include/lldb/Utility/AnsiTerminal.h
+++ b/include/lldb/Utility/AnsiTerminal.h
@@ -55,7 +55,7 @@
#include <string>
-namespace lldb_utility {
+namespace lldb_private {
namespace ansi {
@@ -137,4 +137,4 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
return fmt;
}
}
-}
+} // namespace lldb_private
diff --git a/include/lldb/Utility/ArchSpec.h b/include/lldb/Utility/ArchSpec.h
index 7a32556310c4..3bfc988abf0b 100644
--- a/include/lldb/Utility/ArchSpec.h
+++ b/include/lldb/Utility/ArchSpec.h
@@ -122,6 +122,7 @@ public:
eCore_thumbv7em,
eCore_arm_arm64,
eCore_arm_armv8,
+ eCore_arm_arm64_32,
eCore_arm_aarch64,
eCore_mips32,
@@ -183,6 +184,8 @@ public:
eCore_uknownMach32,
eCore_uknownMach64,
+ eCore_arc, // little endian ARC
+
kNumCores,
kCore_invalid,
@@ -268,7 +271,7 @@ public:
static bool ContainsOnlyArch(const llvm::Triple &normalized_triple);
static void ListSupportedArchNames(StringList &list);
- static size_t AutoComplete(CompletionRequest &request);
+ static void AutoComplete(CompletionRequest &request);
/// Returns a static string representing the current architecture.
///
diff --git a/include/lldb/Utility/Args.h b/include/lldb/Utility/Args.h
index 6f258498d5ba..7987787e7af5 100644
--- a/include/lldb/Utility/Args.h
+++ b/include/lldb/Utility/Args.h
@@ -35,6 +35,7 @@ public:
private:
friend class Args;
std::unique_ptr<char[]> ptr;
+ char quote;
char *data() { return ptr.get(); }
@@ -42,12 +43,12 @@ public:
ArgEntry() = default;
ArgEntry(llvm::StringRef str, char quote);
- llvm::StringRef ref;
- char quote;
+ llvm::StringRef ref() const { return c_str(); }
const char *c_str() const { return ptr.get(); }
/// Returns true if this argument was quoted in any way.
bool IsQuoted() const { return quote != '\0'; }
+ char GetQuoteChar() const { return quote; }
};
/// Construct with an option command string.
@@ -121,7 +122,6 @@ public:
const char *GetArgumentAtIndex(size_t idx) const;
llvm::ArrayRef<ArgEntry> entries() const { return m_entries; }
- char GetArgumentQuoteCharAtIndex(size_t idx) const;
using const_iterator = std::vector<ArgEntry>::const_iterator;
@@ -168,8 +168,8 @@ public:
/// Appends a new argument to the end of the list argument list.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
@@ -179,30 +179,27 @@ public:
void AppendArguments(const char **argv);
- /// Insert the argument value at index \a idx to \a arg_cstr.
+ /// Insert the argument value at index \a idx to \a arg_str.
///
/// \param[in] idx
/// The index of where to insert the argument.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
- ///
- /// \return
- /// The NULL terminated C string of the copy of \a arg_cstr.
void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
char quote_char = '\0');
- /// Replaces the argument value at index \a idx to \a arg_cstr if \a idx is
+ /// Replaces the argument value at index \a idx to \a arg_str if \a idx is
/// a valid argument index.
///
/// \param[in] idx
/// The index of the argument that will have its value replaced.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
@@ -238,12 +235,12 @@ public:
/// \see Args::GetArgumentAtIndex (size_t) const
void Shift();
- /// Inserts a class owned copy of \a arg_cstr at the beginning of the
+ /// Inserts a class owned copy of \a arg_str at the beginning of the
/// argument vector.
///
- /// A copy \a arg_cstr will be made.
+ /// A copy \a arg_str will be made.
///
- /// \param[in] arg_cstr
+ /// \param[in] arg_str
/// The argument to push on the front of the argument stack.
///
/// \param[in] quote_char
@@ -255,10 +252,6 @@ public:
// For re-setting or blanking out the list of arguments.
void Clear();
- static const char *StripSpaces(std::string &s, bool leading = true,
- bool trailing = true,
- bool return_null_if_empty = true);
-
static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
size_t total_byte_size) {
if (total_byte_size > 8)
diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h
deleted file mode 100644
index 6cd5f332ef95..000000000000
--- a/include/lldb/Utility/CleanUp.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- CleanUp.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_CleanUp_h_
-#define liblldb_CleanUp_h_
-
-#include "lldb/lldb-public.h"
-#include <functional>
-
-namespace lldb_private {
-
-/// Run a cleanup function on scope exit unless it's explicitly disabled.
-class CleanUp {
- std::function<void()> Clean;
-
-public:
- /// Register a cleanup function which applies \p Func to a list of arguments.
- /// Use caution with arguments which are references: they will be copied.
- template <typename F, typename... Args>
- CleanUp(F &&Func, Args &&... args)
- : Clean(std::bind(std::forward<F>(Func), std::forward<Args>(args)...)) {}
-
- ~CleanUp() {
- if (Clean)
- Clean();
- }
-
- /// Disable the cleanup.
- void disable() { Clean = nullptr; }
-
- // Prevent cleanups from being run more than once.
- DISALLOW_COPY_AND_ASSIGN(CleanUp);
-};
-
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_CleanUp_h_
diff --git a/include/lldb/Utility/CompletionRequest.h b/include/lldb/Utility/CompletionRequest.h
index f5ccb01ca16f..570f626ac54e 100644
--- a/include/lldb/Utility/CompletionRequest.h
+++ b/include/lldb/Utility/CompletionRequest.h
@@ -16,25 +16,53 @@
#include "llvm/ADT/StringSet.h"
namespace lldb_private {
+enum class CompletionMode {
+ // The current token has been completed.
+ Normal,
+ // The current token has been partially completed. This means that we found
+ // a completion, but that the completed token is still incomplete. Examples
+ // for this are file paths, where we want to complete "/bi" to "/bin/", but
+ // the file path token is still incomplete after the completion. Clients
+ // should not indicate to the user that this is a full completion (e.g. by
+ // not inserting the usual trailing space after a successful completion).
+ Partial,
+ // The full line has been rewritten by the completion.
+ RewriteLine,
+};
+
class CompletionResult {
+public:
/// A single completion and all associated data.
- struct Completion {
- Completion(llvm::StringRef completion, llvm::StringRef description)
- : m_completion(completion.str()), m_descripton(description.str()) {}
+ class Completion {
std::string m_completion;
std::string m_descripton;
+ CompletionMode m_mode;
+
+ public:
+ Completion(llvm::StringRef completion, llvm::StringRef description,
+ CompletionMode mode)
+ : m_completion(completion.str()), m_descripton(description.str()),
+ m_mode(mode) {}
+ const std::string &GetCompletion() const { return m_completion; }
+ const std::string &GetDescription() const { return m_descripton; }
+ CompletionMode GetMode() const { return m_mode; }
/// Generates a string that uniquely identifies this completion result.
std::string GetUniqueKey() const;
};
+
+private:
std::vector<Completion> m_results;
/// List of added completions so far. Used to filter out duplicates.
llvm::StringSet<> m_added_values;
public:
- void AddResult(llvm::StringRef completion, llvm::StringRef description);
+ void AddResult(llvm::StringRef completion, llvm::StringRef description,
+ CompletionMode mode);
+
+ llvm::ArrayRef<Completion> GetResults() const { return m_results; }
/// Adds all collected completion matches to the given list.
/// The list will be cleared before the results are added. The number of
@@ -68,18 +96,10 @@ public:
/// the cursor is at the start of the line. The completion starts from
/// this cursor position.
///
- /// \param [in] match_start_point
- /// \param [in] max_return_elements
- /// If there is a match that is expensive to compute, these are here to
- /// allow you to compute the completions in batches. Start the
- /// completion from match_start_point, and return match_return_elements
- /// elements.
- ///
/// \param [out] result
/// The CompletionResult that will be filled with the results after this
/// request has been handled.
CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
- int match_start_point, int max_return_elements,
CompletionResult &result);
llvm::StringRef GetRawLine() const { return m_command; }
@@ -90,21 +110,25 @@ public:
Args &GetParsedLine() { return m_parsed_line; }
- const Args &GetPartialParsedLine() const { return m_partial_parsed_line; }
-
- void SetCursorIndex(int i) { m_cursor_index = i; }
- int GetCursorIndex() const { return m_cursor_index; }
-
- void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; }
- int GetCursorCharPosition() const { return m_cursor_char_position; }
-
- int GetMatchStartPoint() const { return m_match_start_point; }
+ const Args::ArgEntry &GetParsedArg() {
+ return GetParsedLine()[GetCursorIndex()];
+ }
- int GetMaxReturnElements() const { return m_max_return_elements; }
+ /// Drops the first argument from the argument list.
+ void ShiftArguments() {
+ m_cursor_index--;
+ m_parsed_line.Shift();
+ }
- bool GetWordComplete() { return m_word_complete; }
+ /// Adds an empty argument at the end of the argument list and moves
+ /// the cursor to this new argument.
+ void AppendEmptyArgument() {
+ m_parsed_line.AppendArgument(llvm::StringRef());
+ m_cursor_index++;
+ m_cursor_char_position = 0;
+ }
- void SetWordComplete(bool v) { m_word_complete = v; }
+ size_t GetCursorIndex() const { return m_cursor_index; }
/// Adds a possible completion string. If the completion was already
/// suggested before, it will not be added to the list of results. A copy of
@@ -112,11 +136,31 @@ public:
/// afterwards.
///
/// \param match The suggested completion.
- /// \param match An optional description of the completion string. The
+ /// \param completion An optional description of the completion string. The
/// description will be displayed to the user alongside the completion.
+ /// \param mode The CompletionMode for this completion.
void AddCompletion(llvm::StringRef completion,
- llvm::StringRef description = "") {
- m_result.AddResult(completion, description);
+ llvm::StringRef description = "",
+ CompletionMode mode = CompletionMode::Normal) {
+ m_result.AddResult(completion, description, mode);
+ }
+
+ /// Adds a possible completion string if the completion would complete the
+ /// current argument.
+ ///
+ /// \param match The suggested completion.
+ /// \param description An optional description of the completion string. The
+ /// description will be displayed to the user alongside the completion.
+ template <CompletionMode M = CompletionMode::Normal>
+ void TryCompleteCurrentArg(llvm::StringRef completion,
+ llvm::StringRef description = "") {
+ // Trying to rewrite the whole line while checking for the current
+ // argument never makes sense. Completion modes are always hardcoded, so
+ // this can be a static_assert.
+ static_assert(M != CompletionMode::RewriteLine,
+ "Shouldn't rewrite line with this function");
+ if (completion.startswith(GetCursorArgumentPrefix()))
+ AddCompletion(completion, description, M);
}
/// Adds multiple possible completion strings.
@@ -125,8 +169,8 @@ public:
///
/// \see AddCompletion
void AddCompletions(const StringList &completions) {
- for (std::size_t i = 0; i < completions.GetSize(); ++i)
- AddCompletion(completions.GetStringAtIndex(i));
+ for (const std::string &completion : completions)
+ AddCompletion(completion);
}
/// Adds multiple possible completion strings alongside their descriptions.
@@ -145,16 +189,8 @@ public:
descriptions.GetStringAtIndex(i));
}
- std::size_t GetNumberOfMatches() const {
- return m_result.GetNumberOfResults();
- }
-
- llvm::StringRef GetCursorArgument() const {
- return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
- }
-
llvm::StringRef GetCursorArgumentPrefix() const {
- return GetCursorArgument().substr(0, GetCursorCharPosition());
+ return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
}
private:
@@ -164,22 +200,10 @@ private:
unsigned m_raw_cursor_pos;
/// The command line parsed as arguments.
Args m_parsed_line;
- /// The command line until the cursor position parsed as arguments.
- Args m_partial_parsed_line;
/// The index of the argument in which the completion cursor is.
- int m_cursor_index;
+ size_t m_cursor_index;
/// The cursor position in the argument indexed by m_cursor_index.
- int m_cursor_char_position;
- /// If there is a match that is expensive
- /// to compute, these are here to allow you to compute the completions in
- /// batches. Start the completion from \amatch_start_point, and return
- /// \amatch_return_elements elements.
- // FIXME: These two values are not implemented.
- int m_match_start_point;
- int m_max_return_elements;
- /// \btrue if this is a complete option value (a space will be inserted
- /// after the completion.) \bfalse otherwise.
- bool m_word_complete = false;
+ size_t m_cursor_char_position;
/// The result this request is supposed to fill out.
/// We keep this object private to ensure that no backend can in any way
diff --git a/include/lldb/Utility/ConstString.h b/include/lldb/Utility/ConstString.h
index 8576c18ddcd8..9a9ee458239f 100644
--- a/include/lldb/Utility/ConstString.h
+++ b/include/lldb/Utility/ConstString.h
@@ -10,6 +10,7 @@
#define liblldb_ConstString_h_
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/FormatVariadic.h"
#include <stddef.h>
@@ -204,9 +205,7 @@ public:
/// \param[in] rhs
/// Another string object to compare this object to.
///
- /// \return
- /// \li \b true if this object is not equal to \a rhs.
- /// \li \b false if this object is equal to \a rhs.
+ /// \return \b true if this object is not equal to \a rhs, false otherwise.
bool operator!=(const char *rhs) const { return !(*this == rhs); }
bool operator<(ConstString rhs) const;
@@ -218,8 +217,7 @@ public:
///
/// If \a value_if_empty is nullptr, then nullptr will be returned.
///
- /// \return
- /// Returns \a value_if_empty if the string is empty, otherwise
+ /// \return Returns \a value_if_empty if the string is empty, otherwise
/// the C string value contained in this object.
const char *AsCString(const char *value_if_empty = nullptr) const {
return (IsEmpty() ? value_if_empty : m_string);
@@ -269,7 +267,7 @@ public:
/// in a pointer comparison since all strings are in a uniqued in a global
/// string pool.
///
- /// \param[in] rhs
+ /// \param[in] lhs
/// The Left Hand Side const ConstString object reference.
///
/// \param[in] rhs
@@ -279,9 +277,7 @@ public:
/// Case sensitivity. If true, case sensitive equality
/// will be tested, otherwise character case will be ignored
///
- /// \return
- /// \li \b true if this object is equal to \a rhs.
- /// \li \b false if this object is not equal to \a rhs.
+ /// \return \b true if this object is equal to \a rhs, \b false otherwise.
static bool Equals(ConstString lhs, ConstString rhs,
const bool case_sensitive = true);
@@ -305,10 +301,7 @@ public:
/// Case sensitivity of compare. If true, case sensitive compare
/// will be performed, otherwise character case will be ignored
///
- /// \return
- /// \li -1 if lhs < rhs
- /// \li 0 if lhs == rhs
- /// \li 1 if lhs > rhs
+ /// \return -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs
static int Compare(ConstString lhs, ConstString rhs,
const bool case_sensitive = true);
@@ -445,6 +438,14 @@ public:
static size_t StaticMemorySize();
protected:
+ template <typename T> friend struct ::llvm::DenseMapInfo;
+ /// Only used by DenseMapInfo.
+ static ConstString FromStringPoolPointer(const char *ptr) {
+ ConstString s;
+ s.m_string = ptr;
+ return s;
+ };
+
// Member variables
const char *m_string;
};
@@ -459,6 +460,27 @@ template <> struct format_provider<lldb_private::ConstString> {
static void format(const lldb_private::ConstString &CS, llvm::raw_ostream &OS,
llvm::StringRef Options);
};
+
+/// DenseMapInfo implementation.
+/// \{
+template <> struct DenseMapInfo<lldb_private::ConstString> {
+ static inline lldb_private::ConstString getEmptyKey() {
+ return lldb_private::ConstString::FromStringPoolPointer(
+ DenseMapInfo<const char *>::getEmptyKey());
+ }
+ static inline lldb_private::ConstString getTombstoneKey() {
+ return lldb_private::ConstString::FromStringPoolPointer(
+ DenseMapInfo<const char *>::getTombstoneKey());
+ }
+ static unsigned getHashValue(lldb_private::ConstString val) {
+ return DenseMapInfo<const char *>::getHashValue(val.m_string);
+ }
+ static bool isEqual(lldb_private::ConstString LHS,
+ lldb_private::ConstString RHS) {
+ return LHS == RHS;
+ }
+};
+/// \}
}
#endif // liblldb_ConstString_h_
diff --git a/include/lldb/Utility/DataEncoder.h b/include/lldb/Utility/DataEncoder.h
index 19b7cef9f0ca..7d44afd2ce69 100644
--- a/include/lldb/Utility/DataEncoder.h
+++ b/include/lldb/Utility/DataEncoder.h
@@ -204,12 +204,11 @@ public:
/// m_addr_size member variable and should be set correctly prior to
/// extracting any address values.
///
- /// \param[in,out] offset_ptr
- /// A pointer to an offset within the data that will be advanced
- /// by the appropriate number of bytes if the value is extracted
- /// correctly. If the offset is out of bounds or there are not
- /// enough bytes to extract this value, the offset will be left
- /// unmodified.
+ /// \param[in] offset
+ /// The offset where to encode the address.
+ ///
+ /// \param[in] addr
+ /// The address to encode.
///
/// \return
/// The next valid offset within data if the put operation
@@ -220,19 +219,18 @@ public:
///
/// Encodes a C string into the existing data including the terminating
///
- /// \param[in,out] offset_ptr
- /// A pointer to an offset within the data that will be advanced
- /// by the appropriate number of bytes if the value is extracted
- /// correctly. If the offset is out of bounds or there are not
- /// enough bytes to extract this value, the offset will be left
- /// unmodified.
+ /// \param[in] offset
+ /// The offset where to encode the string.
+ ///
+ /// \param[in] cstr
+ /// The string to encode.
///
/// \return
/// A pointer to the C string value in the data. If the offset
/// pointed to by \a offset_ptr is out of bounds, or if the
/// offset plus the length of the C string is out of bounds,
/// NULL will be returned.
- uint32_t PutCString(uint32_t offset_ptr, const char *cstr);
+ uint32_t PutCString(uint32_t offset, const char *cstr);
lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
diff --git a/include/lldb/Utility/DataExtractor.h b/include/lldb/Utility/DataExtractor.h
index 74174b34ce99..333baf9fd349 100644
--- a/include/lldb/Utility/DataExtractor.h
+++ b/include/lldb/Utility/DataExtractor.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
#include <cassert>
#include <stdint.h>
@@ -167,9 +168,8 @@ public:
/// the beginning of each line and can be offset by base address \a
/// base_addr. \a num_per_line objects will be displayed on each line.
///
- /// \param[in] s
- /// The stream to dump the output to. If nullptr the output will
- /// be dumped to Log().
+ /// \param[in] log
+ /// The log to dump the output to.
///
/// \param[in] offset
/// The offset into the data at which to start dumping.
@@ -362,30 +362,29 @@ public:
/// when say copying a partial data value into a register.
///
/// \param[in] src_offset
- /// The offset into this data from which to start copying an
- /// endian entity
+ /// The offset into this data from which to start copying an endian
+ /// entity
///
/// \param[in] src_len
- /// The length of the endian data to copy from this object
- /// into the \a dst object
+ /// The length of the endian data to copy from this object into the \a
+ /// dst object
///
/// \param[out] dst
- /// The buffer where to place the endian data. The data might
- /// need to be byte swapped (and appropriately padded with
- /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order
- /// does not match the byte order in this object.
+ /// The buffer where to place the endian data. The data might need to be
+ /// byte swapped (and appropriately padded with zeroes if \a src_len !=
+ /// \a dst_len) if \a dst_byte_order does not match the byte order in
+ /// this object.
///
/// \param[in] dst_len
- /// The length number of bytes that the endian value will
- /// occupy is \a dst.
+ /// The length number of bytes that the endian value will occupy is \a
+ /// dst.
///
- /// \param[in] byte_order
- /// The byte order that the endian value should be in the \a dst
- /// buffer.
+ /// \param[in] dst_byte_order
+ /// The byte order that the endian value should be in the \a dst buffer.
///
/// \return
- /// Returns the number of bytes that were copied, or zero if
- /// anything goes wrong.
+ /// Returns the number of bytes that were copied, or zero if anything
+ /// goes wrong.
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset,
lldb::offset_t src_len, void *dst,
lldb::offset_t dst_len,
@@ -520,7 +519,7 @@ public:
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
- /// \param[in] byte_size
+ /// \param[in] size
/// The size in byte of the integer to extract.
///
/// \param[in] bitfield_bit_size
@@ -558,7 +557,7 @@ public:
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
- /// \param[in] byte_size
+ /// \param[in] size
/// The size in bytes of the integer to extract.
///
/// \param[in] bitfield_bit_size
@@ -956,14 +955,14 @@ public:
/// unmodified.
///
/// \return
- // The number of bytes consumed during the extraction.
+ /// The number of bytes consumed during the extraction.
uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const;
/// Test the validity of \a offset.
///
/// \return
- /// \b true if \a offset is a valid offset into the data in this
- /// object, \b false otherwise.
+ /// true if \a offset is a valid offset into the data in this object,
+ /// false otherwise.
bool ValidOffset(lldb::offset_t offset) const {
return offset < GetByteSize();
}
@@ -971,8 +970,8 @@ public:
/// Test the availability of \a length bytes of data from \a offset.
///
/// \return
- /// \b true if \a offset is a valid offset and there are \a
- /// length bytes available at that offset, \b false otherwise.
+ /// true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, false otherwise.
bool ValidOffsetForDataOfSize(lldb::offset_t offset,
lldb::offset_t length) const {
return length <= BytesLeft(offset);
@@ -997,6 +996,11 @@ public:
return {GetDataStart(), size_t(GetByteSize())};
}
+ llvm::DataExtractor GetAsLLVM() const {
+ return {GetData(), GetByteOrder() == lldb::eByteOrderLittle,
+ uint8_t(GetAddressByteSize())};
+ }
+
protected:
// Member variables
const uint8_t *m_start; ///< A pointer to the first byte of data.
diff --git a/include/lldb/Utility/FileCollector.h b/include/lldb/Utility/FileCollector.h
deleted file mode 100644
index a89206747fe1..000000000000
--- a/include/lldb/Utility/FileCollector.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- FileCollector.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_UTILITY_FILE_COLLECTOR_H
-#define LLDB_UTILITY_FILE_COLLECTOR_H
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/VirtualFileSystem.h"
-
-#include <mutex>
-
-namespace lldb_private {
-
-/// Collects files into a directory and generates a mapping that can be used by
-/// the VFS.
-class FileCollector {
-public:
- FileCollector(const FileSpec &root, const FileSpec &overlay);
-
- void AddFile(const llvm::Twine &file);
- void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); }
-
- /// Write the yaml mapping (for the VFS) to the given file.
- std::error_code WriteMapping(const FileSpec &mapping_file);
-
- /// Copy the files into the root directory.
- ///
- /// When stop_on_error is true (the default) we abort as soon as one file
- /// cannot be copied. This is relatively common, for example when a file was
- /// removed after it was added to the mapping.
- std::error_code CopyFiles(bool stop_on_error = true);
-
-protected:
- void AddFileImpl(llvm::StringRef src_path);
-
- bool MarkAsSeen(llvm::StringRef path) { return m_seen.insert(path).second; }
-
- bool GetRealPath(llvm::StringRef src_path,
- llvm::SmallVectorImpl<char> &result);
-
- void AddFileToMapping(llvm::StringRef virtual_path,
- llvm::StringRef real_path) {
- m_vfs_writer.addFileMapping(virtual_path, real_path);
- }
-
- /// Synchronizes adding files.
- std::mutex m_mutex;
-
- /// The root directory where files are copied.
- FileSpec m_root;
-
- /// The root directory where the VFS overlay lives.
- FileSpec m_overlay_root;
-
- /// Tracks already seen files so they can be skipped.
- llvm::StringSet<> m_seen;
-
- /// The yaml mapping writer.
- llvm::vfs::YAMLVFSWriter m_vfs_writer;
-
- /// Caches real_path calls when resolving symlinks.
- llvm::StringMap<std::string> m_symlink_map;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_UTILITY_FILE_COLLECTOR_H
diff --git a/include/lldb/Utility/FileSpec.h b/include/lldb/Utility/FileSpec.h
index f0bc5c89fec7..50ad1f1600d8 100644
--- a/include/lldb/Utility/FileSpec.h
+++ b/include/lldb/Utility/FileSpec.h
@@ -73,7 +73,7 @@ public:
/// \see FileSpec::SetFile (const char *path)
explicit FileSpec(llvm::StringRef path, Style style = Style::native);
- explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple);
+ explicit FileSpec(llvm::StringRef path, const llvm::Triple &triple);
/// Copy constructor
///
@@ -200,10 +200,8 @@ public:
/// only the filename will be compared, else a full comparison
/// is done.
///
- /// \return
- /// \li -1 if \a lhs is less than \a rhs
- /// \li 0 if \a lhs is equal to \a rhs
- /// \li 1 if \a lhs is greater than \a rhs
+ /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs,
+ /// 1 if \a lhs is greater than \a rhs
static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
@@ -322,10 +320,6 @@ public:
/// Extract the full path to the file.
///
/// Extract the directory and path into an llvm::SmallVectorImpl<>
- ///
- /// \return
- /// Returns a std::string with the directory and filename
- /// concatenated.
void GetPath(llvm::SmallVectorImpl<char> &path,
bool denormalize = true) const;
@@ -336,8 +330,7 @@ public:
/// filename has no extension, ConstString(nullptr) is returned. The dot
/// ('.') character is not returned as part of the extension
///
- /// \return
- /// Returns the extension of the file as a ConstString object.
+ /// \return Returns the extension of the file as a ConstString object.
ConstString GetFileNameExtension() const;
/// Return the filename without the extension part
@@ -346,9 +339,7 @@ public:
/// without the extension part (e.g. for a file named "foo.bar", "foo" is
/// returned)
///
- /// \return
- /// Returns the filename without extension
- /// as a ConstString object.
+ /// \return Returns the filename without extension as a ConstString object.
ConstString GetFileNameStrippingExtension() const;
/// Get the memory cost of this object.
@@ -372,12 +363,22 @@ public:
/// \param[in] path
/// A full, partial, or relative path to a file.
///
- /// \param[in] resolve_path
- /// If \b true, then we will try to resolve links the path using
- /// the static FileSpec::Resolve.
+ /// \param[in] style
+ /// The style for the given path.
void SetFile(llvm::StringRef path, Style style);
- void SetFile(llvm::StringRef path, const llvm::Triple &Triple);
+ /// Change the file specified with a new path.
+ ///
+ /// Update the contents of this object with a new path. The path will be
+ /// split up into a directory and filename and stored as uniqued string
+ /// values for quick comparison and efficient memory usage.
+ ///
+ /// \param[in] path
+ /// A full, partial, or relative path to a file.
+ ///
+ /// \param[in] triple
+ /// The triple which is used to set the Path style.
+ void SetFile(llvm::StringRef path, const llvm::Triple &triple);
bool IsResolved() const { return m_is_resolved; }
diff --git a/include/lldb/Utility/Flags.h b/include/lldb/Utility/Flags.h
index 48b14e7d2a2c..aa869eca0c6e 100644
--- a/include/lldb/Utility/Flags.h
+++ b/include/lldb/Utility/Flags.h
@@ -121,32 +121,6 @@ public:
/// \b true if \a bit is 0, \b false otherwise.
bool IsClear(ValueType bit) const { return (m_flags & bit) == 0; }
- /// Get the number of zero bits in \a m_flags.
- ///
- /// \return
- /// The number of bits that are set to 0 in the current flags.
- size_t ClearCount() const {
- size_t count = 0;
- for (ValueType shift = 0; shift < sizeof(ValueType) * 8; ++shift) {
- if ((m_flags & (1u << shift)) == 0)
- ++count;
- }
- return count;
- }
-
- /// Get the number of one bits in \a m_flags.
- ///
- /// \return
- /// The number of bits that are set to 1 in the current flags.
- size_t SetCount() const {
- size_t count = 0;
- for (ValueType mask = m_flags; mask; mask >>= 1) {
- if (mask & 1u)
- ++count;
- }
- return count;
- }
-
protected:
ValueType m_flags; ///< The flags.
};
diff --git a/include/lldb/Utility/GDBRemote.h b/include/lldb/Utility/GDBRemote.h
new file mode 100644
index 000000000000..b4adeb368524
--- /dev/null
+++ b/include/lldb/Utility/GDBRemote.h
@@ -0,0 +1,117 @@
+//===-- GDBRemote.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_GDBRemote_h_
+#define liblldb_GDBRemote_h_
+
+#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-public.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+
+class StreamGDBRemote : public StreamString {
+public:
+ StreamGDBRemote();
+
+ StreamGDBRemote(uint32_t flags, uint32_t addr_size,
+ lldb::ByteOrder byte_order);
+
+ ~StreamGDBRemote() override;
+
+ /// Output a block of data to the stream performing GDB-remote escaping.
+ ///
+ /// \param[in] s
+ /// A block of data.
+ ///
+ /// \param[in] src_len
+ /// The amount of data to write.
+ ///
+ /// \return
+ /// Number of bytes written.
+ // TODO: Convert this function to take ArrayRef<uint8_t>
+ int PutEscapedBytes(const void *s, size_t src_len);
+};
+
+/// GDB remote packet as used by the reproducer and the GDB remote
+/// communication history. Packets can be serialized to file.
+struct GDBRemotePacket {
+
+ friend llvm::yaml::MappingTraits<GDBRemotePacket>;
+
+ enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
+
+ GDBRemotePacket()
+ : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0),
+ tid(LLDB_INVALID_THREAD_ID) {}
+
+ void Clear() {
+ packet.data.clear();
+ type = ePacketTypeInvalid;
+ bytes_transmitted = 0;
+ packet_idx = 0;
+ tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ struct BinaryData {
+ std::string data;
+ };
+
+ void Serialize(llvm::raw_ostream &strm) const;
+ void Dump(Stream &strm) const;
+
+ BinaryData packet;
+ Type type;
+ uint32_t bytes_transmitted;
+ uint32_t packet_idx;
+ lldb::tid_t tid;
+
+private:
+ llvm::StringRef GetTypeStr() const;
+};
+
+} // namespace lldb_private
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector<lldb_private::GDBRemotePacket>)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct ScalarEnumerationTraits<lldb_private::GDBRemotePacket::Type> {
+ static void enumeration(IO &io, lldb_private::GDBRemotePacket::Type &value);
+};
+
+template <> struct ScalarTraits<lldb_private::GDBRemotePacket::BinaryData> {
+ static void output(const lldb_private::GDBRemotePacket::BinaryData &, void *,
+ raw_ostream &);
+
+ static StringRef input(StringRef, void *,
+ lldb_private::GDBRemotePacket::BinaryData &);
+
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+
+template <> struct MappingTraits<lldb_private::GDBRemotePacket> {
+ static void mapping(IO &io, lldb_private::GDBRemotePacket &Packet);
+
+ static StringRef validate(IO &io, lldb_private::GDBRemotePacket &);
+};
+
+} // namespace yaml
+} // namespace llvm
+
+#endif // liblldb_GDBRemote_h_
diff --git a/include/lldb/Utility/IOObject.h b/include/lldb/Utility/IOObject.h
index 1640200a01d9..16ed580abf71 100644
--- a/include/lldb/Utility/IOObject.h
+++ b/include/lldb/Utility/IOObject.h
@@ -29,8 +29,7 @@ public:
typedef int WaitableHandle;
static const WaitableHandle kInvalidHandleValue;
- IOObject(FDType type, bool should_close)
- : m_fd_type(type), m_should_close_fd(should_close) {}
+ IOObject(FDType type) : m_fd_type(type) {}
virtual ~IOObject();
virtual Status Read(void *buf, size_t &num_bytes) = 0;
@@ -44,8 +43,6 @@ public:
protected:
FDType m_fd_type;
- bool m_should_close_fd; // True if this class should close the file descriptor
- // when it goes away.
private:
DISALLOW_COPY_AND_ASSIGN(IOObject);
diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h
deleted file mode 100644
index 172f77afb01f..000000000000
--- a/include/lldb/Utility/JSON.h
+++ /dev/null
@@ -1,283 +0,0 @@
-//===---------------------JSON.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 utility_JSON_h_
-#define utility_JSON_h_
-
-#include "lldb/Utility/StringExtractor.h"
-
-#include <map>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <stdint.h>
-
-namespace lldb_private {
-class Stream;
-
-class JSONValue {
-public:
- virtual void Write(Stream &s) = 0;
-
- typedef std::shared_ptr<JSONValue> SP;
-
- enum class Kind { String, Number, True, False, Null, Object, Array };
-
- JSONValue(Kind k) : m_kind(k) {}
-
- Kind GetKind() const { return m_kind; }
-
- virtual ~JSONValue() = default;
-
-private:
- const Kind m_kind;
-};
-
-class JSONString : public JSONValue {
-public:
- JSONString();
- JSONString(const char *s);
- JSONString(const std::string &s);
-
- JSONString(const JSONString &s) = delete;
- JSONString &operator=(const JSONString &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONString> SP;
-
- std::string GetData() { return m_data; }
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::String;
- }
-
- ~JSONString() override = default;
-
-private:
- static std::string json_string_quote_metachars(const std::string &);
-
- std::string m_data;
-};
-
-class JSONNumber : public JSONValue {
-public:
- typedef std::shared_ptr<JSONNumber> SP;
-
- // We cretae a constructor for all integer and floating point type with using
- // templates and
- // SFINAE to avoid having ambiguous overloads because of the implicit type
- // promotion. If we
- // would have constructors only with int64_t, uint64_t and double types then
- // constructing a JSONNumber from an int32_t (or any other similar type)
- // would fail to compile.
-
- template <typename T, typename std::enable_if<
- std::is_integral<T>::value &&
- std::is_unsigned<T>::value>::type * = nullptr>
- explicit JSONNumber(T u)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
- m_data.m_unsigned = u;
- }
-
- template <typename T,
- typename std::enable_if<std::is_integral<T>::value &&
- std::is_signed<T>::value>::type * = nullptr>
- explicit JSONNumber(T s)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
- m_data.m_signed = s;
- }
-
- template <typename T, typename std::enable_if<
- std::is_floating_point<T>::value>::type * = nullptr>
- explicit JSONNumber(T d)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
- m_data.m_double = d;
- }
-
- ~JSONNumber() override = default;
-
- JSONNumber(const JSONNumber &s) = delete;
- JSONNumber &operator=(const JSONNumber &s) = delete;
-
- void Write(Stream &s) override;
-
- uint64_t GetAsUnsigned() const;
-
- int64_t GetAsSigned() const;
-
- double GetAsDouble() const;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Number;
- }
-
-private:
- enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
-
- union {
- uint64_t m_unsigned;
- int64_t m_signed;
- double m_double;
- } m_data;
-};
-
-class JSONTrue : public JSONValue {
-public:
- JSONTrue();
-
- JSONTrue(const JSONTrue &s) = delete;
- JSONTrue &operator=(const JSONTrue &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONTrue> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::True;
- }
-
- ~JSONTrue() override = default;
-};
-
-class JSONFalse : public JSONValue {
-public:
- JSONFalse();
-
- JSONFalse(const JSONFalse &s) = delete;
- JSONFalse &operator=(const JSONFalse &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONFalse> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::False;
- }
-
- ~JSONFalse() override = default;
-};
-
-class JSONNull : public JSONValue {
-public:
- JSONNull();
-
- JSONNull(const JSONNull &s) = delete;
- JSONNull &operator=(const JSONNull &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONNull> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Null;
- }
-
- ~JSONNull() override = default;
-};
-
-class JSONObject : public JSONValue {
-public:
- JSONObject();
-
- JSONObject(const JSONObject &s) = delete;
- JSONObject &operator=(const JSONObject &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONObject> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Object;
- }
-
- bool SetObject(const std::string &key, JSONValue::SP value);
-
- JSONValue::SP GetObject(const std::string &key);
-
- ~JSONObject() override = default;
-
-private:
- typedef std::map<std::string, JSONValue::SP> Map;
- typedef Map::iterator Iterator;
- Map m_elements;
-};
-
-class JSONArray : public JSONValue {
-public:
- JSONArray();
-
- JSONArray(const JSONArray &s) = delete;
- JSONArray &operator=(const JSONArray &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONArray> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Array;
- }
-
-private:
- typedef std::vector<JSONValue::SP> Vector;
- typedef Vector::iterator Iterator;
- typedef Vector::size_type Index;
- typedef Vector::size_type Size;
-
-public:
- bool SetObject(Index i, JSONValue::SP value);
-
- bool AppendObject(JSONValue::SP value);
-
- JSONValue::SP GetObject(Index i);
-
- Size GetNumElements();
-
- ~JSONArray() override = default;
-
- Vector m_elements;
-};
-
-class JSONParser : public StringExtractor {
-public:
- enum Token {
- Invalid,
- Status,
- ObjectStart,
- ObjectEnd,
- ArrayStart,
- ArrayEnd,
- Comma,
- Colon,
- String,
- Integer,
- Float,
- True,
- False,
- Null,
- EndOfFile
- };
-
- JSONParser(llvm::StringRef data);
-
- int GetEscapedChar(bool &was_escaped);
-
- Token GetToken(std::string &value);
-
- JSONValue::SP ParseJSONValue();
-
-protected:
- JSONValue::SP ParseJSONObject();
-
- JSONValue::SP ParseJSONArray();
-};
-} // namespace lldb_private
-
-#endif // utility_JSON_h_
diff --git a/include/lldb/Utility/Log.h b/include/lldb/Utility/Log.h
index 949de69c8e5a..09c0f6954478 100644
--- a/include/lldb/Utility/Log.h
+++ b/include/lldb/Utility/Log.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-defines.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -112,6 +113,14 @@ public:
static bool ListChannelCategories(llvm::StringRef channel,
llvm::raw_ostream &stream);
+ /// Returns the list of log channels.
+ static std::vector<llvm::StringRef> ListChannels();
+ /// Calls the given lambda for every category in the given channel.
+ /// If no channel with the given name exists, lambda is never called.
+ static void ForEachChannelCategory(
+ llvm::StringRef channel,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
static void DisableAllLogChannels();
static void ListAllLogChannels(llvm::raw_ostream &stream);
@@ -142,14 +151,11 @@ public:
std::forward<Args>(args)...));
}
+ /// Prefer using LLDB_LOGF whenever possible.
void Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
- void VAPrintf(const char *format, va_list args);
-
void Error(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
- void VAError(const char *format, va_list args);
-
void Verbose(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void Warning(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
@@ -161,6 +167,9 @@ public:
bool GetVerbose() const;
private:
+ void VAPrintf(const char *format, va_list args);
+ void VAError(const char *format, va_list args);
+
Channel &m_channel;
// The mutex makes sure enable/disable operations are thread-safe. The
@@ -193,6 +202,10 @@ private:
typedef llvm::StringMap<Log> ChannelMap;
static llvm::ManagedStatic<ChannelMap> g_channel_map;
+ static void ForEachCategory(
+ const Log::ChannelMap::value_type &entry,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
static void ListCategories(llvm::raw_ostream &stream,
const ChannelMap::value_type &entry);
static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
@@ -206,6 +219,26 @@ private:
} // namespace lldb_private
+/// The LLDB_LOG* macros defined below are the way to emit log messages.
+///
+/// Note that the macros surround the arguments in a check for the log
+/// being on, so you can freely call methods in arguments without affecting
+/// the non-log execution flow.
+///
+/// If you need to do more complex computations to prepare the log message
+/// be sure to add your own if (log) check, since we don't want logging to
+/// have any effect when not on.
+///
+/// However, the LLDB_LOG macro uses the llvm::formatv system (see the
+/// ProgrammersManual page in the llvm docs for more details). This allows
+/// the use of "format_providers" to auto-format datatypes, and there are
+/// already formatters for some of the llvm and lldb datatypes.
+///
+/// So if you need to do non-trivial formatting of one of these types, be
+/// sure to grep the lldb and llvm sources for "format_provider" to see if
+/// there is already a formatter before doing in situ formatting, and if
+/// possible add a provider if one does not already exist.
+
#define LLDB_LOG(log, ...) \
do { \
::lldb_private::Log *log_private = (log); \
@@ -213,6 +246,13 @@ private:
log_private->Format(__FILE__, __func__, __VA_ARGS__); \
} while (0)
+#define LLDB_LOGF(log, ...) \
+ do { \
+ ::lldb_private::Log *log_private = (log); \
+ if (log_private) \
+ log_private->Printf(__VA_ARGS__); \
+ } while (0)
+
#define LLDB_LOGV(log, ...) \
do { \
::lldb_private::Log *log_private = (log); \
diff --git a/include/lldb/Utility/Logging.h b/include/lldb/Utility/Logging.h
index 41086fedf8c2..1a8a1022c5c0 100644
--- a/include/lldb/Utility/Logging.h
+++ b/include/lldb/Utility/Logging.h
@@ -54,8 +54,6 @@ namespace lldb_private {
class Log;
-void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...);
-
Log *GetLogIfAllCategoriesSet(uint32_t mask);
Log *GetLogIfAnyCategoriesSet(uint32_t mask);
diff --git a/include/lldb/Utility/Predicate.h b/include/lldb/Utility/Predicate.h
index f1539b576686..cbccc3e91a8b 100644
--- a/include/lldb/Utility/Predicate.h
+++ b/include/lldb/Utility/Predicate.h
@@ -117,8 +117,7 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li m_value if Cond(m_value) is true.
- /// \li None otherwise (timeout occurred).
+ /// m_value if Cond(m_value) is true, None otherwise (timeout occurred).
template <typename C>
llvm::Optional<T> WaitFor(C Cond, const Timeout<std::micro> &timeout) {
std::unique_lock<std::mutex> lock(m_mutex);
@@ -151,8 +150,8 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li \b true if the \a m_value is equal to \a value
- /// \li \b false otherwise (timeout occurred)
+ /// true if the \a m_value is equal to \a value, false otherwise (timeout
+ /// occurred).
bool WaitForValueEqualTo(T value,
const Timeout<std::micro> &timeout = llvm::None) {
return WaitFor([&value](T current) { return value == current; }, timeout) !=
@@ -179,8 +178,7 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li m_value if m_value != value
- /// \li None otherwise (timeout occurred).
+ /// m_value if m_value != value, None otherwise (timeout occurred).
llvm::Optional<T>
WaitForValueNotEqualTo(T value,
const Timeout<std::micro> &timeout = llvm::None) {
diff --git a/include/lldb/Utility/ProcessInfo.h b/include/lldb/Utility/ProcessInfo.h
index a25c06cabdf6..9188bf3b7090 100644
--- a/include/lldb/Utility/ProcessInfo.h
+++ b/include/lldb/Utility/ProcessInfo.h
@@ -38,7 +38,7 @@ public:
const char *GetName() const;
- size_t GetNameLength() const;
+ llvm::StringRef GetNameAsStringRef() const;
FileSpec &GetExecutableFile() { return m_executable; }
@@ -165,12 +165,8 @@ public:
void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); }
- const char *GetProcessNameAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr);
- }
-
- size_t GetProcessNameLengthAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0);
+ llvm::StringRef GetProcessNameAtIndex(size_t idx) {
+ return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : "");
}
lldb::pid_t GetProcessIDAtIndex(size_t idx) {
@@ -227,8 +223,20 @@ public:
m_name_match_type = name_match_type;
}
+ /// Return true iff the architecture in this object matches arch_spec.
+ bool ArchitectureMatches(const ArchSpec &arch_spec) const;
+
+ /// Return true iff the process name in this object matches process_name.
bool NameMatches(const char *process_name) const;
+ /// Return true iff the process ID and parent process IDs in this object match
+ /// the ones in proc_info.
+ bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const;
+
+ /// Return true iff the (both effective and real) user and group IDs in this
+ /// object match the ones in proc_info.
+ bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const;
+
bool Matches(const ProcessInstanceInfo &proc_info) const;
bool MatchAllProcesses() const;
diff --git a/include/lldb/Utility/RangeMap.h b/include/lldb/Utility/RangeMap.h
index 36401f59d34f..709b5d2f66c7 100644
--- a/include/lldb/Utility/RangeMap.h
+++ b/include/lldb/Utility/RangeMap.h
@@ -724,12 +724,14 @@ public:
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert(IsSorted());
#endif
-
- if (!m_entries.empty()) {
- for (const auto &entry : m_entries) {
- if (entry.Contains(addr))
- indexes.push_back(entry.data);
- }
+ // Search the entries until the first entry that has a larger base address
+ // than `addr`. As m_entries is sorted by their base address, all following
+ // entries can't contain `addr` as their base address is already larger.
+ for (const auto &entry : m_entries) {
+ if (entry.Contains(addr))
+ indexes.push_back(entry.data);
+ else if (entry.GetRangeBase() > addr)
+ break;
}
return indexes.size();
}
diff --git a/include/lldb/Utility/RegularExpression.h b/include/lldb/Utility/RegularExpression.h
index 54f3dd89c7a2..6acc203d8e7c 100644
--- a/include/lldb/Utility/RegularExpression.h
+++ b/include/lldb/Utility/RegularExpression.h
@@ -9,189 +9,84 @@
#ifndef liblldb_RegularExpression_h_
#define liblldb_RegularExpression_h_
-#ifdef _WIN32
-#include "../lib/Support/regex_impl.h"
-
-typedef llvm_regmatch_t regmatch_t;
-typedef llvm_regex_t regex_t;
-
-inline int regcomp(llvm_regex_t *a, const char *b, int c) {
- return llvm_regcomp(a, b, c);
-}
-
-inline size_t regerror(int a, const llvm_regex_t *b, char *c, size_t d) {
- return llvm_regerror(a, b, c, d);
-}
-
-inline int regexec(const llvm_regex_t *a, const char *b, size_t c,
- llvm_regmatch_t d[], int e) {
- return llvm_regexec(a, b, c, d, e);
-}
-
-inline void regfree(llvm_regex_t *a) { llvm_regfree(a); }
-#else
-#ifdef __ANDROID__
-#include <regex>
-#endif
-#include <regex.h>
-#endif
-
-#include <string>
-#include <vector>
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace llvm {
-class StringRef;
-} // namespace llvm
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
namespace lldb_private {
-/// \class RegularExpression RegularExpression.h
-/// "lldb/Utility/RegularExpression.h"
-/// A C++ wrapper class for regex.
-///
-/// This regular expression class wraps the posix regex functions \c
-/// regcomp(), \c regerror(), \c regexec(), and \c regfree() from the header
-/// file in \c /usr/include/regex\.h.
class RegularExpression {
public:
- class Match {
- public:
- Match(uint32_t max_matches) : m_matches() {
- if (max_matches > 0)
- m_matches.resize(max_matches + 1);
- }
-
- void Clear() {
- const size_t num_matches = m_matches.size();
- regmatch_t invalid_match = {-1, -1};
- for (size_t i = 0; i < num_matches; ++i)
- m_matches[i] = invalid_match;
- }
-
- size_t GetSize() const { return m_matches.size(); }
-
- regmatch_t *GetData() {
- return (m_matches.empty() ? nullptr : m_matches.data());
- }
-
- bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- std::string &match_str) const;
-
- bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- llvm::StringRef &match_str) const;
-
- bool GetMatchSpanningIndices(llvm::StringRef s, uint32_t idx1,
- uint32_t idx2,
- llvm::StringRef &match_str) const;
-
- protected:
- std::vector<regmatch_t>
- m_matches; ///< Where parenthesized subexpressions results are stored
- };
-
- /// Default constructor.
- ///
/// The default constructor that initializes the object state such that it
/// contains no compiled regular expression.
- RegularExpression();
+ RegularExpression() = default;
- explicit RegularExpression(llvm::StringRef string);
-
- /// Destructor.
- ///
- /// Any previously compiled regular expression contained in this object will
- /// be freed.
- ~RegularExpression();
-
- RegularExpression(const RegularExpression &rhs);
-
- const RegularExpression &operator=(const RegularExpression &rhs);
-
- /// Compile a regular expression.
+ /// Constructor for a regular expression.
///
/// Compile a regular expression using the supplied regular expression text.
/// The compiled regular expression lives in this object so that it can be
/// readily used for regular expression matches. Execute() can be called
- /// after the regular expression is compiled. Any previously compiled
- /// regular expression contained in this object will be freed.
+ /// after the regular expression is compiled.
///
- /// \param[in] re
- /// A NULL terminated C string that represents the regular
- /// expression to compile.
- ///
- /// \return
- /// \b true if the regular expression compiles successfully,
- /// \b false otherwise.
- bool Compile(llvm::StringRef string);
- bool Compile(const char *) = delete;
+ /// \param[in] string
+ /// An llvm::StringRef that represents the regular expression to compile.
+ // String is not referenced anymore after the object is constructed.
+ explicit RegularExpression(llvm::StringRef string);
+
+ ~RegularExpression() = default;
+
+ RegularExpression(const RegularExpression &rhs);
+ RegularExpression(RegularExpression &&rhs) = default;
+
+ RegularExpression &operator=(RegularExpression &&rhs) = default;
+ RegularExpression &operator=(const RegularExpression &rhs) = default;
- /// Executes a regular expression.
- ///
/// Execute a regular expression match using the compiled regular expression
- /// that is already in this object against the match string \a s. If any
- /// parens are used for regular expression matches \a match_count should
- /// indicate the number of regmatch_t values that are present in \a
- /// match_ptr.
+ /// that is already in this object against the given \a string. If any parens
+ /// are used for regular expression matches.
///
/// \param[in] string
/// The string to match against the compile regular expression.
///
- /// \param[in] match
- /// A pointer to a RegularExpression::Match structure that was
- /// properly initialized with the desired number of maximum
- /// matches, or nullptr if no parenthesized matching is needed.
+ /// \param[out] matches
+ /// A pointer to a SmallVector to hold the matches.
///
/// \return
- /// \b true if \a string matches the compiled regular
- /// expression, \b false otherwise.
- bool Execute(llvm::StringRef string, Match *match = nullptr) const;
- bool Execute(const char *, Match * = nullptr) = delete;
-
- size_t GetErrorAsCString(char *err_str, size_t err_str_max_len) const;
-
- /// Free the compiled regular expression.
- ///
- /// If this object contains a valid compiled regular expression, this
- /// function will free any resources it was consuming.
- void Free();
+ /// true if \a string matches the compiled regular expression, false
+ /// otherwise incl. the case regular exression failed to compile.
+ bool Execute(llvm::StringRef string,
+ llvm::SmallVectorImpl<llvm::StringRef> *matches = nullptr) const;
/// Access the regular expression text.
///
- /// Returns the text that was used to compile the current regular
- /// expression.
- ///
/// \return
/// The NULL terminated C string that was used to compile the
/// current regular expression
llvm::StringRef GetText() const;
- /// Test if valid.
- ///
/// Test if this object contains a valid regular expression.
///
/// \return
- /// \b true if the regular expression compiled and is ready
- /// for execution, \b false otherwise.
+ /// true if the regular expression compiled and is ready for execution,
+ /// false otherwise.
bool IsValid() const;
- void Clear() {
- Free();
- m_re.clear();
- m_comp_err = 1;
- }
-
- int GetErrorCode() const { return m_comp_err; }
+ /// Return an error if the regular expression failed to compile.
+ ///
+ /// \return
+ /// A string error if the regular expression failed to compile, success
+ /// otherwise.
+ llvm::Error GetError() const;
- bool operator<(const RegularExpression &rhs) const;
+ bool operator==(const RegularExpression &rhs) const {
+ return GetText() == rhs.GetText();
+ }
private:
- // Member variables
- std::string m_re; ///< A copy of the original regular expression text
- int m_comp_err; ///< Status code for the regular expression compilation
- regex_t m_preg; ///< The compiled regular expression
+ /// A copy of the original regular expression text.
+ std::string m_regex_text;
+ /// The compiled regular expression.
+ mutable llvm::Regex m_regex;
};
} // namespace lldb_private
diff --git a/include/lldb/Utility/Reproducer.h b/include/lldb/Utility/Reproducer.h
index 670041d06bba..3db98a781d4c 100644
--- a/include/lldb/Utility/Reproducer.h
+++ b/include/lldb/Utility/Reproducer.h
@@ -9,11 +9,10 @@
#ifndef LLDB_UTILITY_REPRODUCER_H
#define LLDB_UTILITY_REPRODUCER_H
-#include "lldb/Utility/FileCollector.h"
#include "lldb/Utility/FileSpec.h"
-
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FileCollector.h"
#include "llvm/Support/YAMLTraits.h"
#include <mutex>
@@ -91,23 +90,26 @@ public:
FileProvider(const FileSpec &directory)
: Provider(directory),
- m_collector(directory.CopyByAppendingPathComponent("root"), directory) {
- }
+ m_collector(std::make_shared<llvm::FileCollector>(
+ directory.CopyByAppendingPathComponent("root").GetPath(),
+ directory.GetPath())) {}
- FileCollector &GetFileCollector() { return m_collector; }
+ std::shared_ptr<llvm::FileCollector> GetFileCollector() {
+ return m_collector;
+ }
void Keep() override {
auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
// Temporary files that are removed during execution can cause copy errors.
- if (auto ec = m_collector.CopyFiles(/*stop_on_error=*/false))
+ if (auto ec = m_collector->copyFiles(/*stop_on_error=*/false))
return;
- m_collector.WriteMapping(mapping);
+ m_collector->writeMapping(mapping.GetPath());
}
static char ID;
private:
- FileCollector m_collector;
+ std::shared_ptr<llvm::FileCollector> m_collector;
};
/// Provider for the LLDB version number.
@@ -130,11 +132,32 @@ public:
static char ID;
};
+/// Provider for the LLDB current working directroy.
+///
+/// When the reproducer is kept, it writes lldb's current working directory to
+/// a file named cwd.txt in the reproducer root.
+class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> {
+public:
+ WorkingDirectoryProvider(const FileSpec &directory) : Provider(directory) {
+ llvm::SmallString<128> cwd;
+ if (std::error_code EC = llvm::sys::fs::current_path(cwd))
+ return;
+ m_cwd = cwd.str();
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ void Keep() override;
+ std::string m_cwd;
+ static char ID;
+};
+
class DataRecorder {
public:
DataRecorder(const FileSpec &filename, std::error_code &ec)
: m_filename(filename.GetFilename().GetStringRef()),
- m_os(filename.GetPath(), ec, llvm::sys::fs::F_Text), m_record(true) {}
+ m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
static llvm::Expected<std::unique_ptr<DataRecorder>>
Create(const FileSpec &filename);
@@ -181,12 +204,39 @@ private:
std::vector<std::unique_ptr<DataRecorder>> m_data_recorders;
};
+class ProcessGDBRemoteProvider
+ : public repro::Provider<ProcessGDBRemoteProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
+
+ llvm::raw_ostream *GetHistoryStream();
+
+ void SetCallback(std::function<void()> callback) {
+ m_callback = std::move(callback);
+ }
+
+ void Keep() override { m_callback(); }
+ void Discard() override { m_callback(); }
+
+ static char ID;
+
+private:
+ std::function<void()> m_callback;
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+};
+
/// The generator is responsible for the logic needed to generate a
/// reproducer. For doing so it relies on providers, who serialize data that
/// is necessary for reproducing a failure.
class Generator final {
+
public:
- Generator(const FileSpec &root);
+ Generator(FileSpec root);
~Generator();
/// Method to indicate we want to keep the reproducer. If reproducer
@@ -200,7 +250,7 @@ public:
/// Create and register a new provider.
template <typename T> T *Create() {
- std::unique_ptr<ProviderBase> provider = llvm::make_unique<T>(m_root);
+ std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
return static_cast<T *>(Register(std::move(provider)));
}
@@ -243,7 +293,7 @@ private:
class Loader final {
public:
- Loader(const FileSpec &root);
+ Loader(FileSpec root);
template <typename T> FileSpec GetFile() {
if (!HasFile(T::file))
@@ -252,6 +302,15 @@ public:
return GetRoot().CopyByAppendingPathComponent(T::file);
}
+ template <typename T> llvm::Expected<std::string> LoadBuffer() {
+ FileSpec file = GetFile<typename T::Info>();
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+ llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
+ if (!buffer)
+ return llvm::errorCodeToError(buffer.getError());
+ return (*buffer)->getBuffer().str();
+ }
+
llvm::Error LoadIndex();
const FileSpec &GetRoot() const { return m_root; }
@@ -284,6 +343,9 @@ public:
FileSpec GetReproducerPath() const;
+ bool IsCapturing() { return static_cast<bool>(m_generator); };
+ bool IsReplaying() { return static_cast<bool>(m_loader); };
+
protected:
llvm::Error SetCapture(llvm::Optional<FileSpec> root);
llvm::Error SetReplay(llvm::Optional<FileSpec> root);
@@ -297,6 +359,19 @@ private:
mutable std::mutex m_mutex;
};
+/// Helper class for replaying commands through the reproducer.
+class CommandLoader {
+public:
+ CommandLoader(std::vector<std::string> files) : m_files(files) {}
+
+ static std::unique_ptr<CommandLoader> Create(Loader *loader);
+ llvm::Optional<std::string> GetNextFile();
+
+private:
+ std::vector<std::string> m_files;
+ unsigned m_index = 0;
+};
+
} // namespace repro
} // namespace lldb_private
diff --git a/include/lldb/Utility/ReproducerInstrumentation.h b/include/lldb/Utility/ReproducerInstrumentation.h
index f90ce4bc767a..75d66045758f 100644
--- a/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/include/lldb/Utility/ReproducerInstrumentation.h
@@ -40,7 +40,7 @@ inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) {
template <>
inline void stringify_append<char>(llvm::raw_string_ostream &ss,
const char *t) {
- ss << t;
+ ss << '\"' << t << '\"';
}
template <typename Head>
@@ -105,8 +105,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
+ lldb_private::repro::Recorder sb_recorder( \
+ LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -117,8 +117,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
+ lldb_private::repro::Recorder sb_recorder( \
+ LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -129,7 +129,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(*this)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
@@ -139,7 +140,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(*this)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -175,6 +177,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
#define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \
lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
stringify_args(__VA_ARGS__));
+#define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION);
namespace lldb_private {
namespace repro {
@@ -234,9 +238,12 @@ struct ReferenceTag {};
struct ValueTag {};
struct FundamentalPointerTag {};
struct FundamentalReferenceTag {};
+struct NotImplementedTag {};
/// Return the deserialization tag for the given type T.
-template <class T> struct serializer_tag { typedef ValueTag type; };
+template <class T> struct serializer_tag {
+ typedef typename std::conditional<std::is_trivially_copyable<T>::value, ValueTag, NotImplementedTag>::type type;
+};
template <class T> struct serializer_tag<T *> {
typedef
typename std::conditional<std::is_fundamental<T>::value,
@@ -300,6 +307,11 @@ public:
}
private:
+ template <typename T> T Read(NotImplementedTag) {
+ m_buffer = m_buffer.drop_front(sizeof(T));
+ return T();
+ }
+
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
T t;
@@ -442,7 +454,7 @@ public:
void Register(Signature *f, llvm::StringRef result = {},
llvm::StringRef scope = {}, llvm::StringRef name = {},
llvm::StringRef args = {}) {
- DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(f),
+ DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(f),
SignatureStr(result, scope, name, args));
}
@@ -452,7 +464,7 @@ public:
void Register(Signature *f, Signature *g, llvm::StringRef result = {},
llvm::StringRef scope = {}, llvm::StringRef name = {},
llvm::StringRef args = {}) {
- DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(g),
+ DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(g),
SignatureStr(result, scope, name, args));
}
@@ -542,9 +554,7 @@ public:
SerializeAll(tail...);
}
- void SerializeAll() {
- m_stream.flush();
- }
+ void SerializeAll() { m_stream.flush(); }
private:
/// Serialize pointers. We need to differentiate between pointers to
diff --git a/include/lldb/Utility/Scalar.h b/include/lldb/Utility/Scalar.h
index 62ee9f666e89..72f153ff97cd 100644
--- a/include/lldb/Utility/Scalar.h
+++ b/include/lldb/Utility/Scalar.h
@@ -38,6 +38,7 @@ namespace lldb_private {
// follows the ANSI C type promotion rules.
class Scalar {
public:
+ // FIXME: These are host types which seems to be an odd choice.
enum Type {
e_void = 0,
e_sint,
@@ -98,30 +99,14 @@ public:
}
Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
m_integer = llvm::APInt(v);
- switch (m_integer.getBitWidth()) {
- case 8:
- case 16:
- case 32:
- m_type = e_sint;
- return;
- case 64:
- m_type = e_slonglong;
- return;
- case 128:
- m_type = e_sint128;
- return;
- case 256:
- m_type = e_sint256;
- return;
- case 512:
- m_type = e_sint512;
- return;
- }
- lldbassert(false && "unsupported bitwidth");
+ m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
}
// Scalar(const RegisterValue& reg_value);
virtual ~Scalar();
+ /// Return the most efficient Scalar::Type for the requested bit size.
+ static Type GetBestTypeForBitSize(size_t bit_size, bool sign);
+
bool SignExtend(uint32_t bit_pos);
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
@@ -154,6 +139,9 @@ public:
return (m_type >= e_sint) && (m_type <= e_long_double);
}
+ /// Convert integer to \p type, limited to \p bits size.
+ void TruncOrExtendTo(Scalar::Type type, uint16_t bits);
+
bool Promote(Scalar::Type type);
bool MakeSigned();
diff --git a/include/lldb/Utility/Status.h b/include/lldb/Utility/Status.h
index ae730b90dffe..e6a0a8e7fce1 100644
--- a/include/lldb/Utility/Status.h
+++ b/include/lldb/Utility/Status.h
@@ -47,8 +47,8 @@ public:
/// into ValueType.
typedef uint32_t ValueType;
- /// Default constructor.
- ///
+ Status();
+
/// Initialize the error object with a generic success value.
///
/// \param[in] err
@@ -56,23 +56,14 @@ public:
///
/// \param[in] type
/// The type for \a err.
- Status();
-
explicit Status(ValueType err,
lldb::ErrorType type = lldb::eErrorTypeGeneric);
- /* implicit */ Status(std::error_code EC);
+ Status(std::error_code EC);
explicit Status(const char *format, ...)
__attribute__((format(printf, 2, 3)));
- /// Assignment operator.
- ///
- /// \param[in] err
- /// An error code.
- ///
- /// \return
- /// A const reference to this object.
const Status &operator=(const Status &rhs);
~Status();
@@ -221,4 +212,11 @@ template <> struct format_provider<lldb_private::Status> {
};
}
+#define LLDB_ERRORF(status, fmt, ...) \
+ do { \
+ if (status) { \
+ (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__); \
+ } \
+ } while (0);
+
#endif // #ifndef LLDB_UTILITY_STATUS_H
diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h
index b24d4e457177..414f92177303 100644
--- a/include/lldb/Utility/Stream.h
+++ b/include/lldb/Utility/Stream.h
@@ -35,11 +35,11 @@ public:
/// Utility class for counting the bytes that were written to a stream in a
/// certain time span.
+ ///
/// \example
/// ByteDelta delta(*this);
/// WriteDataToStream("foo");
/// return *delta;
- /// \endcode
class ByteDelta {
Stream *m_stream;
/// Bytes we have written so far when ByteDelta was created.
diff --git a/include/lldb/Utility/StreamGDBRemote.h b/include/lldb/Utility/StreamGDBRemote.h
deleted file mode 100644
index dd0ea31126d9..000000000000
--- a/include/lldb/Utility/StreamGDBRemote.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- StreamGDBRemote.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_StreamGDBRemote_h_
-#define liblldb_StreamGDBRemote_h_
-
-#include "lldb/Utility/StreamString.h"
-#include "lldb/lldb-enumerations.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace lldb_private {
-
-class StreamGDBRemote : public StreamString {
-public:
- StreamGDBRemote();
-
- StreamGDBRemote(uint32_t flags, uint32_t addr_size,
- lldb::ByteOrder byte_order);
-
- ~StreamGDBRemote() override;
-
- /// Output a block of data to the stream performing GDB-remote escaping.
- ///
- /// \param[in] s
- /// A block of data.
- ///
- /// \param[in] src_len
- /// The amount of data to write.
- ///
- /// \return
- /// Number of bytes written.
- // TODO: Convert this function to take ArrayRef<uint8_t>
- int PutEscapedBytes(const void *s, size_t src_len);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_StreamGDBRemote_h_
diff --git a/include/lldb/Utility/StringExtractor.h b/include/lldb/Utility/StringExtractor.h
index f20ec92199bb..293fef2fbe6b 100644
--- a/include/lldb/Utility/StringExtractor.h
+++ b/include/lldb/Utility/StringExtractor.h
@@ -45,9 +45,7 @@ public:
void SkipSpaces();
- std::string &GetStringRef() { return m_packet; }
-
- const std::string &GetStringRef() const { return m_packet; }
+ llvm::StringRef GetStringRef() const { return m_packet; }
bool Empty() { return m_packet.empty(); }
@@ -91,9 +89,6 @@ public:
size_t GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest);
- uint64_t GetHexWithFixedSize(uint32_t byte_size, bool little_endian,
- uint64_t fail_value);
-
size_t GetHexByteString(std::string &str);
size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length);
@@ -113,12 +108,14 @@ protected:
m_index = UINT64_MAX;
return false;
}
- // For StringExtractor only
- std::string m_packet; // The string in which to extract data.
- uint64_t m_index; // When extracting data from a packet, this index
- // will march along as things get extracted. If set to
- // UINT64_MAX the end of the packet data was reached
- // when decoding information
+
+ /// The string in which to extract data.
+ std::string m_packet;
+
+ /// When extracting data from a packet, this index will march along as things
+ /// get extracted. If set to UINT64_MAX the end of the packet data was
+ /// reached when decoding information.
+ uint64_t m_index;
};
#endif // utility_StringExtractor_h_
diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h
index d9806c1b37d7..533fd4fb896e 100644
--- a/include/lldb/Utility/StringLexer.h
+++ b/include/lldb/Utility/StringLexer.h
@@ -1,4 +1,4 @@
-//===--------------------- StringLexer.h ------------------------*- C++ -*-===//
+//===-- StringLexer.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.
@@ -13,7 +13,7 @@
#include <string>
#include <utility>
-namespace lldb_utility {
+namespace lldb_private {
class StringLexer {
public:
diff --git a/include/lldb/Utility/StringList.h b/include/lldb/Utility/StringList.h
index 68c1f87510f6..0b1d955678b3 100644
--- a/include/lldb/Utility/StringList.h
+++ b/include/lldb/Utility/StringList.h
@@ -23,6 +23,8 @@ class Stream;
namespace lldb_private {
class StringList {
+ typedef std::vector<std::string> collection;
+
public:
StringList();
@@ -52,6 +54,14 @@ public:
size_t GetMaxStringLength() const;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ iterator begin() { return m_strings.begin(); }
+ iterator end() { return m_strings.end(); }
+ const_iterator begin() const { return m_strings.begin(); }
+ const_iterator end() const { return m_strings.end(); }
+
std::string &operator[](size_t idx) {
// No bounds checking, verify "idx" is good prior to calling this function
return m_strings[idx];
@@ -69,7 +79,7 @@ public:
void Clear();
- void LongestCommonPrefix(std::string &common_prefix);
+ std::string LongestCommonPrefix();
void InsertStringAtIndex(size_t idx, const std::string &str);
@@ -97,14 +107,6 @@ public:
// Copy assignment for a vector of strings
StringList &operator=(const std::vector<std::string> &rhs);
- // This string list contains a list of valid auto completion strings, and the
- // "s" is passed in. "matches" is filled in with zero or more string values
- // that start with "s", and the first string to exactly match one of the
- // string values in this collection, will have "exact_matches_idx" filled in
- // to match the index, or "exact_matches_idx" will have SIZE_MAX
- size_t AutoComplete(llvm::StringRef s, StringList &matches,
- size_t &exact_matches_idx) const;
-
// Dump the StringList to the given lldb_private::Log, `log`, one item per
// line. If given, `name` will be used to identify the start and end of the
// list in the output.
@@ -125,7 +127,7 @@ public:
}
private:
- std::vector<std::string> m_strings;
+ collection m_strings;
};
} // namespace lldb_private
diff --git a/include/lldb/Utility/StructuredData.h b/include/lldb/Utility/StructuredData.h
index 75eb2f7b7291..01b14fc3d4d3 100644
--- a/include/lldb/Utility/StructuredData.h
+++ b/include/lldb/Utility/StructuredData.h
@@ -10,9 +10,11 @@
#define liblldb_StructuredData_h_
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
#include <cassert>
@@ -28,7 +30,6 @@
namespace lldb_private {
class Status;
-class Stream;
}
namespace lldb_private {
@@ -150,7 +151,12 @@ public:
void DumpToStdout(bool pretty_print = true) const;
- virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
+ virtual void Serialize(llvm::json::OStream &s) const = 0;
+
+ void Dump(lldb_private::Stream &s, bool pretty_print = true) const {
+ llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 2 : 0);
+ Serialize(jso);
+ }
private:
lldb::StructuredDataType m_type;
@@ -269,7 +275,7 @@ public:
void AddItem(ObjectSP item) { m_items.push_back(item); }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
typedef std::vector<ObjectSP> collection;
@@ -287,7 +293,7 @@ public:
uint64_t GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
uint64_t m_value;
@@ -304,7 +310,7 @@ public:
double GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
double m_value;
@@ -321,7 +327,7 @@ public:
bool GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
bool m_value;
@@ -337,7 +343,7 @@ public:
llvm::StringRef GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
std::string m_value;
@@ -506,7 +512,7 @@ public:
AddItem(key, std::make_shared<Boolean>(value));
}
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
typedef std::map<ConstString, ObjectSP> collection;
@@ -521,7 +527,7 @@ public:
bool IsValid() const override { return false; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
};
class Generic : public Object {
@@ -535,14 +541,13 @@ public:
bool IsValid() const override { return m_object != nullptr; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
private:
void *m_object;
};
static ObjectSP ParseJSON(std::string json_text);
-
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
};
diff --git a/include/lldb/Utility/UUID.h b/include/lldb/Utility/UUID.h
index dbeb9db611b2..0284357be44a 100644
--- a/include/lldb/Utility/UUID.h
+++ b/include/lldb/Utility/UUID.h
@@ -9,14 +9,11 @@
#ifndef LLDB_UTILITY_UUID_H
#define LLDB_UTILITY_UUID_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
-#include "llvm/ADT/ArrayRef.h"
-
-namespace llvm {
- class StringRef;
-}
namespace lldb_private {
@@ -67,10 +64,10 @@ public:
std::string GetAsString(llvm::StringRef separator = "-") const;
size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16);
-
- // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the
+
+ // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the
// UUID to invalid.
- size_t SetFromOptionalStringRef(llvm::StringRef str,
+ size_t SetFromOptionalStringRef(llvm::StringRef str,
uint32_t num_uuid_bytes = 16);
// Decode as many UUID bytes (up to 16) as possible from the C string "cstr"
@@ -79,14 +76,13 @@ public:
/// Decode as many UUID bytes (up to 16) as possible from the C
/// string \a cstr.
///
- /// \param[in] cstr
- /// A NULL terminate C string that points at a UUID string value
- /// (no leading spaces). The string must contain only hex
- /// characters and optionally can contain the '-' sepearators.
+ /// \param[in] str
+ /// An llvm::StringRef that points at a UUID string value (no leading
+ /// spaces). The string must contain only hex characters and optionally
+ /// can contain the '-' sepearators.
///
/// \param[in] uuid_bytes
- /// A buffer of bytes that will contain a full or patially
- /// decoded UUID.
+ /// A buffer of bytes that will contain a full or partially decoded UUID.
///
/// \return
/// The original string, with all decoded bytes removed.
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h
index f9830c04bc39..3c80bcffec20 100644
--- a/include/lldb/lldb-enumerations.h
+++ b/include/lldb/lldb-enumerations.h
@@ -69,21 +69,22 @@
namespace lldb {
-// Process and Thread States
+/// Process and Thread States.
enum StateType {
eStateInvalid = 0,
eStateUnloaded, ///< Process is object is valid, but not currently loaded
eStateConnected, ///< Process is connected to remote debug services, but not
- ///launched or attached to anything yet
+ /// launched or attached to anything yet
eStateAttaching, ///< Process is currently trying to attach
eStateLaunching, ///< Process is in the process of launching
- // The state changes eStateAttaching and eStateLaunching are both sent while the
- // private state thread is either not yet started or paused. For that reason, they
- // should only be signaled as public state changes, and not private state changes.
+ // The state changes eStateAttaching and eStateLaunching are both sent while
+ // the private state thread is either not yet started or paused. For that
+ // reason, they should only be signaled as public state changes, and not
+ // private state changes.
eStateStopped, ///< Process or thread is stopped and can be examined.
eStateRunning, ///< Process or thread is running and can't be examined.
eStateStepping, ///< Process or thread is in the process of stepping and can
- ///not be examined.
+ /// not be examined.
eStateCrashed, ///< Process or thread has crashed and can be examined.
eStateDetached, ///< Process has been detached and can't be examined.
eStateExited, ///< Process has exited and can't be examined.
@@ -93,16 +94,17 @@ enum StateType {
kLastStateType = eStateSuspended
};
-// Launch Flags
+/// Launch Flags.
FLAGS_ENUM(LaunchFlags){
eLaunchFlagNone = 0u,
eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling
- ///process into a new process
+ /// process into a new process
eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to
- ///allow the process to be debugged
- eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point
- ///instead of auto-continuing when
- ///launching or attaching at entry point
+ /// allow the process to be debugged
+ eLaunchFlagStopAtEntry = (1u
+ << 2), ///< Stop at the program entry point
+ /// instead of auto-continuing when
+ /// launching or attaching at entry point
eLaunchFlagDisableASLR =
(1u << 3), ///< Disable Address Space Layout Randomization
eLaunchFlagDisableSTDIO =
@@ -113,23 +115,23 @@ FLAGS_ENUM(LaunchFlags){
(1u << 6), ///< Launch the process inside a shell to get shell expansion
eLaunchFlagLaunchInSeparateProcessGroup =
(1u << 7), ///< Launch the process in a separate process group
- eLaunchFlagDontSetExitStatus = (1u << 8), ///< If you are going to hand the
- ///process off (e.g. to
- ///debugserver)
+ ///< If you are going to hand the process off (e.g. to
+ ///< debugserver)
+ eLaunchFlagDontSetExitStatus = (1u << 8),
///< set this flag so lldb & the handee don't race to set its exit status.
eLaunchFlagDetachOnError = (1u << 9), ///< If set, then the client stub
- ///should detach rather than killing
- ///the debugee
+ ///< should detach rather than killing
+ ///< the debugee
///< if it loses connection with lldb.
eLaunchFlagShellExpandArguments =
(1u << 10), ///< Perform shell-style argument expansion
eLaunchFlagCloseTTYOnExit = (1u << 11), ///< Close the open TTY on exit
};
-// Thread Run Modes
+/// Thread Run Modes.
enum RunMode { eOnlyThisThread, eAllThreads, eOnlyDuringStepping };
-// Byte ordering definitions
+/// Byte ordering definitions.
enum ByteOrder {
eByteOrderInvalid = 0,
eByteOrderBig = 1,
@@ -137,16 +139,16 @@ enum ByteOrder {
eByteOrderLittle = 4
};
-// Register encoding definitions
+/// Register encoding definitions.
enum Encoding {
eEncodingInvalid = 0,
- eEncodingUint, // unsigned integer
- eEncodingSint, // signed integer
- eEncodingIEEE754, // float
- eEncodingVector // vector registers
+ eEncodingUint, ///< unsigned integer
+ eEncodingSint, ///< signed integer
+ eEncodingIEEE754, ///< float
+ eEncodingVector ///< vector registers
};
-// Display format definitions
+/// Display format definitions.
enum Format {
eFormatDefault = 0,
eFormatInvalid = 0,
@@ -155,18 +157,18 @@ enum Format {
eFormatBytes,
eFormatBytesWithASCII,
eFormatChar,
- eFormatCharPrintable, // Only printable characters, space if not printable
- eFormatComplex, // Floating point complex type
+ eFormatCharPrintable, ///< Only printable characters, space if not printable
+ eFormatComplex, ///< Floating point complex type
eFormatComplexFloat = eFormatComplex,
- eFormatCString, // NULL terminated C strings
+ eFormatCString, ///< NULL terminated C strings
eFormatDecimal,
eFormatEnum,
eFormatHex,
eFormatHexUppercase,
eFormatFloat,
eFormatOctal,
- eFormatOSType, // OS character codes encoded into an integer 'PICT' 'text'
- // etc...
+ eFormatOSType, ///< OS character codes encoded into an integer 'PICT' 'text'
+ ///< etc...
eFormatUnicode16,
eFormatUnicode32,
eFormatUnsigned,
@@ -184,20 +186,21 @@ enum Format {
eFormatVectorOfFloat32,
eFormatVectorOfFloat64,
eFormatVectorOfUInt128,
- eFormatComplexInteger, // Integer complex type
- eFormatCharArray, // Print characters with no single quotes, used for
- // character arrays that can contain non printable
- // characters
- eFormatAddressInfo, // Describe what an address points to (func + offset with
- // file/line, symbol + offset, data, etc)
- eFormatHexFloat, // ISO C99 hex float string
- eFormatInstruction, // Disassemble an opcode
- eFormatVoid, // Do not print this
+ eFormatComplexInteger, ///< Integer complex type
+ eFormatCharArray, ///< Print characters with no single quotes, used for
+ ///< character arrays that can contain non printable
+ ///< characters
+ eFormatAddressInfo, ///< Describe what an address points to (func + offset
+ ///< with file/line, symbol + offset, data, etc)
+ eFormatHexFloat, ///< ISO C99 hex float string
+ eFormatInstruction, ///< Disassemble an opcode
+ eFormatVoid, ///< Do not print this
+ eFormatUnicode8,
kNumFormats
};
-// Description levels for "void GetDescription(Stream *, DescriptionLevel)"
-// calls
+/// Description levels for "void GetDescription(Stream *, DescriptionLevel)"
+/// calls.
enum DescriptionLevel {
eDescriptionLevelBrief = 0,
eDescriptionLevelFull,
@@ -206,7 +209,7 @@ enum DescriptionLevel {
kNumDescriptionLevels
};
-// Script interpreter types
+/// Script interpreter types.
enum ScriptLanguage {
eScriptLanguageNone,
eScriptLanguagePython,
@@ -214,21 +217,21 @@ enum ScriptLanguage {
eScriptLanguageUnknown
};
-// Register numbering types
+/// Register numbering types.
// See RegisterContext::ConvertRegisterKindToRegisterNumber to convert any of
// these to the lldb internal register numbering scheme (eRegisterKindLLDB).
enum RegisterKind {
- eRegisterKindEHFrame = 0, // the register numbers seen in eh_frame
- eRegisterKindDWARF, // the register numbers seen DWARF
- eRegisterKindGeneric, // insn ptr reg, stack ptr reg, etc not specific to any
- // particular target
- eRegisterKindProcessPlugin, // num used by the process plugin - e.g. by the
- // remote gdb-protocol stub program
- eRegisterKindLLDB, // lldb's internal register numbers
+ eRegisterKindEHFrame = 0, ///< the register numbers seen in eh_frame
+ eRegisterKindDWARF, ///< the register numbers seen DWARF
+ eRegisterKindGeneric, ///< insn ptr reg, stack ptr reg, etc not specific to
+ ///< any particular target
+ eRegisterKindProcessPlugin, ///< num used by the process plugin - e.g. by the
+ ///< remote gdb-protocol stub program
+ eRegisterKindLLDB, ///< lldb's internal register numbers
kNumRegisterKinds
};
-// Thread stop reasons
+/// Thread stop reasons.
enum StopReason {
eStopReasonInvalid = 0,
eStopReasonNone,
@@ -237,13 +240,13 @@ enum StopReason {
eStopReasonWatchpoint,
eStopReasonSignal,
eStopReasonException,
- eStopReasonExec, // Program was re-exec'ed
+ eStopReasonExec, ///< Program was re-exec'ed
eStopReasonPlanComplete,
eStopReasonThreadExiting,
eStopReasonInstrumentation
};
-// Command Return Status Types
+/// Command Return Status Types.
enum ReturnStatus {
eReturnStatusInvalid,
eReturnStatusSuccessFinishNoResult,
@@ -255,7 +258,7 @@ enum ReturnStatus {
eReturnStatusQuit
};
-// The results of expression evaluation:
+/// The results of expression evaluation.
enum ExpressionResults {
eExpressionCompleted = 0,
eExpressionSetupError,
@@ -269,26 +272,26 @@ enum ExpressionResults {
};
enum SearchDepth {
- eSearchDepthInvalid = 0,
- eSearchDepthTarget,
- eSearchDepthModule,
- eSearchDepthCompUnit,
- eSearchDepthFunction,
- eSearchDepthBlock,
- eSearchDepthAddress,
- kLastSearchDepthKind = eSearchDepthAddress
+ eSearchDepthInvalid = 0,
+ eSearchDepthTarget,
+ eSearchDepthModule,
+ eSearchDepthCompUnit,
+ eSearchDepthFunction,
+ eSearchDepthBlock,
+ eSearchDepthAddress,
+ kLastSearchDepthKind = eSearchDepthAddress
};
-// Connection Status Types
+/// Connection Status Types.
enum ConnectionStatus {
- eConnectionStatusSuccess, // Success
- eConnectionStatusEndOfFile, // End-of-file encountered
- eConnectionStatusError, // Check GetError() for details
- eConnectionStatusTimedOut, // Request timed out
- eConnectionStatusNoConnection, // No connection
- eConnectionStatusLostConnection, // Lost connection while connected to a valid
- // connection
- eConnectionStatusInterrupted // Interrupted read
+ eConnectionStatusSuccess, ///< Success
+ eConnectionStatusEndOfFile, ///< End-of-file encountered
+ eConnectionStatusError, ///< Check GetError() for details
+ eConnectionStatusTimedOut, ///< Request timed out
+ eConnectionStatusNoConnection, ///< No connection
+ eConnectionStatusLostConnection, ///< Lost connection while connected to a
+ ///< valid connection
+ eConnectionStatusInterrupted ///< Interrupted read
};
enum ErrorType {
@@ -302,17 +305,17 @@ enum ErrorType {
enum ValueType {
eValueTypeInvalid = 0,
- eValueTypeVariableGlobal = 1, // globals variable
- eValueTypeVariableStatic = 2, // static variable
- eValueTypeVariableArgument = 3, // function argument variables
- eValueTypeVariableLocal = 4, // function local variables
- eValueTypeRegister = 5, // stack frame register value
- eValueTypeRegisterSet = 6, // A collection of stack frame register values
- eValueTypeConstResult = 7, // constant result variables
- eValueTypeVariableThreadLocal = 8 // thread local storage variable
+ eValueTypeVariableGlobal = 1, ///< globals variable
+ eValueTypeVariableStatic = 2, ///< static variable
+ eValueTypeVariableArgument = 3, ///< function argument variables
+ eValueTypeVariableLocal = 4, ///< function local variables
+ eValueTypeRegister = 5, ///< stack frame register value
+ eValueTypeRegisterSet = 6, ///< A collection of stack frame register values
+ eValueTypeConstResult = 7, ///< constant result variables
+ eValueTypeVariableThreadLocal = 8 ///< thread local storage variable
};
-// Token size/granularities for Input Readers
+/// Token size/granularities for Input Readers.
enum InputReaderGranularity {
eInputReaderGranularityInvalid = 0,
@@ -331,39 +334,37 @@ enum InputReaderGranularity {
/// in this class, and requests that that item be resolved, or
/// indicates that the member did get resolved.
FLAGS_ENUM(SymbolContextItem){
- eSymbolContextTarget = (1u << 0), ///< Set when \a target is requested from
- /// a query, or was located in query
- /// results
- eSymbolContextModule = (1u << 1), ///< Set when \a module is requested from
- /// a query, or was located in query
- /// results
- eSymbolContextCompUnit = (1u << 2), ///< Set when \a comp_unit is requested
- /// from a query, or was located in
- /// query results
- eSymbolContextFunction = (1u << 3), ///< Set when \a function is requested
- /// from a query, or was located in
- /// query results
- eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is
- /// requested from a query, or was located
- /// in query results
- eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is
- /// requested from a query, or was
- /// located in query results
- eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from
- /// a query, or was located in query
- /// results
- eSymbolContextEverything = ((eSymbolContextSymbol << 1) -
- 1u), ///< Indicates to try and lookup everything
- /// up during a routine symbol context
- /// query.
- eSymbolContextVariable = (1u << 7), ///< Set when \a global or static
- /// variable is requested from a query,
- /// or was located in query results.
- ///< eSymbolContextVariable is potentially expensive to lookup so it isn't
- /// included in
- ///< eSymbolContextEverything which stops it from being used during frame PC
- /// lookups and
- ///< many other potential address to symbol context lookups.
+ /// Set when \a target is requested from a query, or was located
+ /// in query results
+ eSymbolContextTarget = (1u << 0),
+ /// Set when \a module is requested from a query, or was located
+ /// in query results
+ eSymbolContextModule = (1u << 1),
+ /// Set when \a comp_unit is requested from a query, or was
+ /// located in query results
+ eSymbolContextCompUnit = (1u << 2),
+ /// Set when \a function is requested from a query, or was located
+ /// in query results
+ eSymbolContextFunction = (1u << 3),
+ /// Set when the deepest \a block is requested from a query, or
+ /// was located in query results
+ eSymbolContextBlock = (1u << 4),
+ /// Set when \a line_entry is requested from a query, or was
+ /// located in query results
+ eSymbolContextLineEntry = (1u << 5),
+ /// Set when \a symbol is requested from a query, or was located
+ /// in query results
+ eSymbolContextSymbol = (1u << 6),
+ /// Indicates to try and lookup everything up during a routine
+ /// symbol context query.
+ eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u),
+ /// Set when \a global or static variable is requested from a
+ /// query, or was located in query results.
+ /// eSymbolContextVariable is potentially expensive to lookup so
+ /// it isn't included in eSymbolContextEverything which stops it
+ /// from being used during frame PC lookups and many other
+ /// potential address to symbol context lookups.
+ eSymbolContextVariable = (1u << 7),
};
LLDB_MARK_AS_BITMASK_ENUM(SymbolContextItem)
@@ -373,27 +374,28 @@ FLAGS_ENUM(Permissions){ePermissionsWritable = (1u << 0),
LLDB_MARK_AS_BITMASK_ENUM(Permissions)
enum InputReaderAction {
- eInputReaderActivate, // reader is newly pushed onto the reader stack
- eInputReaderAsynchronousOutputWritten, // an async output event occurred; the
- // reader may want to do something
- eInputReaderReactivate, // reader is on top of the stack again after another
- // reader was popped off
- eInputReaderDeactivate, // another reader was pushed on the stack
- eInputReaderGotToken, // reader got one of its tokens (granularity)
- eInputReaderInterrupt, // reader received an interrupt signal (probably from a
- // control-c)
- eInputReaderEndOfFile, // reader received an EOF char (probably from a
- // control-d)
- eInputReaderDone // reader was just popped off the stack and is done
+ eInputReaderActivate, ///< reader is newly pushed onto the reader stack
+ eInputReaderAsynchronousOutputWritten, ///< an async output event occurred;
+ ///< the reader may want to do
+ ///< something
+ eInputReaderReactivate, ///< reader is on top of the stack again after another
+ ///< reader was popped off
+ eInputReaderDeactivate, ///< another reader was pushed on the stack
+ eInputReaderGotToken, ///< reader got one of its tokens (granularity)
+ eInputReaderInterrupt, ///< reader received an interrupt signal (probably from
+ ///< a control-c)
+ eInputReaderEndOfFile, ///< reader received an EOF char (probably from a
+ ///< control-d)
+ eInputReaderDone ///< reader was just popped off the stack and is done
};
FLAGS_ENUM(BreakpointEventType){
eBreakpointEventTypeInvalidType = (1u << 0),
eBreakpointEventTypeAdded = (1u << 1),
eBreakpointEventTypeRemoved = (1u << 2),
- eBreakpointEventTypeLocationsAdded = (1u << 3), // Locations added doesn't
- // get sent when the
- // breakpoint is created
+ eBreakpointEventTypeLocationsAdded = (1u << 3), ///< Locations added doesn't
+ ///< get sent when the
+ ///< breakpoint is created
eBreakpointEventTypeLocationsRemoved = (1u << 4),
eBreakpointEventTypeLocationsResolved = (1u << 5),
eBreakpointEventTypeEnabled = (1u << 6),
@@ -591,8 +593,8 @@ enum CommandArgumentType {
// enumeration!!
};
-// Symbol types
-// Symbol holds the SymbolType in a 6-bit field (m_type), so if you get over 63
+/// Symbol types.
+// Symbol holds the SymbolType in a 6-bit field (m_type), so if you get over 63
// entries you will have to resize that field.
enum SymbolType {
eSymbolTypeAny = 0,
@@ -617,8 +619,8 @@ enum SymbolType {
eSymbolTypeLineHeader,
eSymbolTypeScopeBegin,
eSymbolTypeScopeEnd,
- eSymbolTypeAdditional, // When symbols take more than one entry, the extra
- // entries get this type
+ eSymbolTypeAdditional, ///< When symbols take more than one entry, the extra
+ ///< entries get this type
eSymbolTypeCompiler,
eSymbolTypeInstrumentation,
eSymbolTypeUndefined,
@@ -631,19 +633,20 @@ enum SymbolType {
enum SectionType {
eSectionTypeInvalid,
eSectionTypeCode,
- eSectionTypeContainer, // The section contains child sections
+ eSectionTypeContainer, ///< The section contains child sections
eSectionTypeData,
- eSectionTypeDataCString, // Inlined C string data
- eSectionTypeDataCStringPointers, // Pointers to C string data
- eSectionTypeDataSymbolAddress, // Address of a symbol in the symbol table
+ eSectionTypeDataCString, ///< Inlined C string data
+ eSectionTypeDataCStringPointers, ///< Pointers to C string data
+ eSectionTypeDataSymbolAddress, ///< Address of a symbol in the symbol table
eSectionTypeData4,
eSectionTypeData8,
eSectionTypeData16,
eSectionTypeDataPointers,
eSectionTypeDebug,
eSectionTypeZeroFill,
- eSectionTypeDataObjCMessageRefs, // Pointer to function pointer + selector
- eSectionTypeDataObjCCFStrings, // Objective-C const CFString/NSString objects
+ eSectionTypeDataObjCMessageRefs, ///< Pointer to function pointer + selector
+ eSectionTypeDataObjCCFStrings, ///< Objective-C const CFString/NSString
+ ///< objects
eSectionTypeDWARFDebugAbbrev,
eSectionTypeDWARFDebugAddr,
eSectionTypeDWARFDebugAranges,
@@ -663,25 +666,25 @@ enum SectionType {
eSectionTypeDWARFAppleTypes,
eSectionTypeDWARFAppleNamespaces,
eSectionTypeDWARFAppleObjC,
- eSectionTypeELFSymbolTable, // Elf SHT_SYMTAB section
- eSectionTypeELFDynamicSymbols, // Elf SHT_DYNSYM section
- eSectionTypeELFRelocationEntries, // Elf SHT_REL or SHT_REL section
- eSectionTypeELFDynamicLinkInfo, // Elf SHT_DYNAMIC section
+ eSectionTypeELFSymbolTable, ///< Elf SHT_SYMTAB section
+ eSectionTypeELFDynamicSymbols, ///< Elf SHT_DYNSYM section
+ eSectionTypeELFRelocationEntries, ///< Elf SHT_REL or SHT_REL section
+ eSectionTypeELFDynamicLinkInfo, ///< Elf SHT_DYNAMIC section
eSectionTypeEHFrame,
eSectionTypeARMexidx,
eSectionTypeARMextab,
- eSectionTypeCompactUnwind, // compact unwind section in Mach-O,
- // __TEXT,__unwind_info
+ eSectionTypeCompactUnwind, ///< compact unwind section in Mach-O,
+ ///< __TEXT,__unwind_info
eSectionTypeGoSymtab,
- eSectionTypeAbsoluteAddress, // Dummy section for symbols with absolute
- // address
+ eSectionTypeAbsoluteAddress, ///< Dummy section for symbols with absolute
+ ///< address
eSectionTypeDWARFGNUDebugAltLink,
- eSectionTypeDWARFDebugTypes, // DWARF .debug_types section
- eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names
+ eSectionTypeDWARFDebugTypes, ///< DWARF .debug_types section
+ eSectionTypeDWARFDebugNames, ///< DWARF v5 .debug_names
eSectionTypeOther,
- eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str
- eSectionTypeDWARFDebugRngLists, // DWARF v5 .debug_rnglists
- eSectionTypeDWARFDebugLocLists, // DWARF v5 .debug_loclists
+ eSectionTypeDWARFDebugLineStr, ///< DWARF v5 .debug_line_str
+ eSectionTypeDWARFDebugRngLists, ///< DWARF v5 .debug_rnglists
+ eSectionTypeDWARFDebugLocLists, ///< DWARF v5 .debug_loclists
eSectionTypeDWARFDebugAbbrevDwo,
eSectionTypeDWARFDebugInfoDwo,
eSectionTypeDWARFDebugStrDwo,
@@ -697,26 +700,27 @@ FLAGS_ENUM(EmulateInstructionOptions){
FLAGS_ENUM(FunctionNameType){
eFunctionNameTypeNone = 0u,
eFunctionNameTypeAuto =
- (1u << 1), // Automatically figure out which FunctionNameType
- // bits to set based on the function name.
- eFunctionNameTypeFull = (1u << 2), // The function name.
- // For C this is the same as just the name of the function For C++ this is
- // the mangled or demangled version of the mangled name. For ObjC this is
- // the full function signature with the + or - and the square brackets and
- // the class and selector
- eFunctionNameTypeBase = (1u << 3), // The function name only, no namespaces
- // or arguments and no class
- // methods or selectors will be searched.
- eFunctionNameTypeMethod = (1u << 4), // Find function by method name (C++)
- // with no namespace or arguments
+ (1u << 1), ///< Automatically figure out which FunctionNameType
+ ///< bits to set based on the function name.
+ eFunctionNameTypeFull = (1u << 2), ///< The function name.
+ ///< For C this is the same as just the name of the function For C++ this is
+ ///< the mangled or demangled version of the mangled name. For ObjC this is
+ ///< the full function signature with the + or - and the square brackets and
+ ///< the class and selector
+ eFunctionNameTypeBase = (1u
+ << 3), ///< The function name only, no namespaces
+ ///< or arguments and no class
+ ///< methods or selectors will be searched.
+ eFunctionNameTypeMethod = (1u << 4), ///< Find function by method name (C++)
+ ///< with no namespace or arguments
eFunctionNameTypeSelector =
- (1u << 5), // Find function by selector name (ObjC) names
+ (1u << 5), ///< Find function by selector name (ObjC) names
eFunctionNameTypeAny =
- eFunctionNameTypeAuto // DEPRECATED: use eFunctionNameTypeAuto
+ eFunctionNameTypeAuto ///< DEPRECATED: use eFunctionNameTypeAuto
};
LLDB_MARK_AS_BITMASK_ENUM(FunctionNameType)
-// Basic types enumeration for the public API SBType::GetBasicType()
+/// Basic types enumeration for the public API SBType::GetBasicType().
enum BasicType {
eBasicTypeInvalid = 0,
eBasicTypeVoid = 1,
@@ -801,8 +805,8 @@ enum TemplateArgumentKind {
eTemplateArgumentKindNullPtr,
};
-// Options that can be set for a formatter to alter its behavior Not all of
-// these are applicable to all formatter types
+/// Options that can be set for a formatter to alter its behavior. Not
+/// all of these are applicable to all formatter types.
FLAGS_ENUM(TypeOptions){eTypeOptionNone = (0u),
eTypeOptionCascade = (1u << 0),
eTypeOptionSkipPointers = (1u << 1),
@@ -813,20 +817,28 @@ FLAGS_ENUM(TypeOptions){eTypeOptionNone = (0u),
eTypeOptionHideNames = (1u << 6),
eTypeOptionNonCacheable = (1u << 7),
eTypeOptionHideEmptyAggregates = (1u << 8),
- eTypeOptionFrontEndWantsDereference = (1u << 9)
-};
+ eTypeOptionFrontEndWantsDereference = (1u << 9)};
-// This is the return value for frame comparisons. If you are comparing frame
-// A to frame B the following cases arise: 1) When frame A pushes frame B (or a
-// frame that ends up pushing B) A is Older than B. 2) When frame A pushed
-// frame B (or if frame A is on the stack but B is not) A is Younger than B 3)
-// When frame A and frame B have the same StackID, they are Equal. 4) When
-// frame A and frame B have the same immediate parent frame, but are not equal,
-// the comparison yields
-// SameParent.
-// 5) If the two frames are on different threads or processes the comparison is
-// Invalid 6) If for some reason we can't figure out what went on, we return
-// Unknown.
+/// This is the return value for frame comparisons. If you are comparing frame
+/// A to frame B the following cases arise:
+///
+/// 1) When frame A pushes frame B (or a frame that ends up pushing
+/// B) A is Older than B.
+///
+/// 2) When frame A pushed frame B (or if frameA is on the stack
+/// but B is not) A is Younger than B.
+///
+/// 3) When frame A and frame B have the same StackID, they are
+/// Equal.
+///
+/// 4) When frame A and frame B have the same immediate parent
+/// frame, but are not equal, the comparison yields SameParent.
+///
+/// 5) If the two frames are on different threads or processes the
+/// comparison is Invalid.
+///
+/// 6) If for some reason we can't figure out what went on, we
+/// return Unknown.
enum FrameComparison {
eFrameCompareInvalid,
eFrameCompareUnknown,
@@ -836,12 +848,13 @@ enum FrameComparison {
eFrameCompareOlder
};
-// File Permissions
-//
-// Designed to mimic the unix file permission bits so they can be used with
-// functions that set 'mode_t' to certain values for permissions.
+/// File Permissions.
+///
+/// Designed to mimic the unix file permission bits so they can be used with
+/// functions that set 'mode_t' to certain values for permissions.
FLAGS_ENUM(FilePermissions){
- eFilePermissionsUserRead = (1u << 8), eFilePermissionsUserWrite = (1u << 7),
+ eFilePermissionsUserRead = (1u << 8),
+ eFilePermissionsUserWrite = (1u << 7),
eFilePermissionsUserExecute = (1u << 6),
eFilePermissionsGroupRead = (1u << 5),
eFilePermissionsGroupWrite = (1u << 4),
@@ -895,29 +908,32 @@ FLAGS_ENUM(FilePermissions){
eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX,
};
-// Queue work item types
-//
-// The different types of work that can be enqueued on a libdispatch aka Grand
-// Central Dispatch (GCD) queue.
+/// Queue work item types.
+///
+/// The different types of work that can be enqueued on a libdispatch aka Grand
+/// Central Dispatch (GCD) queue.
enum QueueItemKind {
eQueueItemKindUnknown = 0,
eQueueItemKindFunction,
eQueueItemKindBlock
};
-// Queue type
-// libdispatch aka Grand Central Dispatch (GCD) queues can be either serial
-// (executing on one thread) or concurrent (executing on multiple threads).
+/// Queue type.
+///
+/// libdispatch aka Grand Central Dispatch (GCD) queues can be either
+/// serial (executing on one thread) or concurrent (executing on
+/// multiple threads).
enum QueueKind {
eQueueKindUnknown = 0,
eQueueKindSerial,
eQueueKindConcurrent
};
-// Expression Evaluation Stages
-// These are the cancellable stages of expression evaluation, passed to the
-// expression evaluation callback, so that you can interrupt expression
-// evaluation at the various points in its lifecycle.
+/// Expression Evaluation Stages.
+///
+/// These are the cancellable stages of expression evaluation, passed
+/// to the expression evaluation callback, so that you can interrupt
+/// expression evaluation at the various points in its lifecycle.
enum ExpressionEvaluationPhase {
eExpressionEvaluationParse = 0,
eExpressionEvaluationIRGen,
@@ -925,9 +941,10 @@ enum ExpressionEvaluationPhase {
eExpressionEvaluationComplete
};
-// Watchpoint Kind
-// Indicates what types of events cause the watchpoint to fire. Used by Native
-// *Protocol-related classes.
+/// Watchpoint Kind.
+///
+/// Indicates what types of events cause the watchpoint to fire. Used by Native
+/// *Protocol-related classes.
FLAGS_ENUM(WatchpointKind){eWatchpointKindWrite = (1u << 0),
eWatchpointKindRead = (1u << 1)};
@@ -940,42 +957,44 @@ enum GdbSignal {
eGdbSignalBreakpoint = 0x96
};
-// Used with SBHost::GetPath (lldb::PathType) to find files that are related to
-// LLDB on the current host machine. Most files are relative to LLDB or are in
-// known locations.
+/// Used with SBHost::GetPath (lldb::PathType) to find files that are
+/// related to LLDB on the current host machine. Most files are
+/// relative to LLDB or are in known locations.
enum PathType {
- ePathTypeLLDBShlibDir, // The directory where the lldb.so (unix) or LLDB
- // mach-o file in LLDB.framework (MacOSX) exists
- ePathTypeSupportExecutableDir, // Find LLDB support executable directory
- // (debugserver, etc)
- ePathTypeHeaderDir, // Find LLDB header file directory
- ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory
- ePathTypeLLDBSystemPlugins, // System plug-ins directory
- ePathTypeLLDBUserPlugins, // User plug-ins directory
- ePathTypeLLDBTempSystemDir, // The LLDB temp directory for this system that
- // will be cleaned up on exit
- ePathTypeGlobalLLDBTempSystemDir, // The LLDB temp directory for this system,
- // NOT cleaned up on a process exit.
- ePathTypeClangDir // Find path to Clang builtin headers
+ ePathTypeLLDBShlibDir, ///< The directory where the lldb.so (unix) or LLDB
+ ///< mach-o file in LLDB.framework (MacOSX) exists
+ ePathTypeSupportExecutableDir, ///< Find LLDB support executable directory
+ ///< (debugserver, etc)
+ ePathTypeHeaderDir, ///< Find LLDB header file directory
+ ePathTypePythonDir, ///< Find Python modules (PYTHONPATH) directory
+ ePathTypeLLDBSystemPlugins, ///< System plug-ins directory
+ ePathTypeLLDBUserPlugins, ///< User plug-ins directory
+ ePathTypeLLDBTempSystemDir, ///< The LLDB temp directory for this system that
+ ///< will be cleaned up on exit
+ ePathTypeGlobalLLDBTempSystemDir, ///< The LLDB temp directory for this
+ ///< system, NOT cleaned up on a process
+ ///< exit.
+ ePathTypeClangDir ///< Find path to Clang builtin headers
};
-// Kind of member function
-// Used by the type system
+/// Kind of member function.
+///
+/// Used by the type system.
enum MemberFunctionKind {
- eMemberFunctionKindUnknown = 0, // Not sure what the type of this is
- eMemberFunctionKindConstructor, // A function used to create instances
- eMemberFunctionKindDestructor, // A function used to tear down existing
- // instances
- eMemberFunctionKindInstanceMethod, // A function that applies to a specific
- // instance
- eMemberFunctionKindStaticMethod // A function that applies to a type rather
- // than any instance
+ eMemberFunctionKindUnknown = 0, ///< Not sure what the type of this is
+ eMemberFunctionKindConstructor, ///< A function used to create instances
+ eMemberFunctionKindDestructor, ///< A function used to tear down existing
+ ///< instances
+ eMemberFunctionKindInstanceMethod, ///< A function that applies to a specific
+ ///< instance
+ eMemberFunctionKindStaticMethod ///< A function that applies to a type rather
+ ///< than any instance
};
-// String matching algorithm used by SBTarget
+/// String matching algorithm used by SBTarget.
enum MatchType { eMatchTypeNormal, eMatchTypeRegex, eMatchTypeStartsWith };
-// Bitmask that describes details about a type
+/// Bitmask that describes details about a type.
FLAGS_ENUM(TypeFlags){
eTypeHasChildren = (1u << 0), eTypeHasValue = (1u << 1),
eTypeIsArray = (1u << 2), eTypeIsBlock = (1u << 3),
@@ -991,67 +1010,67 @@ FLAGS_ENUM(TypeFlags){
eTypeInstanceIsPointer = (1u << 22)};
FLAGS_ENUM(CommandFlags){
- // eCommandRequiresTarget
- //
- // Ensures a valid target is contained in m_exe_ctx prior to executing the
- // command. If a target doesn't exist or is invalid, the command will fail
- // and CommandObject::GetInvalidTargetDescription() will be returned as the
- // error. CommandObject subclasses can override the virtual function for
- // GetInvalidTargetDescription() to provide custom strings when needed.
+ /// eCommandRequiresTarget
+ ///
+ /// Ensures a valid target is contained in m_exe_ctx prior to executing the
+ /// command. If a target doesn't exist or is invalid, the command will fail
+ /// and CommandObject::GetInvalidTargetDescription() will be returned as the
+ /// error. CommandObject subclasses can override the virtual function for
+ /// GetInvalidTargetDescription() to provide custom strings when needed.
eCommandRequiresTarget = (1u << 0),
- // eCommandRequiresProcess
- //
- // Ensures a valid process is contained in m_exe_ctx prior to executing the
- // command. If a process doesn't exist or is invalid, the command will fail
- // and CommandObject::GetInvalidProcessDescription() will be returned as
- // the error. CommandObject subclasses can override the virtual function
- // for GetInvalidProcessDescription() to provide custom strings when
- // needed.
+ /// eCommandRequiresProcess
+ ///
+ /// Ensures a valid process is contained in m_exe_ctx prior to executing the
+ /// command. If a process doesn't exist or is invalid, the command will fail
+ /// and CommandObject::GetInvalidProcessDescription() will be returned as
+ /// the error. CommandObject subclasses can override the virtual function
+ /// for GetInvalidProcessDescription() to provide custom strings when
+ /// needed.
eCommandRequiresProcess = (1u << 1),
- // eCommandRequiresThread
- //
- // Ensures a valid thread is contained in m_exe_ctx prior to executing the
- // command. If a thread doesn't exist or is invalid, the command will fail
- // and CommandObject::GetInvalidThreadDescription() will be returned as the
- // error. CommandObject subclasses can override the virtual function for
- // GetInvalidThreadDescription() to provide custom strings when needed.
+ /// eCommandRequiresThread
+ ///
+ /// Ensures a valid thread is contained in m_exe_ctx prior to executing the
+ /// command. If a thread doesn't exist or is invalid, the command will fail
+ /// and CommandObject::GetInvalidThreadDescription() will be returned as the
+ /// error. CommandObject subclasses can override the virtual function for
+ /// GetInvalidThreadDescription() to provide custom strings when needed.
eCommandRequiresThread = (1u << 2),
- // eCommandRequiresFrame
- //
- // Ensures a valid frame is contained in m_exe_ctx prior to executing the
- // command. If a frame doesn't exist or is invalid, the command will fail
- // and CommandObject::GetInvalidFrameDescription() will be returned as the
- // error. CommandObject subclasses can override the virtual function for
- // GetInvalidFrameDescription() to provide custom strings when needed.
+ /// eCommandRequiresFrame
+ ///
+ /// Ensures a valid frame is contained in m_exe_ctx prior to executing the
+ /// command. If a frame doesn't exist or is invalid, the command will fail
+ /// and CommandObject::GetInvalidFrameDescription() will be returned as the
+ /// error. CommandObject subclasses can override the virtual function for
+ /// GetInvalidFrameDescription() to provide custom strings when needed.
eCommandRequiresFrame = (1u << 3),
- // eCommandRequiresRegContext
- //
- // Ensures a valid register context (from the selected frame if there is a
- // frame in m_exe_ctx, or from the selected thread from m_exe_ctx) is
- // available from m_exe_ctx prior to executing the command. If a target
- // doesn't exist or is invalid, the command will fail and
- // CommandObject::GetInvalidRegContextDescription() will be returned as the
- // error. CommandObject subclasses can override the virtual function for
- // GetInvalidRegContextDescription() to provide custom strings when needed.
+ /// eCommandRequiresRegContext
+ ///
+ /// Ensures a valid register context (from the selected frame if there is a
+ /// frame in m_exe_ctx, or from the selected thread from m_exe_ctx) is
+ /// available from m_exe_ctx prior to executing the command. If a target
+ /// doesn't exist or is invalid, the command will fail and
+ /// CommandObject::GetInvalidRegContextDescription() will be returned as the
+ /// error. CommandObject subclasses can override the virtual function for
+ /// GetInvalidRegContextDescription() to provide custom strings when needed.
eCommandRequiresRegContext = (1u << 4),
- // eCommandTryTargetAPILock
- //
- // Attempts to acquire the target lock if a target is selected in the
- // command interpreter. If the command object fails to acquire the API
- // lock, the command will fail with an appropriate error message.
+ /// eCommandTryTargetAPILock
+ ///
+ /// Attempts to acquire the target lock if a target is selected in the
+ /// command interpreter. If the command object fails to acquire the API
+ /// lock, the command will fail with an appropriate error message.
eCommandTryTargetAPILock = (1u << 5),
- // eCommandProcessMustBeLaunched
- //
- // Verifies that there is a launched process in m_exe_ctx, if there isn't,
- // the command will fail with an appropriate error message.
+ /// eCommandProcessMustBeLaunched
+ ///
+ /// Verifies that there is a launched process in m_exe_ctx, if there isn't,
+ /// the command will fail with an appropriate error message.
eCommandProcessMustBeLaunched = (1u << 6),
- // eCommandProcessMustBePaused
- //
- // Verifies that there is a paused process in m_exe_ctx, if there isn't,
- // the command will fail with an appropriate error message.
+ /// eCommandProcessMustBePaused
+ ///
+ /// Verifies that there is a paused process in m_exe_ctx, if there isn't,
+ /// the command will fail with an appropriate error message.
eCommandProcessMustBePaused = (1u << 7)};
-// Whether a summary should cap how much data it returns to users or not
+/// Whether a summary should cap how much data it returns to users or not.
enum TypeSummaryCapping {
eTypeSummaryCapped = true,
eTypeSummaryUncapped = false
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index 0cdaf1cf9bf8..8315fbb27346 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -44,6 +44,7 @@ class BreakpointSiteList;
class BroadcastEventSpec;
class Broadcaster;
class BroadcasterManager;
+class CallFrameInfo;
class ClangASTContext;
class ClangASTImporter;
class ClangASTMetadata;
@@ -331,6 +332,7 @@ typedef std::shared_ptr<lldb_private::EventDataStructuredData>
typedef std::shared_ptr<lldb_private::ExecutionContextRef>
ExecutionContextRefSP;
typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP;
+typedef std::unique_ptr<lldb_private::File> FileUP;
typedef std::shared_ptr<lldb_private::File> FileSP;
typedef std::shared_ptr<lldb_private::Function> FunctionSP;
typedef std::shared_ptr<lldb_private::FunctionCaller> FunctionCallerSP;
diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h
index 3d8b360fb301..9b7879c05f9e 100644
--- a/include/lldb/lldb-private-enumerations.h
+++ b/include/lldb/lldb-private-enumerations.h
@@ -198,18 +198,24 @@ enum class LineStatus {
enum class TypeValidatorResult : bool { Success = true, Failure = false };
// Enumerations that can be used to specify scopes types when looking up types.
-enum class CompilerContextKind {
+enum class CompilerContextKind : uint16_t {
Invalid = 0,
- TranslationUnit,
- Module,
- Namespace,
- Class,
- Structure,
- Union,
- Function,
- Variable,
- Enumeration,
- Typedef
+ TranslationUnit = 1,
+ Module = 1 << 1,
+ Namespace = 1 << 2,
+ Class = 1 << 3,
+ Struct = 1 << 4,
+ Union = 1 << 5,
+ Function = 1 << 6,
+ Variable = 1 << 7,
+ Enum = 1 << 8,
+ Typedef = 1 << 9,
+
+ Any = 1 << 15,
+ /// Match 0..n nested modules.
+ AnyModule = Any | Module,
+ /// Match any type.
+ AnyType = Any | Class | Struct | Union | Enum | Typedef
};
// Enumerations that can be used to specify the kind of metric we're looking at
diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h
index 3a9f78aae0fe..04b78bcc19f8 100644
--- a/include/lldb/lldb-private-interfaces.h
+++ b/include/lldb/lldb-private-interfaces.h
@@ -70,7 +70,7 @@ typedef lldb::ProcessSP (*ProcessCreateInstance)(
const FileSpec *crash_file_path);
typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(
Debugger &debugger);
-typedef SymbolFile *(*SymbolFileCreateInstance)(ObjectFile *obj_file);
+typedef SymbolFile *(*SymbolFileCreateInstance)(lldb::ObjectFileSP objfile_sp);
typedef SymbolVendor *(*SymbolVendorCreateInstance)(
const lldb::ModuleSP &module_sp,
lldb_private::Stream
@@ -102,11 +102,6 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
lldb::LanguageType language,
Debugger *debugger, Target *target,
const char *repl_options);
-typedef void (*TypeSystemEnumerateSupportedLanguages)(
- std::set<lldb::LanguageType> &languages_for_types,
- std::set<lldb::LanguageType> &languages_for_expressions);
-typedef void (*REPLEnumerateSupportedLanguages)(
- std::set<lldb::LanguageType> &languages);
typedef int (*ComparisonFunction)(const void *, const void *);
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp
index 358cb400a76c..dcde25b77917 100644
--- a/source/API/SBAddress.cpp
+++ b/source/API/SBAddress.cpp
@@ -28,7 +28,7 @@ SBAddress::SBAddress() : m_opaque_up(new Address()) {
SBAddress::SBAddress(const Address *lldb_object_ptr)
: m_opaque_up(new Address()) {
if (lldb_object_ptr)
- m_opaque_up = llvm::make_unique<Address>(*lldb_object_ptr);
+ m_opaque_up = std::make_unique<Address>(*lldb_object_ptr);
}
SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) {
@@ -210,12 +210,6 @@ bool SBAddress::GetDescription(SBStream &description) {
if (m_opaque_up->IsValid()) {
m_opaque_up->Dump(&strm, nullptr, Address::DumpStyleResolvedDescription,
Address::DumpStyleModuleWithFileAddress, 4);
- StreamString sstrm;
- // m_opaque_up->Dump (&sstrm, NULL,
- // Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid,
- // 4);
- // if (sstrm.GetData())
- // strm.Printf (" (%s)", sstrm.GetData());
} else
strm.PutCString("No value");
diff --git a/source/API/SBBreakpointOptionCommon.cpp b/source/API/SBBreakpointOptionCommon.cpp
index 058b3e0398cd..870b4b941ada 100644
--- a/source/API/SBBreakpointOptionCommon.cpp
+++ b/source/API/SBBreakpointOptionCommon.cpp
@@ -41,7 +41,7 @@ using namespace lldb_private;
SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback
callback,
void *baton)
- : TypedBaton(llvm::make_unique<CallbackData>()) {
+ : TypedBaton(std::make_unique<CallbackData>()) {
getItem()->callback = callback;
getItem()->callback_baton = baton;
}
diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp
index c07dffce0baa..6e5ebe6a7ded 100644
--- a/source/API/SBCommandInterpreter.cpp
+++ b/source/API/SBCommandInterpreter.cpp
@@ -162,12 +162,11 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- SBCommandReturnObject sb_return(&result);
+ SBCommandReturnObject sb_return(result);
SBCommandInterpreter sb_interpreter(&m_interpreter);
SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
bool ret = m_backend->DoExecute(
debugger_sb, (char **)command.GetArgumentVector(), sb_return);
- sb_return.Release();
return ret;
}
std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
@@ -353,8 +352,6 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions(
current_line, cursor, last_char, match_start_point,
max_return_elements, matches, descriptions);
- int num_completions = 0;
-
// Sanity check the arguments that are passed in: cursor & last_char have to
// be within the current_line.
if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
@@ -368,20 +365,50 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions(
last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
return 0;
+ if (!IsValid())
+ return 0;
- if (IsValid()) {
- lldb_private::StringList lldb_matches, lldb_descriptions;
- num_completions = m_opaque_ptr->HandleCompletion(
- current_line, cursor, last_char, match_start_point, max_return_elements,
- lldb_matches, lldb_descriptions);
-
- SBStringList temp_matches_list(&lldb_matches);
- matches.AppendList(temp_matches_list);
- SBStringList temp_descriptions_list(&lldb_descriptions);
- descriptions.AppendList(temp_descriptions_list);
+ lldb_private::StringList lldb_matches, lldb_descriptions;
+ CompletionResult result;
+ CompletionRequest request(current_line, cursor - current_line, result);
+ m_opaque_ptr->HandleCompletion(request);
+ result.GetMatches(lldb_matches);
+ result.GetDescriptions(lldb_descriptions);
+
+ // Make the result array indexed from 1 again by adding the 'common prefix'
+ // of all completions as element 0. This is done to emulate the old API.
+ if (request.GetParsedLine().GetArgumentCount() == 0) {
+ // If we got an empty string, insert nothing.
+ lldb_matches.InsertStringAtIndex(0, "");
+ lldb_descriptions.InsertStringAtIndex(0, "");
+ } else {
+ // Now figure out if there is a common substring, and if so put that in
+ // element 0, otherwise put an empty string in element 0.
+ std::string command_partial_str = request.GetCursorArgumentPrefix().str();
+
+ std::string common_prefix = lldb_matches.LongestCommonPrefix();
+ const size_t partial_name_len = command_partial_str.size();
+ common_prefix.erase(0, partial_name_len);
+
+ // If we matched a unique single command, add a space... Only do this if
+ // the completer told us this was a complete word, however...
+ if (lldb_matches.GetSize() == 1) {
+ char quote_char = request.GetParsedArg().GetQuoteChar();
+ common_prefix =
+ Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
+ if (request.GetParsedArg().IsQuoted())
+ common_prefix.push_back(quote_char);
+ common_prefix.push_back(' ');
+ }
+ lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
+ lldb_descriptions.InsertStringAtIndex(0, "");
}
- return num_completions;
+ SBStringList temp_matches_list(&lldb_matches);
+ matches.AppendList(temp_matches_list);
+ SBStringList temp_descriptions_list(&lldb_descriptions);
+ descriptions.AppendList(temp_descriptions_list);
+ return result.GetNumberOfResults();
}
int SBCommandInterpreter::HandleCompletionWithDescriptions(
diff --git a/source/API/SBCommandReturnObject.cpp b/source/API/SBCommandReturnObject.cpp
index 94e89916f7f6..eec1383df875 100644
--- a/source/API/SBCommandReturnObject.cpp
+++ b/source/API/SBCommandReturnObject.cpp
@@ -10,6 +10,7 @@
#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/API/SBError.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBStream.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Utility/ConstString.h"
@@ -18,11 +19,43 @@
using namespace lldb;
using namespace lldb_private;
+class lldb_private::SBCommandReturnObjectImpl {
+public:
+ SBCommandReturnObjectImpl()
+ : m_ptr(new CommandReturnObject()), m_owned(true) {}
+ SBCommandReturnObjectImpl(CommandReturnObject &ref)
+ : m_ptr(&ref), m_owned(false) {}
+ SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs)
+ : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {}
+ SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) {
+ SBCommandReturnObjectImpl copy(rhs);
+ std::swap(*this, copy);
+ return *this;
+ }
+ // rvalue ctor+assignment are not used by SBCommandReturnObject.
+ ~SBCommandReturnObjectImpl() {
+ if (m_owned)
+ delete m_ptr;
+ }
+
+ CommandReturnObject &operator*() const { return *m_ptr; }
+
+private:
+ CommandReturnObject *m_ptr;
+ bool m_owned;
+};
+
SBCommandReturnObject::SBCommandReturnObject()
- : m_opaque_up(new CommandReturnObject()) {
+ : m_opaque_up(new SBCommandReturnObjectImpl()) {
LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject);
}
+SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref)
+ : m_opaque_up(new SBCommandReturnObjectImpl(ref)) {
+ LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject,
+ (lldb_private::CommandReturnObject &), ref);
+}
+
SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs)
: m_opaque_up() {
LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject,
@@ -31,25 +64,10 @@ SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs)
m_opaque_up = clone(rhs.m_opaque_up);
}
-SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject *ptr)
- : m_opaque_up(ptr) {
- LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject,
- (lldb_private::CommandReturnObject *), ptr);
-}
-
-SBCommandReturnObject::~SBCommandReturnObject() = default;
-
-CommandReturnObject *SBCommandReturnObject::Release() {
- LLDB_RECORD_METHOD_NO_ARGS(lldb_private::CommandReturnObject *,
- SBCommandReturnObject, Release);
-
- return LLDB_RECORD_RESULT(m_opaque_up.release());
-}
-
-const SBCommandReturnObject &SBCommandReturnObject::
+SBCommandReturnObject &SBCommandReturnObject::
operator=(const SBCommandReturnObject &rhs) {
LLDB_RECORD_METHOD(
- const lldb::SBCommandReturnObject &,
+ lldb::SBCommandReturnObject &,
SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &),
rhs);
@@ -58,6 +76,8 @@ operator=(const SBCommandReturnObject &rhs) {
return LLDB_RECORD_RESULT(*this);
}
+SBCommandReturnObject::~SBCommandReturnObject() = default;
+
bool SBCommandReturnObject::IsValid() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid);
return this->operator bool();
@@ -65,49 +85,38 @@ bool SBCommandReturnObject::IsValid() const {
SBCommandReturnObject::operator bool() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool);
- return m_opaque_up != nullptr;
+ // This method is not useful but it needs to stay to keep SB API stable.
+ return true;
}
const char *SBCommandReturnObject::GetOutput() {
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput);
- if (m_opaque_up) {
- llvm::StringRef output = m_opaque_up->GetOutputData();
- ConstString result(output.empty() ? llvm::StringRef("") : output);
-
- return result.AsCString();
- }
-
- return nullptr;
+ ConstString output(ref().GetOutputData());
+ return output.AsCString(/*value_if_empty*/ "");
}
const char *SBCommandReturnObject::GetError() {
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError);
- if (m_opaque_up) {
- llvm::StringRef output = m_opaque_up->GetErrorData();
- ConstString result(output.empty() ? llvm::StringRef("") : output);
- return result.AsCString();
- }
-
- return nullptr;
+ ConstString output(ref().GetErrorData());
+ return output.AsCString(/*value_if_empty*/ "");
}
size_t SBCommandReturnObject::GetOutputSize() {
LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize);
- return (m_opaque_up ? m_opaque_up->GetOutputData().size() : 0);
+ return ref().GetOutputData().size();
}
size_t SBCommandReturnObject::GetErrorSize() {
LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize);
- return (m_opaque_up ? m_opaque_up->GetErrorData().size() : 0);
+ return ref().GetErrorData().size();
}
size_t SBCommandReturnObject::PutOutput(FILE *fh) {
- LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh);
-
+ LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh);
if (fh) {
size_t num_bytes = GetOutputSize();
if (num_bytes)
@@ -116,9 +125,23 @@ size_t SBCommandReturnObject::PutOutput(FILE *fh) {
return 0;
}
-size_t SBCommandReturnObject::PutError(FILE *fh) {
- LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *), fh);
+size_t SBCommandReturnObject::PutOutput(FileSP file_sp) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP),
+ file_sp);
+ if (!file_sp)
+ return 0;
+ return file_sp->Printf("%s", GetOutput());
+}
+
+size_t SBCommandReturnObject::PutOutput(SBFile file) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile), file);
+ if (!file.m_opaque_sp)
+ return 0;
+ return file.m_opaque_sp->Printf("%s", GetOutput());
+}
+size_t SBCommandReturnObject::PutError(FILE *fh) {
+ LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutError, (FILE *), fh);
if (fh) {
size_t num_bytes = GetErrorSize();
if (num_bytes)
@@ -127,77 +150,81 @@ size_t SBCommandReturnObject::PutError(FILE *fh) {
return 0;
}
+size_t SBCommandReturnObject::PutError(FileSP file_sp) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP),
+ file_sp);
+ if (!file_sp)
+ return 0;
+ return file_sp->Printf("%s", GetError());
+}
+
+size_t SBCommandReturnObject::PutError(SBFile file) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile), file);
+ if (!file.m_opaque_sp)
+ return 0;
+ return file.m_opaque_sp->Printf("%s", GetError());
+}
+
void SBCommandReturnObject::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear);
- if (m_opaque_up)
- m_opaque_up->Clear();
+ ref().Clear();
}
lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject,
GetStatus);
- return (m_opaque_up ? m_opaque_up->GetStatus() : lldb::eReturnStatusInvalid);
+ return ref().GetStatus();
}
void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus,
(lldb::ReturnStatus), status);
- if (m_opaque_up)
- m_opaque_up->SetStatus(status);
+ ref().SetStatus(status);
}
bool SBCommandReturnObject::Succeeded() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded);
- return (m_opaque_up ? m_opaque_up->Succeeded() : false);
+ return ref().Succeeded();
}
bool SBCommandReturnObject::HasResult() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult);
- return (m_opaque_up ? m_opaque_up->HasResult() : false);
+ return ref().HasResult();
}
void SBCommandReturnObject::AppendMessage(const char *message) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *),
message);
- if (m_opaque_up)
- m_opaque_up->AppendMessage(message);
+ ref().AppendMessage(message);
}
void SBCommandReturnObject::AppendWarning(const char *message) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *),
message);
- if (m_opaque_up)
- m_opaque_up->AppendWarning(message);
+ ref().AppendWarning(message);
}
CommandReturnObject *SBCommandReturnObject::operator->() const {
- return m_opaque_up.get();
+ return &**m_opaque_up;
}
CommandReturnObject *SBCommandReturnObject::get() const {
- return m_opaque_up.get();
+ return &**m_opaque_up;
}
CommandReturnObject &SBCommandReturnObject::operator*() const {
- assert(m_opaque_up.get());
- return *(m_opaque_up.get());
+ return **m_opaque_up;
}
CommandReturnObject &SBCommandReturnObject::ref() const {
- assert(m_opaque_up.get());
- return *(m_opaque_up.get());
-}
-
-void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) {
- if (m_opaque_up)
- m_opaque_up.reset(ptr);
+ return **m_opaque_up;
}
bool SBCommandReturnObject::GetDescription(SBStream &description) {
@@ -206,84 +233,99 @@ bool SBCommandReturnObject::GetDescription(SBStream &description) {
Stream &strm = description.ref();
- if (m_opaque_up) {
- description.Printf("Error: ");
- lldb::ReturnStatus status = m_opaque_up->GetStatus();
- if (status == lldb::eReturnStatusStarted)
- strm.PutCString("Started");
- else if (status == lldb::eReturnStatusInvalid)
- strm.PutCString("Invalid");
- else if (m_opaque_up->Succeeded())
- strm.PutCString("Success");
- else
- strm.PutCString("Fail");
-
- if (GetOutputSize() > 0)
- strm.Printf("\nOutput Message:\n%s", GetOutput());
-
- if (GetErrorSize() > 0)
- strm.Printf("\nError Message:\n%s", GetError());
- } else
- strm.PutCString("No value");
+ description.Printf("Error: ");
+ lldb::ReturnStatus status = ref().GetStatus();
+ if (status == lldb::eReturnStatusStarted)
+ strm.PutCString("Started");
+ else if (status == lldb::eReturnStatusInvalid)
+ strm.PutCString("Invalid");
+ else if (ref().Succeeded())
+ strm.PutCString("Success");
+ else
+ strm.PutCString("Fail");
+
+ if (GetOutputSize() > 0)
+ strm.Printf("\nOutput Message:\n%s", GetOutput());
+
+ if (GetErrorSize() > 0)
+ strm.Printf("\nError Message:\n%s", GetError());
return true;
}
void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
- LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
- (FILE *), fh);
+ LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FILE *), fh);
SetImmediateOutputFile(fh, false);
}
void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
- LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
- (FILE *), fh);
+ LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FILE *), fh);
SetImmediateErrorFile(fh, false);
}
void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
bool transfer_ownership) {
- LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
- (FILE *, bool), fh, transfer_ownership);
-
- if (m_opaque_up)
- m_opaque_up->SetImmediateOutputFile(fh, transfer_ownership);
+ LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FILE *, bool), fh, transfer_ownership);
+ FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
+ ref().SetImmediateOutputFile(file);
}
void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
bool transfer_ownership) {
+ LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FILE *, bool), fh, transfer_ownership);
+ FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
+ ref().SetImmediateErrorFile(file);
+}
+
+void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (SBFile), file);
+ ref().SetImmediateOutputFile(file.m_opaque_sp);
+}
+
+void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
- (FILE *, bool), fh, transfer_ownership);
+ (SBFile), file);
+ ref().SetImmediateErrorFile(file.m_opaque_sp);
+}
- if (m_opaque_up)
- m_opaque_up->SetImmediateErrorFile(fh, transfer_ownership);
+void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FileSP), file_sp);
+ SetImmediateOutputFile(SBFile(file_sp));
+}
+
+void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FileSP), file_sp);
+ SetImmediateErrorFile(SBFile(file_sp));
}
void SBCommandReturnObject::PutCString(const char *string, int len) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString,
(const char *, int), string, len);
- if (m_opaque_up) {
- if (len == 0 || string == nullptr || *string == 0) {
- return;
- } else if (len > 0) {
- std::string buffer(string, len);
- m_opaque_up->AppendMessage(buffer.c_str());
- } else
- m_opaque_up->AppendMessage(string);
- }
+ if (len == 0 || string == nullptr || *string == 0) {
+ return;
+ } else if (len > 0) {
+ std::string buffer(string, len);
+ ref().AppendMessage(buffer.c_str());
+ } else
+ ref().AppendMessage(string);
}
const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) {
LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool),
only_if_no_immediate);
- if (!m_opaque_up)
- return nullptr;
if (!only_if_no_immediate ||
- m_opaque_up->GetImmediateOutputStream().get() == nullptr)
+ ref().GetImmediateOutputStream().get() == nullptr)
return GetOutput();
return nullptr;
}
@@ -292,23 +334,17 @@ const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) {
LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool),
only_if_no_immediate);
- if (!m_opaque_up)
- return nullptr;
- if (!only_if_no_immediate ||
- m_opaque_up->GetImmediateErrorStream().get() == nullptr)
+ if (!only_if_no_immediate || ref().GetImmediateErrorStream().get() == nullptr)
return GetError();
return nullptr;
}
size_t SBCommandReturnObject::Printf(const char *format, ...) {
- if (m_opaque_up) {
- va_list args;
- va_start(args, format);
- size_t result = m_opaque_up->GetOutputStream().PrintfVarArg(format, args);
- va_end(args);
- return result;
- }
- return 0;
+ va_list args;
+ va_start(args, format);
+ size_t result = ref().GetOutputStream().PrintfVarArg(format, args);
+ va_end(args);
+ return result;
}
void SBCommandReturnObject::SetError(lldb::SBError &error,
@@ -317,20 +353,18 @@ void SBCommandReturnObject::SetError(lldb::SBError &error,
(lldb::SBError &, const char *), error,
fallback_error_cstr);
- if (m_opaque_up) {
- if (error.IsValid())
- m_opaque_up->SetError(error.ref(), fallback_error_cstr);
- else if (fallback_error_cstr)
- m_opaque_up->SetError(Status(), fallback_error_cstr);
- }
+ if (error.IsValid())
+ ref().SetError(error.ref(), fallback_error_cstr);
+ else if (fallback_error_cstr)
+ ref().SetError(Status(), fallback_error_cstr);
}
void SBCommandReturnObject::SetError(const char *error_cstr) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *),
error_cstr);
- if (m_opaque_up && error_cstr)
- m_opaque_up->SetError(error_cstr);
+ if (error_cstr)
+ ref().SetError(error_cstr);
}
namespace lldb_private {
@@ -340,13 +374,11 @@ template <>
void RegisterMethods<SBCommandReturnObject>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ());
LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject,
- (const lldb::SBCommandReturnObject &));
+ (lldb_private::CommandReturnObject &));
LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject,
- (lldb_private::CommandReturnObject *));
- LLDB_REGISTER_METHOD(lldb_private::CommandReturnObject *,
- SBCommandReturnObject, Release, ());
+ (const lldb::SBCommandReturnObject &));
LLDB_REGISTER_METHOD(
- const lldb::SBCommandReturnObject &,
+ lldb::SBCommandReturnObject &,
SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &));
LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ());
LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ());
@@ -356,6 +388,10 @@ void RegisterMethods<SBCommandReturnObject>(Registry &R) {
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ());
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *));
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ());
LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus,
());
@@ -374,6 +410,14 @@ void RegisterMethods<SBCommandReturnObject>(Registry &R) {
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
(FILE *));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (SBFile));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (SBFile));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FileSP));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FileSP));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
(FILE *, bool));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
(FILE *, bool));
diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp
index c9ca70645d95..581bda363507 100644
--- a/source/API/SBCompileUnit.cpp
+++ b/source/API/SBCompileUnit.cpp
@@ -14,8 +14,9 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/LineTable.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
using namespace lldb;
using namespace lldb_private;
@@ -137,13 +138,13 @@ lldb::SBTypeList SBCompileUnit::GetTypes(uint32_t type_mask) {
if (!module_sp)
return LLDB_RECORD_RESULT(sb_type_list);
- SymbolVendor *vendor = module_sp->GetSymbolVendor();
- if (!vendor)
+ SymbolFile *symfile = module_sp->GetSymbolFile();
+ if (!symfile)
return LLDB_RECORD_RESULT(sb_type_list);
TypeClass type_class = static_cast<TypeClass>(type_mask);
TypeList type_list;
- vendor->GetTypes(m_opaque_ptr, type_class, type_list);
+ symfile->GetTypes(m_opaque_ptr, type_class, type_list);
sb_type_list.m_opaque_up->Append(type_list);
return LLDB_RECORD_RESULT(sb_type_list);
}
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index 634c4a929595..82dc60489008 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -18,6 +18,7 @@
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBProcess.h"
@@ -57,51 +58,6 @@
using namespace lldb;
using namespace lldb_private;
-/// Helper class for replaying commands through the reproducer.
-class CommandLoader {
-public:
- CommandLoader(std::vector<std::string> files) : m_files(files) {}
-
- static std::unique_ptr<CommandLoader> Create() {
- repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
- if (!loader)
- return {};
-
- FileSpec file = loader->GetFile<repro::CommandProvider::Info>();
- if (!file)
- return {};
-
- auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
- if (auto err = error_or_file.getError())
- return {};
-
- std::vector<std::string> files;
- llvm::yaml::Input yin((*error_or_file)->getBuffer());
- yin >> files;
-
- if (auto err = yin.error())
- return {};
-
- for (auto &file : files) {
- FileSpec absolute_path =
- loader->GetRoot().CopyByAppendingPathComponent(file);
- file = absolute_path.GetPath();
- }
-
- return llvm::make_unique<CommandLoader>(std::move(files));
- }
-
- FILE *GetNextFile() {
- if (m_index >= m_files.size())
- return nullptr;
- return FileSystem::Instance().Fopen(m_files[m_index++].c_str(), "r");
- }
-
-private:
- std::vector<std::string> m_files;
- unsigned m_index = 0;
-};
-
static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp,
const FileSpec &spec,
Status &error) {
@@ -200,11 +156,9 @@ lldb::SBError SBDebugger::InitializeWithErrorHandling() {
LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger,
InitializeWithErrorHandling);
-
-
SBError error;
if (auto e = g_debugger_lifetime->Initialize(
- llvm::make_unique<SystemInitializerFull>(), LoadPlugin)) {
+ std::make_unique<SystemInitializerFull>(), LoadPlugin)) {
error.SetError(Status(std::move(e)));
}
return LLDB_RECORD_RESULT(error);
@@ -219,7 +173,6 @@ void SBDebugger::Terminate() {
void SBDebugger::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear);
-
if (m_opaque_sp)
m_opaque_sp->ClearIOHandlers();
@@ -260,7 +213,6 @@ SBDebugger SBDebugger::Create(bool source_init_files,
debugger.reset(Debugger::CreateInstance(callback, baton));
-
SBCommandInterpreter interp = debugger.GetCommandInterpreter();
if (source_init_files) {
interp.get()->SkipLLDBInitFiles(false);
@@ -278,7 +230,6 @@ void SBDebugger::Destroy(SBDebugger &debugger) {
LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &),
debugger);
-
Debugger::Destroy(debugger.m_opaque_sp);
if (debugger.m_opaque_sp.get() != nullptr)
@@ -335,86 +286,173 @@ void SBDebugger::SkipAppInitFiles(bool b) {
m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b);
}
-// Shouldn't really be settable after initialization as this could cause lots
-// of problems; don't want users trying to switch modes in the middle of a
-// debugging session.
void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh,
transfer_ownership);
+ SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+}
- if (!m_opaque_sp)
- return;
+SBError SBDebugger::SetInputFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp);
+ return SetInputFile(SBFile(file_sp));
+}
+
+// Shouldn't really be settable after initialization as this could cause lots
+// of problems; don't want users trying to switch modes in the middle of a
+// debugging session.
+SBError SBDebugger::SetInputFile(SBFile file) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (SBFile), file);
+
+ SBError error;
+ if (!m_opaque_sp) {
+ error.ref().SetErrorString("invalid debugger");
+ return error;
+ }
repro::DataRecorder *recorder = nullptr;
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator())
recorder = g->GetOrCreate<repro::CommandProvider>().GetNewDataRecorder();
- static std::unique_ptr<CommandLoader> loader = CommandLoader::Create();
- if (loader)
- fh = loader->GetNextFile();
+ FileSP file_sp = file.m_opaque_sp;
+
+ static std::unique_ptr<repro::CommandLoader> loader =
+ repro::CommandLoader::Create(repro::Reproducer::Instance().GetLoader());
+ if (loader) {
+ llvm::Optional<std::string> nextfile = loader->GetNextFile();
+ FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
+ : nullptr;
+ // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the
+ // reproducer somehow if fh is NULL?
+ if (fh) {
+ file_sp = std::make_shared<NativeFile>(fh, true);
+ }
+ }
+
+ if (!file_sp || !file_sp->IsValid()) {
+ error.ref().SetErrorString("invalid file");
+ return error;
+ }
+
+ m_opaque_sp->SetInputFile(file_sp, recorder);
+ return error;
+}
- m_opaque_sp->SetInputFileHandle(fh, transfer_ownership, recorder);
+SBError SBDebugger::SetOutputFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp);
+ return SetOutputFile(SBFile(file_sp));
}
void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh,
transfer_ownership);
+ SetOutputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+}
- if (m_opaque_sp)
- m_opaque_sp->SetOutputFileHandle(fh, transfer_ownership);
+SBError SBDebugger::SetOutputFile(SBFile file) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (SBFile file), file);
+ SBError error;
+ if (!m_opaque_sp) {
+ error.ref().SetErrorString("invalid debugger");
+ return error;
+ }
+ if (!file) {
+ error.ref().SetErrorString("invalid file");
+ return error;
+ }
+ m_opaque_sp->SetOutputFile(file.m_opaque_sp);
+ return error;
}
void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh,
transfer_ownership);
+ SetErrorFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+}
+SBError SBDebugger::SetErrorFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (FileSP), file_sp);
+ return SetErrorFile(SBFile(file_sp));
+}
- if (m_opaque_sp)
- m_opaque_sp->SetErrorFileHandle(fh, transfer_ownership);
+SBError SBDebugger::SetErrorFile(SBFile file) {
+ LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (SBFile file), file);
+ SBError error;
+ if (!m_opaque_sp) {
+ error.ref().SetErrorString("invalid debugger");
+ return error;
+ }
+ if (!file) {
+ error.ref().SetErrorString("invalid file");
+ return error;
+ }
+ m_opaque_sp->SetErrorFile(file.m_opaque_sp);
+ return error;
}
FILE *SBDebugger::GetInputFileHandle() {
LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle);
-
if (m_opaque_sp) {
- StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile());
- if (stream_file_sp)
- return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream());
+ File &file_sp = m_opaque_sp->GetInputFile();
+ return LLDB_RECORD_RESULT(file_sp.GetStream());
}
return nullptr;
}
+SBFile SBDebugger::GetInputFile() {
+ LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetInputFile);
+ if (m_opaque_sp) {
+ return LLDB_RECORD_RESULT(SBFile(m_opaque_sp->GetInputFileSP()));
+ }
+ return LLDB_RECORD_RESULT(SBFile());
+}
+
FILE *SBDebugger::GetOutputFileHandle() {
LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle);
-
if (m_opaque_sp) {
- StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile());
- if (stream_file_sp)
- return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream());
+ StreamFile &stream_file = m_opaque_sp->GetOutputStream();
+ return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
}
return nullptr;
}
+SBFile SBDebugger::GetOutputFile() {
+ LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetOutputFile);
+ if (m_opaque_sp) {
+ SBFile file(m_opaque_sp->GetOutputStream().GetFileSP());
+ return LLDB_RECORD_RESULT(file);
+ }
+ return LLDB_RECORD_RESULT(SBFile());
+}
+
FILE *SBDebugger::GetErrorFileHandle() {
LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle);
if (m_opaque_sp) {
- StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile());
- if (stream_file_sp)
- return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream());
+ StreamFile &stream_file = m_opaque_sp->GetErrorStream();
+ return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
}
return nullptr;
}
+SBFile SBDebugger::GetErrorFile() {
+ LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetErrorFile);
+ SBFile file;
+ if (m_opaque_sp) {
+ SBFile file(m_opaque_sp->GetErrorStream().GetFileSP());
+ return LLDB_RECORD_RESULT(file);
+ }
+ return LLDB_RECORD_RESULT(SBFile());
+}
+
void SBDebugger::SaveInputTerminalState() {
- LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, SaveInputTerminalState);
+ LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, SaveInputTerminalState);
if (m_opaque_sp)
m_opaque_sp->SaveInputTerminalState();
}
void SBDebugger::RestoreInputTerminalState() {
- LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, RestoreInputTerminalState);
+ LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, RestoreInputTerminalState);
if (m_opaque_sp)
m_opaque_sp->RestoreInputTerminalState();
@@ -423,12 +461,10 @@ SBCommandInterpreter SBDebugger::GetCommandInterpreter() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger,
GetCommandInterpreter);
-
SBCommandInterpreter sb_interpreter;
if (m_opaque_sp)
sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter());
-
return LLDB_RECORD_RESULT(sb_interpreter);
}
@@ -446,10 +482,8 @@ void SBDebugger::HandleCommand(const char *command) {
sb_interpreter.HandleCommand(command, result, false);
- if (GetErrorFileHandle() != nullptr)
- result.PutError(GetErrorFileHandle());
- if (GetOutputFileHandle() != nullptr)
- result.PutOutput(GetOutputFileHandle());
+ result.PutError(m_opaque_sp->GetErrorStream().GetFileSP());
+ result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP());
if (!m_opaque_sp->GetAsyncExecution()) {
SBProcess process(GetCommandInterpreter().GetProcess());
@@ -460,8 +494,7 @@ void SBDebugger::HandleCommand(const char *command) {
while (lldb_listener_sp->GetEventForBroadcaster(
process_sp.get(), event_sp, std::chrono::seconds(0))) {
SBEvent event(event_sp);
- HandleProcessEvent(process, event, GetOutputFileHandle(),
- GetErrorFileHandle());
+ HandleProcessEvent(process, event, GetOutputFile(), GetErrorFile());
}
}
}
@@ -471,16 +504,25 @@ void SBDebugger::HandleCommand(const char *command) {
SBListener SBDebugger::GetListener() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener);
-
SBListener sb_listener;
if (m_opaque_sp)
sb_listener.reset(m_opaque_sp->GetListener());
-
return LLDB_RECORD_RESULT(sb_listener);
}
void SBDebugger::HandleProcessEvent(const SBProcess &process,
+ const SBEvent &event, SBFile out,
+ SBFile err) {
+ LLDB_RECORD_METHOD(
+ void, SBDebugger, HandleProcessEvent,
+ (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile), process,
+ event, out, err);
+
+ return HandleProcessEvent(process, event, out.m_opaque_sp, err.m_opaque_sp);
+}
+
+void SBDebugger::HandleProcessEvent(const SBProcess &process,
const SBEvent &event, FILE *out,
FILE *err) {
LLDB_RECORD_METHOD(
@@ -488,6 +530,20 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process,
(const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process,
event, out, err);
+ FileSP outfile = std::make_shared<NativeFile>(out, false);
+ FileSP errfile = std::make_shared<NativeFile>(err, false);
+ return HandleProcessEvent(process, event, outfile, errfile);
+}
+
+void SBDebugger::HandleProcessEvent(const SBProcess &process,
+ const SBEvent &event, FileSP out_sp,
+ FileSP err_sp) {
+
+ LLDB_RECORD_METHOD(
+ void, SBDebugger, HandleProcessEvent,
+ (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP), process,
+ event, out_sp, err_sp);
+
if (!process.IsValid())
return;
@@ -505,16 +561,16 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process,
(Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) {
// Drain stdout when we stop just in case we have any bytes
while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0)
- if (out != nullptr)
- ::fwrite(stdio_buffer, 1, len, out);
+ if (out_sp)
+ out_sp->Write(stdio_buffer, len);
}
if (event_type &
(Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) {
// Drain stderr when we stop just in case we have any bytes
while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0)
- if (err != nullptr)
- ::fwrite(stdio_buffer, 1, len, err);
+ if (err_sp)
+ err_sp->Write(stdio_buffer, len);
}
if (event_type & Process::eBroadcastBitStateChanged) {
@@ -525,7 +581,7 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process,
bool is_stopped = StateIsStoppedState(event_state);
if (!is_stopped)
- process.ReportEventState(event, out);
+ process.ReportEventState(event, out_sp);
}
}
@@ -578,7 +634,8 @@ SBDebugger::GetScriptingLanguage(const char *script_language_name) {
LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
(const char *), script_language_name);
- if (!script_language_name) return eScriptLanguageDefault;
+ if (!script_language_name)
+ return eScriptLanguageDefault;
return OptionArgParser::ToScriptLanguage(
llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr);
}
@@ -599,18 +656,18 @@ const char *SBDebugger::StateAsCString(StateType state) {
static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
llvm::StringRef name, bool value,
llvm::StringRef description) {
- auto entry_up = llvm::make_unique<StructuredData::Dictionary>();
+ auto entry_up = std::make_unique<StructuredData::Dictionary>();
entry_up->AddBooleanItem("value", value);
entry_up->AddStringItem("description", description);
dict.AddItem(name, std::move(entry_up));
}
static void AddLLVMTargets(StructuredData::Dictionary &dict) {
- auto array_up = llvm::make_unique<StructuredData::Array>();
+ auto array_up = std::make_unique<StructuredData::Array>();
#define LLVM_TARGET(target) \
- array_up->AddItem(llvm::make_unique<StructuredData::String>(#target));
+ array_up->AddItem(std::make_unique<StructuredData::String>(#target));
#include "llvm/Config/Targets.def"
- auto entry_up = llvm::make_unique<StructuredData::Dictionary>();
+ auto entry_up = std::make_unique<StructuredData::Dictionary>();
entry_up->AddItem("value", std::move(array_up));
entry_up->AddStringItem("description", "A list of configured LLVM targets.");
dict.AddItem("targets", std::move(entry_up));
@@ -620,10 +677,17 @@ SBStructuredData SBDebugger::GetBuildConfiguration() {
LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger,
GetBuildConfiguration);
- auto config_up = llvm::make_unique<StructuredData::Dictionary>();
+ auto config_up = std::make_unique<StructuredData::Dictionary>();
AddBoolConfigEntry(
*config_up, "xml", XMLDocument::XMLEnabled(),
"A boolean value that indicates if XML support is enabled in LLDB");
+ bool have_curses = true;
+#ifdef LLDB_DISABLE_CURSES
+ have_curses = false;
+#endif
+ AddBoolConfigEntry(
+ *config_up, "curses", have_curses,
+ "A boolean value that indicates if curses support is enabled in LLDB");
AddLLVMTargets(*config_up);
SBStructuredData data;
@@ -635,7 +699,6 @@ bool SBDebugger::StateIsRunningState(StateType state) {
LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState,
(lldb::StateType), state);
-
const bool result = lldb_private::StateIsRunningState(state);
return result;
@@ -645,7 +708,6 @@ bool SBDebugger::StateIsStoppedState(StateType state) {
LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState,
(lldb::StateType), state);
-
const bool result = lldb_private::StateIsStoppedState(state, false);
return result;
@@ -680,13 +742,13 @@ lldb::SBTarget SBDebugger::CreateTarget(const char *filename,
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, "
- "platform_name=%s, add_dependent_modules=%u, error=%s) => "
- "SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
- platform_name, add_dependent_modules, sb_error.GetCString(),
- static_cast<void *>(target_sp.get()));
+ LLDB_LOGF(log,
+ "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, "
+ "platform_name=%s, add_dependent_modules=%u, error=%s) => "
+ "SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+ platform_name, add_dependent_modules, sb_error.GetCString(),
+ static_cast<void *>(target_sp.get()));
return LLDB_RECORD_RESULT(sb_target);
}
@@ -710,11 +772,11 @@ SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename,
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple "
- "(filename=\"%s\", triple=%s) => SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
- static_cast<void *>(target_sp.get()));
+ LLDB_LOGF(log,
+ "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple "
+ "(filename=\"%s\", triple=%s) => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+ static_cast<void *>(target_sp.get()));
return LLDB_RECORD_RESULT(sb_target);
}
@@ -743,11 +805,11 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
}
}
- if (log)
- log->Printf("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
- "arch=%s) => SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr,
- static_cast<void *>(target_sp.get()));
+ LLDB_LOGF(log,
+ "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
+ "arch=%s) => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr,
+ static_cast<void *>(target_sp.get()));
return LLDB_RECORD_RESULT(sb_target);
}
@@ -772,11 +834,10 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
}
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf(
- "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()), filename,
- static_cast<void *>(target_sp.get()));
+ LLDB_LOGF(log,
+ "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()), filename,
+ static_cast<void *>(target_sp.get()));
return LLDB_RECORD_RESULT(sb_target);
}
@@ -785,14 +846,12 @@ SBTarget SBDebugger::GetDummyTarget() {
SBTarget sb_target;
if (m_opaque_sp) {
- sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
+ sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf(
- "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(sb_target.GetSP().get()));
+ LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(sb_target.GetSP().get()));
return LLDB_RECORD_RESULT(sb_target);
}
@@ -814,10 +873,9 @@ bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(target.m_opaque_sp.get()), result);
+ LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(target.m_opaque_sp.get()), result);
return result;
}
@@ -914,9 +972,9 @@ SBTarget SBDebugger::GetSelectedTarget() {
if (log) {
SBStream sstr;
sb_target.GetDescription(sstr, eDescriptionLevelBrief);
- log->Printf("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(target_sp.get()), sstr.GetData());
+ LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(target_sp.get()), sstr.GetData());
}
return LLDB_RECORD_RESULT(sb_target);
@@ -935,9 +993,9 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
if (log) {
SBStream sstr;
sb_target.GetDescription(sstr, eDescriptionLevelBrief);
- log->Printf("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(target_sp.get()), sstr.GetData());
+ LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(target_sp.get()), sstr.GetData());
}
}
@@ -951,11 +1009,10 @@ SBPlatform SBDebugger::GetSelectedPlatform() {
if (debugger_sp) {
sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
}
- if (log)
- log->Printf("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(sb_platform.GetSP().get()),
- sb_platform.GetName());
+ LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(sb_platform.GetSP().get()),
+ sb_platform.GetName());
return LLDB_RECORD_RESULT(sb_platform);
}
@@ -970,11 +1027,10 @@ void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) {
debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
}
- if (log)
- log->Printf("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
- static_cast<void *>(m_opaque_sp.get()),
- static_cast<void *>(sb_platform.GetSP().get()),
- sb_platform.GetName());
+ LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
+ static_cast<void *>(m_opaque_sp.get()),
+ static_cast<void *>(sb_platform.GetSP().get()),
+ sb_platform.GetName());
}
uint32_t SBDebugger::GetNumPlatforms() {
@@ -1018,7 +1074,7 @@ SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) {
GetAvailablePlatformInfoAtIndex, (uint32_t), idx);
SBStructuredData data;
- auto platform_dict = llvm::make_unique<StructuredData::Dictionary>();
+ auto platform_dict = std::make_unique<StructuredData::Dictionary>();
llvm::StringRef name_str("name"), desc_str("description");
if (idx == 0) {
@@ -1062,7 +1118,7 @@ void SBDebugger::DispatchInput(const void *data, size_t data_len) {
// Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
//
// if (log)
- // log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\",
+ // LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\",
// size_t=%" PRIu64 ")",
// m_opaque_sp.get(),
// (int) data_len,
@@ -1074,7 +1130,7 @@ void SBDebugger::DispatchInput(const void *data, size_t data_len) {
}
void SBDebugger::DispatchInputInterrupt() {
- LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputInterrupt);
+ LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, DispatchInputInterrupt);
if (m_opaque_sp)
m_opaque_sp->DispatchInputInterrupt();
@@ -1234,8 +1290,7 @@ uint32_t SBDebugger::GetTerminalWidth() const {
}
void SBDebugger::SetTerminalWidth(uint32_t term_width) {
- LLDB_RECORD_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t),
- term_width);
+ LLDB_RECORD_DUMMY(void, SBDebugger, SetTerminalWidth, (uint32_t), term_width);
if (m_opaque_sp)
m_opaque_sp->SetTerminalWidth(term_width);
@@ -1246,10 +1301,9 @@ const char *SBDebugger::GetPrompt() const {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
- if (log)
- log->Printf("SBDebugger(%p)::GetPrompt () => \"%s\"",
- static_cast<void *>(m_opaque_sp.get()),
- (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : ""));
+ LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"",
+ static_cast<void *>(m_opaque_sp.get()),
+ (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : ""));
return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString()
: nullptr);
@@ -1374,7 +1428,8 @@ bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) {
if (platform_sp) {
if (log && sysroot)
- log->Printf("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot);
+ LLDB_LOGF(log, "SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")",
+ sysroot);
platform_sp->SetSDKRootDirectory(ConstString(sysroot));
return true;
}
@@ -1549,8 +1604,7 @@ void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
namespace lldb_private {
namespace repro {
-template <>
-void RegisterMethods<SBInputReader>(Registry &R) {
+template <> void RegisterMethods<SBInputReader>(Registry &R) {
LLDB_REGISTER_METHOD(void, SBInputReader, SetIsDone, (bool));
LLDB_REGISTER_METHOD_CONST(bool, SBInputReader, IsActive, ());
}
@@ -1559,6 +1613,10 @@ static void SetFileHandleRedirect(SBDebugger *, FILE *, bool) {
// Do nothing.
}
+static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); }
+
+static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); }
+
static bool GetDefaultArchitectureRedirect(char *arch_name,
size_t arch_name_len) {
// The function is writing to its argument. Without the redirect it would
@@ -1567,8 +1625,7 @@ static bool GetDefaultArchitectureRedirect(char *arch_name,
return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len);
}
-template <>
-void RegisterMethods<SBDebugger>(Registry &R) {
+template <> void RegisterMethods<SBDebugger>(Registry &R) {
// Custom implementation.
R.Register(&invoke<void (SBDebugger::*)(
FILE *, bool)>::method<&SBDebugger::SetErrorFileHandle>::doit,
@@ -1580,6 +1637,26 @@ void RegisterMethods<SBDebugger>(Registry &R) {
&SBDebugger::GetDefaultArchitecture),
&GetDefaultArchitectureRedirect);
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ SBFile)>::method<&SBDebugger::SetInputFile>::doit,
+ &SetFileRedirect);
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ SBFile)>::method<&SBDebugger::SetOutputFile>::doit,
+ &SetFileRedirect);
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ SBFile)>::method<&SBDebugger::SetErrorFile>::doit,
+ &SetFileRedirect);
+
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ FileSP)>::method<&SBDebugger::SetInputFile>::doit,
+ &SetFileRedirect);
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ FileSP)>::method<&SBDebugger::SetOutputFile>::doit,
+ &SetFileRedirect);
+ R.Register(&invoke<SBError (SBDebugger::*)(
+ FileSP)>::method<&SBDebugger::SetErrorFile>::doit,
+ &SetFileRedirect);
+
LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ());
LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &));
LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &));
@@ -1592,11 +1669,10 @@ void RegisterMethods<SBDebugger>(Registry &R) {
LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ());
LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ());
LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool));
- LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy,
- (lldb::SBDebugger &));
+ LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &));
LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ());
LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ());
- LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool,());
LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool));
LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ());
LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool));
@@ -1605,6 +1681,9 @@ void RegisterMethods<SBDebugger>(Registry &R) {
LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ());
LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ());
LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetErrorFileHandle, ());
+ LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetInputFile, ());
+ LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetOutputFile, ());
+ LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetErrorFile, ());
LLDB_REGISTER_METHOD(void, SBDebugger, SaveInputTerminalState, ());
LLDB_REGISTER_METHOD(void, SBDebugger, RestoreInputTerminalState, ());
LLDB_REGISTER_METHOD(lldb::SBCommandInterpreter, SBDebugger,
@@ -1614,8 +1693,13 @@ void RegisterMethods<SBDebugger>(Registry &R) {
LLDB_REGISTER_METHOD(
void, SBDebugger, HandleProcessEvent,
(const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *));
- LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager,
- ());
+ LLDB_REGISTER_METHOD(
+ void, SBDebugger, HandleProcessEvent,
+ (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile));
+ LLDB_REGISTER_METHOD(
+ void, SBDebugger, HandleProcessEvent,
+ (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP));
+ LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, ());
LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture,
(const char *));
LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
@@ -1635,8 +1719,7 @@ void RegisterMethods<SBDebugger>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger,
CreateTargetWithFileAndTargetTriple,
(const char *, const char *));
- LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger,
- CreateTargetWithFileAndArch,
+ LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch,
(const char *, const char *));
LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTarget,
(const char *));
@@ -1652,8 +1735,7 @@ void RegisterMethods<SBDebugger>(Registry &R) {
(const char *, const char *));
LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumTargets, ());
LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetSelectedTarget, ());
- LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget,
- (lldb::SBTarget &));
+ LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &));
LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetSelectedPlatform, ());
LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedPlatform,
(lldb::SBPlatform &));
@@ -1673,8 +1755,8 @@ void RegisterMethods<SBDebugger>(Registry &R) {
int &, bool &, bool &));
LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, RunREPL,
(lldb::LanguageType, const char *));
- LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger,
- FindDebuggerWithID, (int));
+ LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID,
+ (int));
LLDB_REGISTER_METHOD(const char *, SBDebugger, GetInstanceName, ());
LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable,
(const char *, const char *, const char *));
@@ -1726,5 +1808,5 @@ void RegisterMethods<SBDebugger>(Registry &R) {
(const char *, const char **));
}
-}
-}
+} // namespace repro
+} // namespace lldb_private
diff --git a/source/API/SBDeclaration.cpp b/source/API/SBDeclaration.cpp
index a7790b293981..50db1770c612 100644
--- a/source/API/SBDeclaration.cpp
+++ b/source/API/SBDeclaration.cpp
@@ -32,7 +32,7 @@ SBDeclaration::SBDeclaration(const SBDeclaration &rhs) : m_opaque_up() {
SBDeclaration::SBDeclaration(const lldb_private::Declaration *lldb_object_ptr)
: m_opaque_up() {
if (lldb_object_ptr)
- m_opaque_up = llvm::make_unique<Declaration>(*lldb_object_ptr);
+ m_opaque_up = std::make_unique<Declaration>(*lldb_object_ptr);
}
const SBDeclaration &SBDeclaration::operator=(const SBDeclaration &rhs) {
diff --git a/source/API/SBFile.cpp b/source/API/SBFile.cpp
new file mode 100644
index 000000000000..f5a38efe4a77
--- /dev/null
+++ b/source/API/SBFile.cpp
@@ -0,0 +1,129 @@
+//===-- SBFile.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/API/SBFile.h"
+#include "SBReproducerPrivate.h"
+#include "lldb/API/SBError.h"
+#include "lldb/Host/File.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBFile::~SBFile() {}
+
+SBFile::SBFile(FileSP file_sp) : m_opaque_sp(file_sp) {
+ LLDB_RECORD_DUMMY(void, SBfile, SBFile, (FileSP), file_sp);
+}
+
+SBFile::SBFile() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFile); }
+
+SBFile::SBFile(FILE *file, bool transfer_ownership) {
+ LLDB_RECORD_DUMMY(void, SBFile, (FILE *, bool), file, transfer_ownership);
+ m_opaque_sp = std::make_shared<NativeFile>(file, transfer_ownership);
+}
+
+SBFile::SBFile(int fd, const char *mode, bool transfer_owndership) {
+ LLDB_RECORD_DUMMY(void, SBFile, (int, const char *, bool), fd, mode,
+ transfer_owndership);
+ auto options = File::GetOptionsFromMode(mode);
+ if (!options) {
+ llvm::consumeError(options.takeError());
+ return;
+ }
+ m_opaque_sp =
+ std::make_shared<NativeFile>(fd, options.get(), transfer_owndership);
+}
+
+SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) {
+ LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Read, (uint8_t *, size_t, size_t *),
+ buf, num_bytes, bytes_read);
+ SBError error;
+ if (!m_opaque_sp) {
+ error.SetErrorString("invalid SBFile");
+ *bytes_read = 0;
+ } else {
+ Status status = m_opaque_sp->Read(buf, num_bytes);
+ error.SetError(status);
+ *bytes_read = num_bytes;
+ }
+ return LLDB_RECORD_RESULT(error);
+}
+
+SBError SBFile::Write(const uint8_t *buf, size_t num_bytes,
+ size_t *bytes_written) {
+ LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Write,
+ (const uint8_t *, size_t, size_t *), buf, num_bytes,
+ bytes_written);
+ SBError error;
+ if (!m_opaque_sp) {
+ error.SetErrorString("invalid SBFile");
+ *bytes_written = 0;
+ } else {
+ Status status = m_opaque_sp->Write(buf, num_bytes);
+ error.SetError(status);
+ *bytes_written = num_bytes;
+ }
+ return LLDB_RECORD_RESULT(error);
+}
+
+SBError SBFile::Flush() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBFile, Flush);
+ SBError error;
+ if (!m_opaque_sp) {
+ error.SetErrorString("invalid SBFile");
+ } else {
+ Status status = m_opaque_sp->Flush();
+ error.SetError(status);
+ }
+ return LLDB_RECORD_RESULT(error);
+}
+
+bool SBFile::IsValid() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, IsValid);
+ return m_opaque_sp && m_opaque_sp->IsValid();
+}
+
+SBError SBFile::Close() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBFile, Close);
+ SBError error;
+ if (m_opaque_sp) {
+ Status status = m_opaque_sp->Close();
+ error.SetError(status);
+ }
+ return LLDB_RECORD_RESULT(error);
+}
+
+SBFile::operator bool() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, operator bool);
+ return LLDB_RECORD_RESULT(IsValid());
+}
+
+bool SBFile::operator!() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, operator!);
+ return LLDB_RECORD_RESULT(!IsValid());
+}
+
+FileSP SBFile::GetFile() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(FileSP, SBFile, GetFile);
+ return m_opaque_sp;
+}
+
+namespace lldb_private {
+namespace repro {
+
+template <> void RegisterMethods<SBFile>(Registry &R) {
+
+ LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Flush, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBFile, IsValid, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator bool,());
+ LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator!,());
+ LLDB_REGISTER_METHOD_CONST(FileSP, SBFile, GetFile, ());
+ LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Close, ());
+}
+} // namespace repro
+} // namespace lldb_private
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index 9268f0f9bdbf..c0e272e1bcd4 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -1107,7 +1107,7 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
if (target->GetDisplayExpressionsInCrashlogs()) {
StreamString frame_description;
frame->DumpUsingSettingsFormat(&frame_description);
- stack_trace = llvm::make_unique<llvm::PrettyStackTraceFormat>(
+ stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
"SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
"= %u) %s",
expr, options.GetFetchDynamicValue(),
@@ -1120,10 +1120,10 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
}
}
- if (expr_log)
- expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is "
- "%s, summary %s **",
- expr_result.GetValue(), expr_result.GetSummary());
+ LLDB_LOGF(expr_log,
+ "** [SBFrame::EvaluateExpression] Expression result is "
+ "%s, summary %s **",
+ expr_result.GetValue(), expr_result.GetSummary());
return LLDB_RECORD_RESULT(expr_result);
}
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index fcf66fd25824..a9ef9fb59d24 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -11,6 +11,7 @@
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
@@ -255,10 +256,21 @@ bool SBInstruction::GetDescription(lldb::SBStream &s) {
return false;
}
-void SBInstruction::Print(FILE *out) {
- LLDB_RECORD_METHOD(void, SBInstruction, Print, (FILE *), out);
+void SBInstruction::Print(FILE *outp) {
+ LLDB_RECORD_METHOD(void, SBInstruction, Print, (FILE *), outp);
+ FileSP out = std::make_shared<NativeFile>(outp, /*take_ownership=*/false);
+ Print(out);
+}
+
+void SBInstruction::Print(SBFile out) {
+ LLDB_RECORD_METHOD(void, SBInstruction, Print, (SBFile), out);
+ Print(out.m_opaque_sp);
+}
+
+void SBInstruction::Print(FileSP out_sp) {
+ LLDB_RECORD_METHOD(void, SBInstruction, Print, (FileSP), out_sp);
- if (out == nullptr)
+ if (!out_sp || !out_sp->IsValid())
return;
lldb::InstructionSP inst_sp(GetOpaque());
@@ -269,7 +281,7 @@ void SBInstruction::Print(FILE *out) {
if (module_sp)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything,
sc);
- StreamFile out_stream(out, false);
+ StreamFile out_stream(out_sp);
FormatEntity::Entry format;
FormatEntity::Parse("${addr}: ", format);
inst_sp->Dump(&out_stream, 0, true, false, nullptr, &sc, nullptr, &format,
@@ -358,6 +370,8 @@ void RegisterMethods<SBInstruction>(Registry &R) {
LLDB_REGISTER_METHOD(bool, SBInstruction, GetDescription,
(lldb::SBStream &));
LLDB_REGISTER_METHOD(void, SBInstruction, Print, (FILE *));
+ LLDB_REGISTER_METHOD(void, SBInstruction, Print, (SBFile));
+ LLDB_REGISTER_METHOD(void, SBInstruction, Print, (FileSP));
LLDB_REGISTER_METHOD(bool, SBInstruction, EmulateWithFrame,
(lldb::SBFrame &, uint32_t));
LLDB_REGISTER_METHOD(bool, SBInstruction, DumpEmulation, (const char *));
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index cce923bf04a4..8b3855c0883b 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -11,8 +11,10 @@
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBFile.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/Stream.h"
@@ -118,21 +120,41 @@ void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) {
void SBInstructionList::Print(FILE *out) {
LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FILE *), out);
-
if (out == nullptr)
return;
+ StreamFile stream(out, false);
+ GetDescription(stream);
}
-bool SBInstructionList::GetDescription(lldb::SBStream &description) {
+void SBInstructionList::Print(SBFile out) {
+ LLDB_RECORD_METHOD(void, SBInstructionList, Print, (SBFile), out);
+ if (!out.IsValid())
+ return;
+ StreamFile stream(out.m_opaque_sp);
+ GetDescription(stream);
+}
+
+void SBInstructionList::Print(FileSP out_sp) {
+ LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FileSP), out_sp);
+ if (!out_sp || !out_sp->IsValid())
+ return;
+ StreamFile stream(out_sp);
+ GetDescription(stream);
+}
+
+bool SBInstructionList::GetDescription(lldb::SBStream &stream) {
LLDB_RECORD_METHOD(bool, SBInstructionList, GetDescription,
- (lldb::SBStream &), description);
+ (lldb::SBStream &), stream);
+ return GetDescription(stream.ref());
+}
+
+bool SBInstructionList::GetDescription(Stream &sref) {
if (m_opaque_sp) {
size_t num_instructions = GetSize();
if (num_instructions) {
// Call the ref() to make sure a stream is created if one deesn't exist
// already inside description...
- Stream &sref = description.ref();
const uint32_t max_opcode_byte_size =
m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
FormatEntity::Entry format;
@@ -200,6 +222,8 @@ void RegisterMethods<SBInstructionList>(Registry &R) {
LLDB_REGISTER_METHOD(void, SBInstructionList, AppendInstruction,
(lldb::SBInstruction));
LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FILE *));
+ LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (SBFile));
+ LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FileSP));
LLDB_REGISTER_METHOD(bool, SBInstructionList, GetDescription,
(lldb::SBStream &));
LLDB_REGISTER_METHOD(bool, SBInstructionList,
diff --git a/source/API/SBLineEntry.cpp b/source/API/SBLineEntry.cpp
index 010a6057cd31..66884f763398 100644
--- a/source/API/SBLineEntry.cpp
+++ b/source/API/SBLineEntry.cpp
@@ -32,7 +32,7 @@ SBLineEntry::SBLineEntry(const SBLineEntry &rhs) : m_opaque_up() {
SBLineEntry::SBLineEntry(const lldb_private::LineEntry *lldb_object_ptr)
: m_opaque_up() {
if (lldb_object_ptr)
- m_opaque_up = llvm::make_unique<LineEntry>(*lldb_object_ptr);
+ m_opaque_up = std::make_unique<LineEntry>(*lldb_object_ptr);
}
const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) {
@@ -45,7 +45,7 @@ const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) {
}
void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) {
- m_opaque_up = llvm::make_unique<LineEntry>(lldb_object_ref);
+ m_opaque_up = std::make_unique<LineEntry>(lldb_object_ref);
}
SBLineEntry::~SBLineEntry() {}
diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp
index 4bd32bce1c53..6cc6d2628ace 100644
--- a/source/API/SBModule.cpp
+++ b/source/API/SBModule.cpp
@@ -20,7 +20,6 @@
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
@@ -283,18 +282,14 @@ SBSymbolContextList SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) {
SBSymbolContextList sb_sc_list;
const ModuleSP module_sp(GetSP());
if (sb_file_spec.IsValid() && module_sp) {
- const bool append = true;
- module_sp->FindCompileUnits(*sb_file_spec, append, *sb_sc_list);
+ module_sp->FindCompileUnits(*sb_file_spec, *sb_sc_list);
}
return LLDB_RECORD_RESULT(sb_sc_list);
}
static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) {
- if (module_sp) {
- SymbolVendor *symbols = module_sp->GetSymbolVendor();
- if (symbols)
- return symbols->GetSymtab();
- }
+ if (module_sp)
+ return module_sp->GetSymtab();
return nullptr;
}
@@ -302,11 +297,8 @@ size_t SBModule::GetNumSymbols() {
LLDB_RECORD_METHOD_NO_ARGS(size_t, SBModule, GetNumSymbols);
ModuleSP module_sp(GetSP());
- if (module_sp) {
- Symtab *symtab = GetUnifiedSymbolTable(module_sp);
- if (symtab)
- return symtab->GetNumSymbols();
- }
+ if (Symtab *symtab = GetUnifiedSymbolTable(module_sp))
+ return symtab->GetNumSymbols();
return 0;
}
@@ -349,8 +341,9 @@ lldb::SBSymbolContextList SBModule::FindSymbols(const char *name,
Symtab *symtab = GetUnifiedSymbolTable(module_sp);
if (symtab) {
std::vector<uint32_t> matching_symbol_indexes;
- const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(
- ConstString(name), symbol_type, matching_symbol_indexes);
+ symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type,
+ matching_symbol_indexes);
+ const size_t num_matches = matching_symbol_indexes.size();
if (num_matches) {
SymbolContext sc;
sc.module_sp = module_sp;
@@ -372,7 +365,7 @@ size_t SBModule::GetNumSections() {
ModuleSP module_sp(GetSP());
if (module_sp) {
// Give the symbol vendor a chance to add to the unified section list.
- module_sp->GetSymbolVendor();
+ module_sp->GetSymbolFile();
SectionList *section_list = module_sp->GetSectionList();
if (section_list)
return section_list->GetSize();
@@ -388,7 +381,7 @@ SBSection SBModule::GetSectionAtIndex(size_t idx) {
ModuleSP module_sp(GetSP());
if (module_sp) {
// Give the symbol vendor a chance to add to the unified section list.
- module_sp->GetSymbolVendor();
+ module_sp->GetSymbolFile();
SectionList *section_list = module_sp->GetSectionList();
if (section_list)
@@ -405,12 +398,11 @@ lldb::SBSymbolContextList SBModule::FindFunctions(const char *name,
lldb::SBSymbolContextList sb_sc_list;
ModuleSP module_sp(GetSP());
if (name && module_sp) {
- const bool append = true;
const bool symbols_ok = true;
const bool inlines_ok = true;
FunctionNameType type = static_cast<FunctionNameType>(name_type_mask);
module_sp->FindFunctions(ConstString(name), nullptr, type, symbols_ok,
- inlines_ok, append, *sb_sc_list);
+ inlines_ok, *sb_sc_list);
}
return LLDB_RECORD_RESULT(sb_sc_list);
}
@@ -425,9 +417,9 @@ SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name,
ModuleSP module_sp(GetSP());
if (name && module_sp) {
VariableList variable_list;
- const uint32_t match_count = module_sp->FindGlobalVariables(
- ConstString(name), nullptr, max_matches, variable_list);
-
+ module_sp->FindGlobalVariables(ConstString(name), nullptr, max_matches,
+ variable_list);
+ const uint32_t match_count = variable_list.GetSize();
if (match_count > 0) {
for (uint32_t i = 0; i < match_count; ++i) {
lldb::ValueObjectSP valobj_sp;
@@ -468,10 +460,13 @@ lldb::SBType SBModule::FindFirstType(const char *name_cstr) {
sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match));
if (!sb_type.IsValid()) {
- TypeSystem *type_system =
+ auto type_system_or_err =
module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system)
- sb_type = SBType(type_system->GetBuiltinTypeByName(name));
+ if (auto err = type_system_or_err.takeError()) {
+ llvm::consumeError(std::move(err));
+ return LLDB_RECORD_RESULT(SBType());
+ }
+ sb_type = SBType(type_system_or_err->GetBuiltinTypeByName(name));
}
}
return LLDB_RECORD_RESULT(sb_type);
@@ -483,10 +478,14 @@ lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {
ModuleSP module_sp(GetSP());
if (module_sp) {
- TypeSystem *type_system =
+ auto type_system_or_err =
module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system)
- return LLDB_RECORD_RESULT(SBType(type_system->GetBasicTypeFromAST(type)));
+ if (auto err = type_system_or_err.takeError()) {
+ llvm::consumeError(std::move(err));
+ } else {
+ return LLDB_RECORD_RESULT(
+ SBType(type_system_or_err->GetBasicTypeFromAST(type)));
+ }
}
return LLDB_RECORD_RESULT(SBType());
}
@@ -503,26 +502,28 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) {
const bool exact_match = false;
ConstString name(type);
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- const uint32_t num_matches = module_sp->FindTypes(
- name, exact_match, UINT32_MAX, searched_symbol_files, type_list);
+ module_sp->FindTypes(name, exact_match, UINT32_MAX, searched_symbol_files,
+ type_list);
- if (num_matches > 0) {
- for (size_t idx = 0; idx < num_matches; idx++) {
- TypeSP type_sp(type_list.GetTypeAtIndex(idx));
- if (type_sp)
- retval.Append(SBType(type_sp));
- }
- } else {
- TypeSystem *type_system =
+ if (type_list.Empty()) {
+ auto type_system_or_err =
module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system) {
- CompilerType compiler_type = type_system->GetBuiltinTypeByName(name);
+ if (auto err = type_system_or_err.takeError()) {
+ llvm::consumeError(std::move(err));
+ } else {
+ CompilerType compiler_type =
+ type_system_or_err->GetBuiltinTypeByName(name);
if (compiler_type)
retval.Append(SBType(compiler_type));
}
+ } else {
+ for (size_t idx = 0; idx < type_list.GetSize(); idx++) {
+ TypeSP type_sp(type_list.GetTypeAtIndex(idx));
+ if (type_sp)
+ retval.Append(SBType(type_sp));
+ }
}
}
-
return LLDB_RECORD_RESULT(retval);
}
@@ -532,9 +533,8 @@ lldb::SBType SBModule::GetTypeByID(lldb::user_id_t uid) {
ModuleSP module_sp(GetSP());
if (module_sp) {
- SymbolVendor *vendor = module_sp->GetSymbolVendor();
- if (vendor) {
- Type *type_ptr = vendor->ResolveTypeUID(uid);
+ if (SymbolFile *symfile = module_sp->GetSymbolFile()) {
+ Type *type_ptr = symfile->ResolveTypeUID(uid);
if (type_ptr)
return LLDB_RECORD_RESULT(SBType(type_ptr->shared_from_this()));
}
@@ -551,13 +551,13 @@ lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) {
ModuleSP module_sp(GetSP());
if (!module_sp)
return LLDB_RECORD_RESULT(sb_type_list);
- SymbolVendor *vendor = module_sp->GetSymbolVendor();
- if (!vendor)
+ SymbolFile *symfile = module_sp->GetSymbolFile();
+ if (!symfile)
return LLDB_RECORD_RESULT(sb_type_list);
TypeClass type_class = static_cast<TypeClass>(type_mask);
TypeList type_list;
- vendor->GetTypes(nullptr, type_class, type_list);
+ symfile->GetTypes(nullptr, type_class, type_list);
sb_type_list.m_opaque_up->Append(type_list);
return LLDB_RECORD_RESULT(sb_type_list);
}
@@ -571,7 +571,7 @@ SBSection SBModule::FindSection(const char *sect_name) {
ModuleSP module_sp(GetSP());
if (sect_name && module_sp) {
// Give the symbol vendor a chance to add to the unified section list.
- module_sp->GetSymbolVendor();
+ module_sp->GetSymbolFile();
SectionList *section_list = module_sp->GetSectionList();
if (section_list) {
ConstString const_sect_name(sect_name);
@@ -653,9 +653,8 @@ lldb::SBFileSpec SBModule::GetSymbolFileSpec() const {
lldb::SBFileSpec sb_file_spec;
ModuleSP module_sp(GetSP());
if (module_sp) {
- SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor();
- if (symbol_vendor_ptr)
- sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec());
+ if (SymbolFile *symfile = module_sp->GetSymbolFile())
+ sb_file_spec.SetFileSpec(symfile->GetObjectFile()->GetFileSpec());
}
return LLDB_RECORD_RESULT(sb_file_spec);
}
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index 4226ff77ecdc..45aaa0bd2d8a 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -29,11 +29,11 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/Stream.h"
-
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/API/SBMemoryRegionInfoList.h"
@@ -331,23 +331,34 @@ lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options,
return LLDB_RECORD_RESULT(trace_instance);
}
+void SBProcess::ReportEventState(const SBEvent &event, SBFile out) const {
+ LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState,
+ (const SBEvent &, SBFile), event, out);
+
+ return ReportEventState(event, out.m_opaque_sp);
+}
+
void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const {
LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState,
(const lldb::SBEvent &, FILE *), event, out);
+ FileSP outfile = std::make_shared<NativeFile>(out, false);
+ return ReportEventState(event, outfile);
+}
+
+void SBProcess::ReportEventState(const SBEvent &event, FileSP out) const {
+
+ LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState,
+ (const SBEvent &, FileSP), event, out);
- if (out == nullptr)
+ if (!out || !out->IsValid())
return;
ProcessSP process_sp(GetSP());
if (process_sp) {
+ StreamFile stream(out);
const StateType event_state = SBProcess::GetStateFromEvent(event);
- char message[1024];
- int message_len = ::snprintf(
- message, sizeof(message), "Process %" PRIu64 " %s\n",
+ stream.Printf("Process %" PRIu64 " %s\n",
process_sp->GetID(), SBDebugger::StateAsCString(event_state));
-
- if (message_len > 0)
- ::fwrite(message, 1, message_len, out);
}
}
@@ -1180,6 +1191,9 @@ bool SBProcess::IsInstrumentationRuntimePresent(
if (!process_sp)
return false;
+ std::lock_guard<std::recursive_mutex> guard(
+ process_sp->GetTarget().GetAPIMutex());
+
InstrumentationRuntimeSP runtime_sp =
process_sp->GetInstrumentationRuntime(type);
@@ -1307,6 +1321,10 @@ void RegisterMethods<SBProcess>(Registry &R) {
(lldb::SBTraceOptions &, lldb::SBError &));
LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
(const lldb::SBEvent &, FILE *));
+ LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
+ (const lldb::SBEvent &, FileSP));
+ LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
+ (const lldb::SBEvent &, SBFile));
LLDB_REGISTER_METHOD(
void, SBProcess, AppendEventStateReport,
(const lldb::SBEvent &, lldb::SBCommandReturnObject &));
diff --git a/source/API/SBReproducer.cpp b/source/API/SBReproducer.cpp
index 439ee5a70460..6e11b2c6366f 100644
--- a/source/API/SBReproducer.cpp
+++ b/source/API/SBReproducer.cpp
@@ -52,6 +52,7 @@ SBRegistry::SBRegistry() {
RegisterMethods<SBEvent>(R);
RegisterMethods<SBExecutionContext>(R);
RegisterMethods<SBExpressionOptions>(R);
+ RegisterMethods<SBFile>(R);
RegisterMethods<SBFileSpec>(R);
RegisterMethods<SBFileSpecList>(R);
RegisterMethods<SBFrame>(R);
diff --git a/source/API/SBReproducerPrivate.h b/source/API/SBReproducerPrivate.h
index 84b6ce967c0b..edd06941398f 100644
--- a/source/API/SBReproducerPrivate.h
+++ b/source/API/SBReproducerPrivate.h
@@ -40,7 +40,7 @@ public:
SBProvider(const FileSpec &directory)
: Provider(directory),
m_stream(directory.CopyByAppendingPathComponent("sbapi.bin").GetPath(),
- m_ec, llvm::sys::fs::OpenFlags::F_None),
+ m_ec, llvm::sys::fs::OpenFlags::OF_None),
m_serializer(m_stream) {}
Serializer &GetSerializer() { return m_serializer; }
diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp
index ae652338e1ea..d57634d2947c 100644
--- a/source/API/SBStream.cpp
+++ b/source/API/SBStream.cpp
@@ -9,6 +9,7 @@
#include "lldb/API/SBStream.h"
#include "SBReproducerPrivate.h"
+#include "lldb/API/SBFile.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/Status.h"
@@ -82,33 +83,45 @@ void SBStream::RedirectToFile(const char *path, bool append) {
if (!m_is_file)
local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString();
}
- StreamFile *stream_file = new StreamFile;
- uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+ auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
if (append)
open_options |= File::eOpenOptionAppend;
else
open_options |= File::eOpenOptionTruncate;
- FileSystem::Instance().Open(stream_file->GetFile(), FileSpec(path),
- open_options);
- m_opaque_up.reset(stream_file);
+ llvm::Expected<FileUP> file =
+ FileSystem::Instance().Open(FileSpec(path), open_options);
+ if (!file) {
+ LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), file.takeError(),
+ "Cannot open {1}: {0}", path);
+ return;
+ }
- if (m_opaque_up) {
- m_is_file = true;
+ m_opaque_up = std::make_unique<StreamFile>(std::move(file.get()));
+ m_is_file = true;
- // If we had any data locally in our StreamString, then pass that along to
- // the to new file we are redirecting to.
- if (!local_data.empty())
- m_opaque_up->Write(&local_data[0], local_data.size());
- } else
- m_is_file = false;
+ // If we had any data locally in our StreamString, then pass that along to
+ // the to new file we are redirecting to.
+ if (!local_data.empty())
+ m_opaque_up->Write(&local_data[0], local_data.size());
}
void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) {
LLDB_RECORD_METHOD(void, SBStream, RedirectToFileHandle, (FILE *, bool), fh,
transfer_fh_ownership);
+ FileSP file = std::make_unique<NativeFile>(fh, transfer_fh_ownership);
+ return RedirectToFile(file);
+}
- if (fh == nullptr)
+void SBStream::RedirectToFile(SBFile file) {
+ LLDB_RECORD_METHOD(void, SBStream, RedirectToFile, (SBFile), file)
+ RedirectToFile(file.GetFile());
+}
+
+void SBStream::RedirectToFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(void, SBStream, RedirectToFile, (FileSP), file_sp);
+
+ if (!file_sp || !file_sp->IsValid())
return;
std::string local_data;
@@ -118,17 +131,14 @@ void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) {
if (!m_is_file)
local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString();
}
- m_opaque_up.reset(new StreamFile(fh, transfer_fh_ownership));
- if (m_opaque_up) {
- m_is_file = true;
+ m_opaque_up = std::make_unique<StreamFile>(file_sp);
+ m_is_file = true;
- // If we had any data locally in our StreamString, then pass that along to
- // the to new file we are redirecting to.
- if (!local_data.empty())
- m_opaque_up->Write(&local_data[0], local_data.size());
- } else
- m_is_file = false;
+ // If we had any data locally in our StreamString, then pass that along to
+ // the to new file we are redirecting to.
+ if (!local_data.empty())
+ m_opaque_up->Write(&local_data[0], local_data.size());
}
void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) {
@@ -143,16 +153,13 @@ void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) {
local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString();
}
- m_opaque_up.reset(new StreamFile(::fdopen(fd, "w"), transfer_fh_ownership));
- if (m_opaque_up) {
- m_is_file = true;
+ m_opaque_up = std::make_unique<StreamFile>(fd, transfer_fh_ownership);
+ m_is_file = true;
- // If we had any data locally in our StreamString, then pass that along to
- // the to new file we are redirecting to.
- if (!local_data.empty())
- m_opaque_up->Write(&local_data[0], local_data.size());
- } else
- m_is_file = false;
+ // If we had any data locally in our StreamString, then pass that along to
+ // the to new file we are redirecting to.
+ if (!local_data.empty())
+ m_opaque_up->Write(&local_data[0], local_data.size());
}
lldb_private::Stream *SBStream::operator->() { return m_opaque_up.get(); }
@@ -189,6 +196,8 @@ void RegisterMethods<SBStream>(Registry &R) {
LLDB_REGISTER_METHOD(const char *, SBStream, GetData, ());
LLDB_REGISTER_METHOD(size_t, SBStream, GetSize, ());
LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (const char *, bool));
+ LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (FileSP));
+ LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (SBFile));
LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileHandle, (FILE *, bool));
LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileDescriptor, (int, bool));
LLDB_REGISTER_METHOD(void, SBStream, Clear, ());
diff --git a/source/API/SBStringList.cpp b/source/API/SBStringList.cpp
index 2f8bd55855a1..ac07b8faac4d 100644
--- a/source/API/SBStringList.cpp
+++ b/source/API/SBStringList.cpp
@@ -21,7 +21,7 @@ SBStringList::SBStringList() : m_opaque_up() {
SBStringList::SBStringList(const lldb_private::StringList *lldb_strings_ptr)
: m_opaque_up() {
if (lldb_strings_ptr)
- m_opaque_up = llvm::make_unique<StringList>(*lldb_strings_ptr);
+ m_opaque_up = std::make_unique<StringList>(*lldb_strings_ptr);
}
SBStringList::SBStringList(const SBStringList &rhs) : m_opaque_up() {
diff --git a/source/API/SBSymbolContext.cpp b/source/API/SBSymbolContext.cpp
index 365f0ccc2fbf..6e01e5535c32 100644
--- a/source/API/SBSymbolContext.cpp
+++ b/source/API/SBSymbolContext.cpp
@@ -27,7 +27,7 @@ SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_up() {
(const lldb_private::SymbolContext *), sc_ptr);
if (sc_ptr)
- m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr);
+ m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr);
}
SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_up() {
@@ -51,7 +51,7 @@ const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) {
void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) {
if (sc_ptr)
- m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr);
+ m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr);
else
m_opaque_up->Clear(true);
}
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 5e87eb6273b3..1d13087eef69 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -44,11 +44,11 @@
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Language.h"
@@ -218,7 +218,7 @@ SBStructuredData SBTarget::GetStatistics() {
if (!target_sp)
return LLDB_RECORD_RESULT(data);
- auto stats_up = llvm::make_unique<StructuredData::Dictionary>();
+ auto stats_up = std::make_unique<StructuredData::Dictionary>();
int i = 0;
for (auto &Entry : target_sp->GetStatistics()) {
std::string Desc = lldb_private::GetStatDescription(
@@ -960,8 +960,8 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateByRegex(
const LazyBool skip_prologue = eLazyBoolCalculate;
sb_bp = target_sp->CreateFuncRegexBreakpoint(
- module_list.get(), comp_unit_list.get(), regexp, symbol_language,
- skip_prologue, internal, hardware);
+ module_list.get(), comp_unit_list.get(), std::move(regexp),
+ symbol_language, skip_prologue, internal, hardware);
}
return LLDB_RECORD_RESULT(sb_bp);
@@ -1061,8 +1061,8 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateBySourceRegex(
}
sb_bp = target_sp->CreateSourceRegexBreakpoint(
- module_list.get(), source_file_list.get(), func_names_set, regexp,
- false, hardware, move_to_nearest_code);
+ module_list.get(), source_file_list.get(), func_names_set,
+ std::move(regexp), false, hardware, move_to_nearest_code);
}
return LLDB_RECORD_RESULT(sb_bp);
@@ -1653,11 +1653,8 @@ SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
SBSymbolContextList sb_sc_list;
const TargetSP target_sp(GetSP());
- if (target_sp && sb_file_spec.IsValid()) {
- const bool append = true;
- target_sp->GetImages().FindCompileUnits(*sb_file_spec,
- append, *sb_sc_list);
- }
+ if (target_sp && sb_file_spec.IsValid())
+ target_sp->GetImages().FindCompileUnits(*sb_file_spec, *sb_sc_list);
return LLDB_RECORD_RESULT(sb_sc_list);
}
@@ -1783,10 +1780,9 @@ lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name,
const bool symbols_ok = true;
const bool inlines_ok = true;
- const bool append = true;
FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask);
target_sp->GetImages().FindFunctions(ConstString(name), mask, symbols_ok,
- inlines_ok, append, *sb_sc_list);
+ inlines_ok, *sb_sc_list);
return LLDB_RECORD_RESULT(sb_sc_list);
}
@@ -1806,17 +1802,16 @@ lldb::SBSymbolContextList SBTarget::FindGlobalFunctions(const char *name,
switch (matchtype) {
case eMatchTypeRegex:
target_sp->GetImages().FindFunctions(RegularExpression(name_ref), true,
- true, true, *sb_sc_list);
+ true, *sb_sc_list);
break;
case eMatchTypeStartsWith:
regexstr = llvm::Regex::escape(name) + ".*";
target_sp->GetImages().FindFunctions(RegularExpression(regexstr), true,
- true, true, *sb_sc_list);
+ true, *sb_sc_list);
break;
default:
- target_sp->GetImages().FindFunctions(ConstString(name),
- eFunctionNameTypeAny, true, true,
- true, *sb_sc_list);
+ target_sp->GetImages().FindFunctions(
+ ConstString(name), eFunctionNameTypeAny, true, true, *sb_sc_list);
break;
}
}
@@ -1858,11 +1853,11 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
}
// No matches, search for basic typename matches
- ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
- if (clang_ast)
- return LLDB_RECORD_RESULT(SBType(ClangASTContext::GetBasicType(
- clang_ast->getASTContext(), const_typename)));
+ for (auto *type_system : target_sp->GetScratchTypeSystems())
+ if (auto type = type_system->GetBuiltinTypeByName(const_typename))
+ return LLDB_RECORD_RESULT(SBType(type));
}
+
return LLDB_RECORD_RESULT(SBType());
}
@@ -1872,10 +1867,9 @@ SBType SBTarget::GetBasicType(lldb::BasicType type) {
TargetSP target_sp(GetSP());
if (target_sp) {
- ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
- if (clang_ast)
- return LLDB_RECORD_RESULT(SBType(
- ClangASTContext::GetBasicType(clang_ast->getASTContext(), type)));
+ for (auto *type_system : target_sp->GetScratchTypeSystems())
+ if (auto compiler_type = type_system->GetBasicTypeFromAST(type))
+ return LLDB_RECORD_RESULT(SBType(compiler_type));
}
return LLDB_RECORD_RESULT(SBType());
}
@@ -1892,16 +1886,13 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) {
bool exact_match = false;
TypeList type_list;
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- uint32_t num_matches =
- images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX,
- searched_symbol_files, type_list);
+ images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX,
+ searched_symbol_files, type_list);
- if (num_matches > 0) {
- for (size_t idx = 0; idx < num_matches; idx++) {
- TypeSP type_sp(type_list.GetTypeAtIndex(idx));
- if (type_sp)
- sb_type_list.Append(SBType(type_sp));
- }
+ for (size_t idx = 0; idx < type_list.GetSize(); idx++) {
+ TypeSP type_sp(type_list.GetTypeAtIndex(idx));
+ if (type_sp)
+ sb_type_list.Append(SBType(type_sp));
}
// Try the loaded language runtimes
@@ -1918,10 +1909,10 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) {
if (sb_type_list.GetSize() == 0) {
// No matches, search for basic typename matches
- ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
- if (clang_ast)
- sb_type_list.Append(SBType(ClangASTContext::GetBasicType(
- clang_ast->getASTContext(), const_typename)));
+ for (auto *type_system : target_sp->GetScratchTypeSystems())
+ if (auto compiler_type =
+ type_system->GetBuiltinTypeByName(const_typename))
+ sb_type_list.Append(SBType(compiler_type));
}
}
return LLDB_RECORD_RESULT(sb_type_list);
@@ -1937,9 +1928,9 @@ SBValueList SBTarget::FindGlobalVariables(const char *name,
TargetSP target_sp(GetSP());
if (name && target_sp) {
VariableList variable_list;
- const uint32_t match_count = target_sp->GetImages().FindGlobalVariables(
- ConstString(name), max_matches, variable_list);
-
+ target_sp->GetImages().FindGlobalVariables(ConstString(name), max_matches,
+ variable_list);
+ const uint32_t match_count = variable_list.GetSize();
if (match_count > 0) {
ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
if (exe_scope == nullptr)
@@ -1974,20 +1965,20 @@ SBValueList SBTarget::FindGlobalVariables(const char *name,
uint32_t match_count;
switch (matchtype) {
case eMatchTypeNormal:
- match_count = target_sp->GetImages().FindGlobalVariables(
- ConstString(name), max_matches, variable_list);
+ target_sp->GetImages().FindGlobalVariables(ConstString(name), max_matches,
+ variable_list);
break;
case eMatchTypeRegex:
- match_count = target_sp->GetImages().FindGlobalVariables(
- RegularExpression(name_ref), max_matches, variable_list);
+ target_sp->GetImages().FindGlobalVariables(RegularExpression(name_ref),
+ max_matches, variable_list);
break;
case eMatchTypeStartsWith:
regexstr = llvm::Regex::escape(name) + ".*";
- match_count = target_sp->GetImages().FindGlobalVariables(
- RegularExpression(regexstr), max_matches, variable_list);
+ target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr),
+ max_matches, variable_list);
break;
}
-
+ match_count = variable_list.GetSize();
if (match_count > 0) {
ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
if (exe_scope == nullptr)
@@ -2291,11 +2282,9 @@ lldb::SBSymbolContextList SBTarget::FindSymbols(const char *name,
SBSymbolContextList sb_sc_list;
if (name && name[0]) {
TargetSP target_sp(GetSP());
- if (target_sp) {
- bool append = true;
+ if (target_sp)
target_sp->GetImages().FindSymbolsWithNameAndType(
- ConstString(name), symbol_type, *sb_sc_list, append);
- }
+ ConstString(name), symbol_type, *sb_sc_list);
}
return LLDB_RECORD_RESULT(sb_sc_list);
}
@@ -2355,10 +2344,10 @@ lldb::SBValue SBTarget::EvaluateExpression(const char *expr,
expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
}
}
- if (expr_log)
- expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is "
- "%s, summary %s **",
- expr_result.GetValue(), expr_result.GetSummary());
+ LLDB_LOGF(expr_log,
+ "** [SBTarget::EvaluateExpression] Expression result is "
+ "%s, summary %s **",
+ expr_result.GetValue(), expr_result.GetSummary());
return LLDB_RECORD_RESULT(expr_result);
}
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index 85e9a6b47955..8d4930bf6edb 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -16,6 +16,7 @@
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
@@ -23,6 +24,7 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -965,9 +967,24 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
}
SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
+ bool resume_immediately) {
+ LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
+ (const char *, bool), script_class_name,
+ resume_immediately);
+
+ lldb::SBStructuredData no_data;
+ return LLDB_RECORD_RESULT(
+ StepUsingScriptedThreadPlan(script_class_name,
+ no_data,
+ resume_immediately));
+}
+
+SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
+ SBStructuredData &args_data,
bool resume_immediately) {
LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
- (const char *, bool), script_class_name,
+ (const char *, lldb::SBStructuredData &, bool),
+ script_class_name, args_data,
resume_immediately);
SBError error;
@@ -982,8 +999,10 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
Thread *thread = exe_ctx.GetThreadPtr();
Status new_plan_status;
+ StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
+
ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
- false, script_class_name, false, new_plan_status);
+ false, script_class_name, obj_sp, false, new_plan_status);
if (new_plan_status.Fail()) {
error.SetErrorString(new_plan_status.AsCString());
@@ -1460,6 +1479,8 @@ void RegisterMethods<SBThread>(Registry &R) {
(const char *));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
(const char *, bool));
+ LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
+ (const char *, SBStructuredData &, bool));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
(lldb::SBFileSpec &, uint32_t));
LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
diff --git a/source/API/SBThreadPlan.cpp b/source/API/SBThreadPlan.cpp
index 8f6802fe9cef..eed4d1bfb9c4 100644
--- a/source/API/SBThreadPlan.cpp
+++ b/source/API/SBThreadPlan.cpp
@@ -11,10 +11,12 @@
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -67,7 +69,20 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
Thread *thread = sb_thread.get();
if (thread)
- m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name);
+ m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ nullptr);
+}
+
+SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
+ lldb::SBStructuredData &args_data) {
+ LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
+ SBStructuredData &),
+ sb_thread, class_name, args_data);
+
+ Thread *thread = sb_thread.get();
+ if (thread)
+ m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ args_data.m_impl_up.get());
}
// Assignment operator
@@ -368,9 +383,35 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
if (m_opaque_sp) {
Status plan_status;
+ StructuredData::ObjectSP empty_args;
SBThreadPlan plan =
SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
- false, script_class_name, false, plan_status));
+ false, script_class_name, empty_args, false, plan_status));
+
+ if (plan_status.Fail())
+ error.SetErrorString(plan_status.AsCString());
+
+ return LLDB_RECORD_RESULT(plan);
+ } else {
+ return LLDB_RECORD_RESULT(SBThreadPlan());
+ }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
+ lldb::SBStructuredData &args_data,
+ SBError &error) {
+ LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
+ QueueThreadPlanForStepScripted,
+ (const char *, lldb::SBStructuredData &, lldb::SBError &),
+ script_class_name, args_data, error);
+
+ if (m_opaque_sp) {
+ Status plan_status;
+ StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
+ SBThreadPlan plan =
+ SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
+ false, script_class_name, args_obj, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
@@ -390,6 +431,8 @@ void RegisterMethods<SBThreadPlan>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &));
LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *));
+ LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
+ lldb::SBStructuredData &));
LLDB_REGISTER_METHOD(const lldb::SBThreadPlan &,
SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ());
@@ -433,6 +476,10 @@ void RegisterMethods<SBThreadPlan>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
QueueThreadPlanForStepScripted,
(const char *, lldb::SBError &));
+ LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
+ QueueThreadPlanForStepScripted,
+ (const char *, lldb::SBStructuredData &,
+ lldb::SBError &));
}
}
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index 5402128b3fae..8efc701a79fb 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -799,7 +799,7 @@ const char *SBTypeMemberFunction::GetDemangledName() {
if (m_opaque_sp) {
ConstString mangled_str = m_opaque_sp->GetMangledName();
if (mangled_str) {
- Mangled mangled(mangled_str, true);
+ Mangled mangled(mangled_str);
return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString();
}
}
diff --git a/source/API/SBTypeCategory.cpp b/source/API/SBTypeCategory.cpp
index 43d5a3ab140f..1e4496575098 100644
--- a/source/API/SBTypeCategory.cpp
+++ b/source/API/SBTypeCategory.cpp
@@ -364,8 +364,8 @@ bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name,
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeFormatsContainer()->Add(
- lldb::RegularExpressionSP(new RegularExpression(
- llvm::StringRef::withNullAsEmpty(type_name.GetName()))),
+ RegularExpression(
+ llvm::StringRef::withNullAsEmpty(type_name.GetName())),
format.GetSP());
else
m_opaque_sp->GetTypeFormatsContainer()->Add(
@@ -443,8 +443,8 @@ bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name,
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeSummariesContainer()->Add(
- lldb::RegularExpressionSP(new RegularExpression(
- llvm::StringRef::withNullAsEmpty(type_name.GetName()))),
+ RegularExpression(
+ llvm::StringRef::withNullAsEmpty(type_name.GetName())),
summary.GetSP());
else
m_opaque_sp->GetTypeSummariesContainer()->Add(
@@ -488,8 +488,8 @@ bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name,
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeFiltersContainer()->Add(
- lldb::RegularExpressionSP(new RegularExpression(
- llvm::StringRef::withNullAsEmpty(type_name.GetName()))),
+ RegularExpression(
+ llvm::StringRef::withNullAsEmpty(type_name.GetName())),
filter.GetSP());
else
m_opaque_sp->GetTypeFiltersContainer()->Add(
@@ -567,8 +567,8 @@ bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name,
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add(
- lldb::RegularExpressionSP(new RegularExpression(
- llvm::StringRef::withNullAsEmpty(type_name.GetName()))),
+ RegularExpression(
+ llvm::StringRef::withNullAsEmpty(type_name.GetName())),
synth.GetSP());
else
m_opaque_sp->GetTypeSyntheticsContainer()->Add(
diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp
index e7f2206b9a59..0acc496ff879 100644
--- a/source/API/SystemInitializerFull.cpp
+++ b/source/API/SystemInitializerFull.cpp
@@ -24,6 +24,7 @@
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
+#include "Plugins/ABI/SysV-arc/ABISysV_arc.h"
#include "Plugins/ABI/SysV-arm/ABISysV_arm.h"
#include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h"
#include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h"
@@ -131,6 +132,39 @@ SystemInitializerFull::SystemInitializerFull() {}
SystemInitializerFull::~SystemInitializerFull() {}
+#define LLDB_PROCESS_AArch64(op) \
+ ABIMacOSX_arm64::op(); \
+ ABISysV_arm64::op();
+#define LLDB_PROCESS_ARM(op) \
+ ABIMacOSX_arm::op(); \
+ ABISysV_arm::op();
+#define LLDB_PROCESS_ARC(op) \
+ ABISysV_arc::op();
+#define LLDB_PROCESS_Hexagon(op) ABISysV_hexagon::op();
+#define LLDB_PROCESS_Mips(op) \
+ ABISysV_mips::op(); \
+ ABISysV_mips64::op();
+#define LLDB_PROCESS_PowerPC(op) \
+ ABISysV_ppc::op(); \
+ ABISysV_ppc64::op();
+#define LLDB_PROCESS_SystemZ(op) ABISysV_s390x::op();
+#define LLDB_PROCESS_X86(op) \
+ ABIMacOSX_i386::op(); \
+ ABISysV_i386::op(); \
+ ABISysV_x86_64::op(); \
+ ABIWindows_x86_64::op();
+
+#define LLDB_PROCESS_AMDGPU(op)
+#define LLDB_PROCESS_AVR(op)
+#define LLDB_PROCESS_BPF(op)
+#define LLDB_PROCESS_Lanai(op)
+#define LLDB_PROCESS_MSP430(op)
+#define LLDB_PROCESS_NVPTX(op)
+#define LLDB_PROCESS_RISCV(op)
+#define LLDB_PROCESS_Sparc(op)
+#define LLDB_PROCESS_WebAssembly(op)
+#define LLDB_PROCESS_XCore(op)
+
llvm::Error SystemInitializerFull::Initialize() {
if (auto e = SystemInitializerCommon::Initialize())
return e;
@@ -174,20 +208,8 @@ llvm::Error SystemInitializerFull::Initialize() {
ClangASTContext::Initialize();
- ABIMacOSX_i386::Initialize();
- ABIMacOSX_arm::Initialize();
- ABIMacOSX_arm64::Initialize();
- ABISysV_arm::Initialize();
- ABISysV_arm64::Initialize();
- ABISysV_hexagon::Initialize();
- ABISysV_i386::Initialize();
- ABISysV_x86_64::Initialize();
- ABISysV_ppc::Initialize();
- ABISysV_ppc64::Initialize();
- ABISysV_mips::Initialize();
- ABISysV_mips64::Initialize();
- ABISysV_s390x::Initialize();
- ABIWindows_x86_64::Initialize();
+#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Initialize)
+#include "llvm/Config/Targets.def"
ArchitectureArm::Initialize();
ArchitectureMips::Initialize();
@@ -288,20 +310,9 @@ void SystemInitializerFull::Terminate() {
ArchitectureMips::Terminate();
ArchitecturePPC64::Terminate();
- ABIMacOSX_i386::Terminate();
- ABIMacOSX_arm::Terminate();
- ABIMacOSX_arm64::Terminate();
- ABISysV_arm::Terminate();
- ABISysV_arm64::Terminate();
- ABISysV_hexagon::Terminate();
- ABISysV_i386::Terminate();
- ABISysV_x86_64::Terminate();
- ABISysV_ppc::Terminate();
- ABISysV_ppc64::Terminate();
- ABISysV_mips::Terminate();
- ABISysV_mips64::Terminate();
- ABISysV_s390x::Terminate();
- ABIWindows_x86_64::Terminate();
+#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Terminate)
+#include "llvm/Config/Targets.def"
+
DisassemblerLLVMC::Terminate();
JITLoaderGDB::Terminate();
diff --git a/source/API/Utils.h b/source/API/Utils.h
index b1975e5421dd..ed81534d2d12 100644
--- a/source/API/Utils.h
+++ b/source/API/Utils.h
@@ -16,7 +16,7 @@ namespace lldb_private {
template <typename T> std::unique_ptr<T> clone(const std::unique_ptr<T> &src) {
if (src)
- return llvm::make_unique<T>(*src);
+ return std::make_unique<T>(*src);
return nullptr;
}
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 3c3841949b91..a112542803c4 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -496,10 +496,10 @@ void Breakpoint::ClearAllBreakpointSites() {
void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
bool delete_locations) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Breakpoint::ModulesChanged: num_modules: %zu load: %i "
- "delete_locations: %i\n",
- module_list.GetSize(), load, delete_locations);
+ LLDB_LOGF(log,
+ "Breakpoint::ModulesChanged: num_modules: %zu load: %i "
+ "delete_locations: %i\n",
+ module_list.GetSize(), load, delete_locations);
std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
if (load) {
@@ -550,10 +550,10 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
seen = true;
if (!break_loc_sp->ResolveBreakpointSite()) {
- if (log)
- log->Printf("Warning: could not set breakpoint site for "
- "breakpoint location %d of breakpoint %d.\n",
- break_loc_sp->GetID(), GetID());
+ LLDB_LOGF(log,
+ "Warning: could not set breakpoint site for "
+ "breakpoint location %d of breakpoint %d.\n",
+ break_loc_sp->GetID(), GetID());
}
}
}
@@ -659,9 +659,8 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc,
void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
ModuleSP new_module_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Breakpoint::ModulesReplaced for %s\n",
- old_module_sp->GetSpecificationDescription().c_str());
+ LLDB_LOGF(log, "Breakpoint::ModulesReplaced for %s\n",
+ old_module_sp->GetSpecificationDescription().c_str());
// First find all the locations that are in the old module
BreakpointLocationCollection old_break_locs;
diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp
index 1e695fae6995..de68c44ec6a4 100644
--- a/source/Breakpoint/BreakpointIDList.cpp
+++ b/source/Breakpoint/BreakpointIDList.cpp
@@ -122,7 +122,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
for (size_t i = 0; i < old_args.size(); ++i) {
bool is_range = false;
- current_arg = old_args[i].ref;
+ current_arg = old_args[i].ref();
if (!allow_locations && current_arg.contains('.')) {
result.AppendErrorWithFormat(
"Breakpoint locations not allowed, saw location: %s.",
@@ -146,16 +146,16 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
} else
names_found.insert(current_arg);
} else if ((i + 2 < old_args.size()) &&
- BreakpointID::IsRangeIdentifier(old_args[i + 1].ref) &&
+ BreakpointID::IsRangeIdentifier(old_args[i + 1].ref()) &&
BreakpointID::IsValidIDExpression(current_arg) &&
- BreakpointID::IsValidIDExpression(old_args[i + 2].ref)) {
+ BreakpointID::IsValidIDExpression(old_args[i + 2].ref())) {
range_from = current_arg;
- range_to = old_args[i + 2].ref;
+ range_to = old_args[i + 2].ref();
is_range = true;
i = i + 2;
} else {
// See if user has specified id.*
- llvm::StringRef tmp_str = old_args[i].ref;
+ llvm::StringRef tmp_str = old_args[i].ref();
size_t pos = tmp_str.find('.');
if (pos != llvm::StringRef::npos) {
llvm::StringRef bp_id_str = tmp_str.substr(0, pos);
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index b718e2aeea5c..46b8f25c5668 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -257,9 +257,8 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
EvaluateExpressionOptions(), nullptr, error));
if (error.Fail()) {
- if (log)
- log->Printf("Error getting condition expression: %s.",
- error.AsCString());
+ LLDB_LOGF(log, "Error getting condition expression: %s.",
+ error.AsCString());
m_user_expression_sp.reset();
return true;
}
@@ -312,8 +311,8 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
ret = result_value_sp->IsLogicalTrue(error);
if (log) {
if (error.Success()) {
- log->Printf("Condition successfully evaluated, result is %s.\n",
- ret ? "true" : "false");
+ LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n",
+ ret ? "true" : "false");
} else {
error.SetErrorString(
"Failed to get an integer result from the expression");
@@ -408,8 +407,8 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
if (log) {
StreamString s;
GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
- should_stop ? "stopping" : "continuing");
+ LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(),
+ should_stop ? "stopping" : "continuing");
}
return should_stop;
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp
index f6f279dc382a..0d4c6173c3c5 100644
--- a/source/Breakpoint/BreakpointOptions.cpp
+++ b/source/Breakpoint/BreakpointOptions.cpp
@@ -309,7 +309,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
}
}
- auto bp_options = llvm::make_unique<BreakpointOptions>(
+ auto bp_options = std::make_unique<BreakpointOptions>(
condition_ref.str().c_str(), enabled,
ignore_count, one_shot, auto_continue);
if (cmd_data_up) {
diff --git a/source/Breakpoint/BreakpointResolver.cpp b/source/Breakpoint/BreakpointResolver.cpp
index b3224aa91753..e0a4e6ac6712 100644
--- a/source/Breakpoint/BreakpointResolver.cpp
+++ b/source/Breakpoint/BreakpointResolver.cpp
@@ -34,7 +34,8 @@ using namespace lldb;
// BreakpointResolver:
const char *BreakpointResolver::g_ty_to_name[] = {"FileAndLine", "Address",
"SymbolName", "SourceRegex",
- "Exception", "Unknown"};
+ "Python", "Exception",
+ "Unknown"};
const char *BreakpointResolver::g_option_names[static_cast<uint32_t>(
BreakpointResolver::OptionNames::LastOptionName)] = {
@@ -294,18 +295,18 @@ void BreakpointResolver::AddLocation(SearchFilter &filter,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Address line_start = sc.line_entry.range.GetBaseAddress();
if (!line_start.IsValid()) {
- if (log)
- log->Printf("error: Unable to set breakpoint %s at file address "
- "0x%" PRIx64 "\n",
- log_ident.str().c_str(), line_start.GetFileAddress());
+ LLDB_LOGF(log,
+ "error: Unable to set breakpoint %s at file address "
+ "0x%" PRIx64 "\n",
+ log_ident.str().c_str(), line_start.GetFileAddress());
return;
}
if (!filter.AddressPasses(line_start)) {
- if (log)
- log->Printf("Breakpoint %s at file address 0x%" PRIx64
- " didn't pass the filter.\n",
- log_ident.str().c_str(), line_start.GetFileAddress());
+ LLDB_LOGF(log,
+ "Breakpoint %s at file address 0x%" PRIx64
+ " didn't pass the filter.\n",
+ log_ident.str().c_str(), line_start.GetFileAddress());
}
// If the line number is before the prologue end, move it there...
@@ -329,8 +330,8 @@ void BreakpointResolver::AddLocation(SearchFilter &filter,
if (log && bp_loc_sp && !m_breakpoint->IsInternal()) {
StreamString s;
bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf("Added location (skipped prologue: %s): %s \n",
- skipped_prologue ? "yes" : "no", s.GetData());
+ LLDB_LOGF(log, "Added location (skipped prologue: %s): %s \n",
+ skipped_prologue ? "yes" : "no", s.GetData());
}
}
diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp
index 8a6fd6a2692c..b98568098b4b 100644
--- a/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -120,10 +120,8 @@ void BreakpointResolverAddress::ResolveBreakpointInModules(
BreakpointResolver::ResolveBreakpointInModules(filter, modules);
}
-Searcher::CallbackReturn
-BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) {
+Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
assert(m_breakpoint != nullptr);
if (filter.AddressPasses(m_addr)) {
@@ -149,8 +147,7 @@ BreakpointResolverAddress::SearchCallback(SearchFilter &filter,
bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Added location: %s\n", s.GetData());
+ LLDB_LOGF(log, "Added location: %s\n", s.GetData());
}
} else {
BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0);
diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp
index a6095be31647..2b26f65816bd 100644
--- a/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -198,10 +198,8 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
}
}
-Searcher::CallbackReturn
-BreakpointResolverFileLine::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr, bool containing) {
+Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
SymbolContextList sc_list;
assert(m_breakpoint != nullptr);
diff --git a/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp
index 0b2485245b72..3cb04263c6dc 100644
--- a/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -20,11 +20,11 @@ using namespace lldb_private;
// BreakpointResolverFileRegex:
BreakpointResolverFileRegex::BreakpointResolverFileRegex(
- Breakpoint *bkpt, RegularExpression &regex,
+ Breakpoint *bkpt, RegularExpression regex,
const std::unordered_set<std::string> &func_names, bool exact_match)
: BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver),
- m_regex(regex), m_exact_match(exact_match), m_function_names(func_names) {
-}
+ m_regex(std::move(regex)), m_exact_match(exact_match),
+ m_function_names(func_names) {}
BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {}
@@ -69,7 +69,8 @@ BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData(
}
}
- return new BreakpointResolverFileRegex(bkpt, regex, names_set, exact_match);
+ return new BreakpointResolverFileRegex(bkpt, std::move(regex), names_set,
+ exact_match);
}
StructuredData::ObjectSP
@@ -93,10 +94,8 @@ BreakpointResolverFileRegex::SerializeToStructuredData() {
return WrapOptionsDict(options_dict_sp);
}
-Searcher::CallbackReturn
-BreakpointResolverFileRegex::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr, bool containing) {
+Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
assert(m_breakpoint != nullptr);
if (!context.target_sp)
diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp
index 3ad2e8867f2a..ba9c88c7eae8 100644
--- a/source/Breakpoint/BreakpointResolverName.cpp
+++ b/source/Breakpoint/BreakpointResolverName.cpp
@@ -31,7 +31,8 @@ BreakpointResolverName::BreakpointResolverName(
m_class_name(), m_regex(), m_match_type(type), m_language(language),
m_skip_prologue(skip_prologue) {
if (m_match_type == Breakpoint::Regexp) {
- if (!m_regex.Compile(llvm::StringRef::withNullAsEmpty(name_cstr))) {
+ m_regex = RegularExpression(llvm::StringRef::withNullAsEmpty(name_cstr));
+ if (!m_regex.IsValid()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -70,12 +71,12 @@ BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt,
}
BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt,
- RegularExpression &func_regex,
+ RegularExpression func_regex,
lldb::LanguageType language,
lldb::addr_t offset,
bool skip_prologue)
: BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
- m_class_name(nullptr), m_regex(func_regex),
+ m_class_name(nullptr), m_regex(std::move(func_regex)),
m_match_type(Breakpoint::Regexp), m_language(language),
m_skip_prologue(skip_prologue) {}
@@ -125,9 +126,8 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
success = options_dict.GetValueForKeyAsString(
GetKey(OptionNames::RegexString), regex_text);
if (success) {
- RegularExpression regex(regex_text);
- return new BreakpointResolverName(bkpt, regex, language, offset,
- skip_prologue);
+ return new BreakpointResolverName(bkpt, RegularExpression(regex_text),
+ language, offset, skip_prologue);
} else {
StructuredData::Array *names_array;
success = options_dict.GetValueForKeyAsArray(
@@ -250,8 +250,7 @@ void BreakpointResolverName::AddNameLookup(ConstString name,
Searcher::CallbackReturn
BreakpointResolverName::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) {
+ SymbolContext &context, Address *addr) {
SymbolContextList func_list;
// SymbolContextList sym_list;
@@ -272,7 +271,6 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
bool filter_by_language = (m_language != eLanguageTypeUnknown);
const bool include_symbols = !filter_by_cu;
const bool include_inlines = true;
- const bool append = true;
switch (m_match_type) {
case Breakpoint::Exact:
@@ -281,7 +279,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
const size_t start_func_idx = func_list.GetSize();
context.module_sp->FindFunctions(
lookup.GetLookupName(), nullptr, lookup.GetNameTypeMask(),
- include_symbols, include_inlines, append, func_list);
+ include_symbols, include_inlines, func_list);
const size_t end_func_idx = func_list.GetSize();
@@ -295,7 +293,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
context.module_sp->FindFunctions(
m_regex,
!filter_by_cu, // include symbols only if we aren't filtering by CU
- include_inlines, append, func_list);
+ include_inlines, func_list);
}
break;
case Breakpoint::Glob:
@@ -388,7 +386,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter,
if (log) {
StreamString s;
bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf("Added location: %s\n", s.GetData());
+ LLDB_LOGF(log, "Added location: %s\n", s.GetData());
}
}
}
diff --git a/source/Breakpoint/BreakpointResolverScripted.cpp b/source/Breakpoint/BreakpointResolverScripted.cpp
index 8363795a4d7f..288fd37c1c79 100644
--- a/source/Breakpoint/BreakpointResolverScripted.cpp
+++ b/source/Breakpoint/BreakpointResolverScripted.cpp
@@ -29,8 +29,7 @@ BreakpointResolverScripted::BreakpointResolverScripted(
Breakpoint *bkpt,
const llvm::StringRef class_name,
lldb::SearchDepth depth,
- StructuredDataImpl *args_data,
- ScriptInterpreter &script_interp)
+ StructuredDataImpl *args_data)
: BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) {
CreateImplementationIfNeeded();
@@ -68,45 +67,25 @@ BreakpointResolverScripted::CreateFromStructuredData(
llvm::StringRef class_name;
bool success;
- if (!bkpt)
- return nullptr;
-
success = options_dict.GetValueForKeyAsString(
GetKey(OptionNames::PythonClassName), class_name);
if (!success) {
error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
return nullptr;
}
- lldb::SearchDepth depth;
- int depth_as_int;
- success = options_dict.GetValueForKeyAsInteger(
- GetKey(OptionNames::SearchDepth), depth_as_int);
- if (!success) {
- error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
- return nullptr;
- }
- if (depth_as_int >= (int) OptionNames::LastOptionName) {
- error.SetErrorString("BRFL::CFSD: Invalid value for search depth.");
- return nullptr;
- }
- depth = (lldb::SearchDepth) depth_as_int;
+ // The Python function will actually provide the search depth, this is a
+ // placeholder.
+ lldb::SearchDepth depth = lldb::eSearchDepthTarget;
StructuredDataImpl *args_data_impl = new StructuredDataImpl();
- StructuredData::Dictionary *args_dict = new StructuredData::Dictionary();
+ StructuredData::Dictionary *args_dict = nullptr;
success = options_dict.GetValueForKeyAsDictionary(
GetKey(OptionNames::ScriptArgs), args_dict);
if (success) {
- // FIXME: The resolver needs a copy of the ARGS dict that it can own,
- // so I need to make a copy constructor for the Dictionary so I can pass
- // that to it here. For now the args are empty.
- //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict);
-
+ args_data_impl->SetObjectSP(args_dict->shared_from_this());
}
- ScriptInterpreter *script_interp = bkpt->GetTarget()
- .GetDebugger()
- .GetScriptInterpreter();
- return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl,
- *script_interp);
+ return new BreakpointResolverScripted(bkpt, class_name, depth,
+ args_data_impl);
}
StructuredData::ObjectSP
@@ -116,6 +95,10 @@ BreakpointResolverScripted::SerializeToStructuredData() {
options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
m_class_name);
+ if (m_args_ptr->IsValid())
+ options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs),
+ m_args_ptr->GetObjectSP());
+
return WrapOptionsDict(options_dict_sp);
}
@@ -123,10 +106,8 @@ ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
return m_breakpoint->GetTarget().GetDebugger().GetScriptInterpreter();
}
-Searcher::CallbackReturn
-BreakpointResolverScripted::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) {
+Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
assert(m_breakpoint != nullptr);
bool should_continue = true;
if (!m_implementation_sp)
@@ -173,11 +154,10 @@ void BreakpointResolverScripted::Dump(Stream *s) const {}
lldb::BreakpointResolverSP
BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) {
- ScriptInterpreter *script_interp = GetScriptInterpreter();
// FIXME: Have to make a copy of the arguments from the m_args_ptr and then
// pass that to the new resolver.
lldb::BreakpointResolverSP ret_sp(
- new BreakpointResolverScripted(&breakpoint, m_class_name,
- m_depth, nullptr, *script_interp));
+ new BreakpointResolverScripted(&breakpoint, m_class_name, m_depth,
+ nullptr));
return ret_sp;
}
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index e8a926527d24..17dcda13e9b9 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -13,10 +13,11 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Expression/UserExpression.h"
-#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
@@ -30,14 +31,22 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size,
m_watch_write(0), m_watch_was_read(0), m_watch_was_written(0),
m_ignore_count(0), m_false_alarms(0), m_decl_str(), m_watch_spec_str(),
m_type(), m_error(), m_options(), m_being_created(true) {
+
if (type && type->IsValid())
m_type = *type;
else {
// If we don't have a known type, then we force it to unsigned int of the
// right size.
- ClangASTContext *ast_context = target.GetScratchClangASTContext();
- m_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint,
- 8 * size);
+ auto type_system_or_err =
+ target.GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS),
+ std::move(err), "Failed to set type.");
+ } else {
+ m_type = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingUint, 8 * size);
+ }
}
// Set the initial value of the watched variable:
diff --git a/source/Breakpoint/WatchpointOptions.cpp b/source/Breakpoint/WatchpointOptions.cpp
index 7dd130a3072c..cd5ef930e5dc 100644
--- a/source/Breakpoint/WatchpointOptions.cpp
+++ b/source/Breakpoint/WatchpointOptions.cpp
@@ -170,9 +170,8 @@ void WatchpointOptions::CommandBaton::GetDescription(
s->IndentMore();
if (data && data->user_source.GetSize() > 0) {
- const size_t num_strings = data->user_source.GetSize();
- for (size_t i = 0; i < num_strings; ++i) {
- s->Indent(data->user_source.GetStringAtIndex(i));
+ for (const std::string &line : data->user_source) {
+ s->Indent(line);
s->EOL();
}
} else {
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index 5d2fb3d67f57..469a6bbbadf6 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -71,10 +71,9 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
return handled;
}
-int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- request.SetWordComplete(true);
+void CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
// Find some way to switch "include support files..."
SourceFileCompleter completer(interpreter, false, request);
@@ -85,20 +84,18 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return request.GetNumberOfMatches();
}
-static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
- bool only_directories, StringList &matches,
- TildeExpressionResolver &Resolver) {
- matches.Clear();
-
+static void DiskFilesOrDirectories(const llvm::Twine &partial_name,
+ bool only_directories,
+ CompletionRequest &request,
+ TildeExpressionResolver &Resolver) {
llvm::SmallString<256> CompletionBuffer;
llvm::SmallString<256> Storage;
partial_name.toVector(CompletionBuffer);
if (CompletionBuffer.size() >= PATH_MAX)
- return matches.GetSize();
+ return;
namespace path = llvm::sys::path;
@@ -126,10 +123,10 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
for (const auto &S : MatchSet) {
Resolved = S.getKey();
path::append(Resolved, path::get_separator());
- matches.AppendString(Resolved);
+ request.AddCompletion(Resolved, "", CompletionMode::Partial);
}
}
- return matches.GetSize();
+ return;
}
// If there was no trailing slash, then we're done as soon as we resolve
@@ -138,8 +135,8 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
if (FirstSep == llvm::StringRef::npos) {
// Make sure it ends with a separator.
path::append(CompletionBuffer, path::get_separator());
- matches.AppendString(CompletionBuffer);
- return matches.GetSize();
+ request.AddCompletion(CompletionBuffer, "", CompletionMode::Partial);
+ return;
}
// We want to keep the form the user typed, so we special case this to
@@ -219,51 +216,56 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name,
path::append(CompletionBuffer, path::get_separator());
}
- matches.AppendString(CompletionBuffer);
+ CompletionMode mode =
+ is_dir ? CompletionMode::Partial : CompletionMode::Normal;
+ request.AddCompletion(CompletionBuffer, "", mode);
}
+}
- return matches.GetSize();
+static void DiskFilesOrDirectories(const llvm::Twine &partial_name,
+ bool only_directories, StringList &matches,
+ TildeExpressionResolver &Resolver) {
+ CompletionResult result;
+ std::string partial_name_str = partial_name.str();
+ CompletionRequest request(partial_name_str, partial_name_str.size(), result);
+ DiskFilesOrDirectories(partial_name, only_directories, request, Resolver);
+ result.GetMatches(matches);
}
-static int DiskFilesOrDirectories(CompletionRequest &request,
- bool only_directories) {
- request.SetWordComplete(false);
+static void DiskFilesOrDirectories(CompletionRequest &request,
+ bool only_directories) {
StandardTildeExpressionResolver resolver;
- StringList matches;
DiskFilesOrDirectories(request.GetCursorArgumentPrefix(), only_directories,
- matches, resolver);
- request.AddCompletions(matches);
- return request.GetNumberOfMatches();
+ request, resolver);
}
-int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- return DiskFilesOrDirectories(request, /*only_dirs*/ false);
+void CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ DiskFilesOrDirectories(request, /*only_dirs*/ false);
}
-int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
- StringList &matches,
- TildeExpressionResolver &Resolver) {
- return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
+void CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name,
+ StringList &matches,
+ TildeExpressionResolver &Resolver) {
+ DiskFilesOrDirectories(partial_file_name, false, matches, Resolver);
}
-int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- return DiskFilesOrDirectories(request, /*only_dirs*/ true);
+void CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ DiskFilesOrDirectories(request, /*only_dirs*/ true);
}
-int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
- StringList &matches,
- TildeExpressionResolver &Resolver) {
- return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
+void CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
+ StringList &matches,
+ TildeExpressionResolver &Resolver) {
+ DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
}
-int CommandCompletions::Modules(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- request.SetWordComplete(true);
+void CommandCompletions::Modules(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
ModuleCompleter completer(interpreter, request);
if (searcher == nullptr) {
@@ -273,13 +275,11 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return request.GetNumberOfMatches();
}
-int CommandCompletions::Symbols(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- request.SetWordComplete(true);
+void CommandCompletions::Symbols(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
SymbolCompleter completer(interpreter, request);
if (searcher == nullptr) {
@@ -289,12 +289,11 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter,
} else {
completer.DoCompletion(searcher);
}
- return request.GetNumberOfMatches();
}
-int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
+void CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
// Cache the full setting name list
static StringList g_property_names;
if (g_property_names.GetSize() == 0) {
@@ -309,38 +308,27 @@ int CommandCompletions::SettingsNames(CommandInterpreter &interpreter,
}
}
- size_t exact_matches_idx = SIZE_MAX;
- StringList matches;
- g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), matches,
- exact_matches_idx);
- request.SetWordComplete(exact_matches_idx != SIZE_MAX);
- request.AddCompletions(matches);
- return request.GetNumberOfMatches();
+ for (const std::string &s : g_property_names)
+ request.TryCompleteCurrentArg(s);
}
-int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- StringList new_matches;
- std::size_t num_matches = PluginManager::AutoCompletePlatformName(
- request.GetCursorArgumentPrefix(), new_matches);
- request.SetWordComplete(num_matches == 1);
- request.AddCompletions(new_matches);
- return request.GetNumberOfMatches();
+void CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ PluginManager::AutoCompletePlatformName(request.GetCursorArgumentPrefix(),
+ request);
}
-int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- const uint32_t num_matches = ArchSpec::AutoComplete(request);
- request.SetWordComplete(num_matches == 1);
- return num_matches;
+void CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ ArchSpec::AutoComplete(request);
}
-int CommandCompletions::VariablePath(CommandInterpreter &interpreter,
- CompletionRequest &request,
- SearchFilter *searcher) {
- return Variable::AutoComplete(interpreter.GetExecutionContext(), request);
+void CommandCompletions::VariablePath(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ Variable::AutoComplete(interpreter.GetExecutionContext(), request);
}
CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
@@ -368,8 +356,7 @@ lldb::SearchDepth CommandCompletions::SourceFileCompleter::GetDepth() {
Searcher::CallbackReturn
CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
SymbolContext &context,
- Address *addr,
- bool complete) {
+ Address *addr) {
if (context.comp_unit != nullptr) {
if (m_include_support_files) {
FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
@@ -411,15 +398,14 @@ CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
return Searcher::eCallbackReturnContinue;
}
-size_t
-CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) {
+void CommandCompletions::SourceFileCompleter::DoCompletion(
+ SearchFilter *filter) {
filter->Search(*this);
// Now convert the filelist to completions:
for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
m_request.AddCompletion(
m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
}
- return m_request.GetNumberOfMatches();
}
// SymbolCompleter
@@ -448,7 +434,7 @@ CommandCompletions::SymbolCompleter::SymbolCompleter(
pos = regex_str.insert(pos, '\\');
pos = find_if(pos + 2, regex_str.end(), regex_chars);
}
- m_regex.Compile(regex_str);
+ m_regex = RegularExpression(regex_str);
}
lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() {
@@ -456,22 +442,24 @@ lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() {
}
Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback(
- SearchFilter &filter, SymbolContext &context, Address *addr,
- bool complete) {
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
if (context.module_sp) {
SymbolContextList sc_list;
const bool include_symbols = true;
const bool include_inlines = true;
- const bool append = true;
context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines,
- append, sc_list);
+ sc_list);
SymbolContext sc;
// Now add the functions & symbols to the list - only add if unique:
for (uint32_t i = 0; i < sc_list.GetSize(); i++) {
if (sc_list.GetContextAtIndex(i, sc)) {
ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
- if (!func_name.IsEmpty())
+ // Ensure that the function name matches the regex. This is more than a
+ // sanity check. It is possible that the demangled function name does
+ // not start with the prefix, for example when it's in an anonymous
+ // namespace.
+ if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef()))
m_match_set.insert(func_name);
}
}
@@ -479,13 +467,11 @@ Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback(
return Searcher::eCallbackReturnContinue;
}
-size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
+void CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
for (pos = m_match_set.begin(); pos != end; pos++)
m_request.AddCompletion((*pos).GetCString());
-
- return m_request.GetNumberOfMatches();
}
// ModuleCompleter
@@ -502,8 +488,7 @@ lldb::SearchDepth CommandCompletions::ModuleCompleter::GetDepth() {
}
Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
- SearchFilter &filter, SymbolContext &context, Address *addr,
- bool complete) {
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
if (context.module_sp) {
const char *cur_file_name =
context.module_sp->GetFileSpec().GetFilename().GetCString();
@@ -526,7 +511,6 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
return Searcher::eCallbackReturnContinue;
}
-size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
+void CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
filter->Search(*this);
- return m_request.GetNumberOfMatches();
}
diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp
index 957de475569c..7ba0b250fbd5 100644
--- a/source/Commands/CommandObjectApropos.cpp
+++ b/source/Commands/CommandObjectApropos.cpp
@@ -44,7 +44,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
const size_t argc = args.GetArgumentCount();
if (argc == 1) {
- auto search_word = args[0].ref;
+ auto search_word = args[0].ref();
if (!search_word.empty()) {
// The bulk of the work must be done inside the Command Interpreter,
// since the command dictionary is private.
@@ -63,13 +63,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
if (commands_found.GetSize() > 0) {
result.AppendMessageWithFormat(
"The following commands may relate to '%s':\n", args[0].c_str());
- size_t max_len = 0;
-
- for (size_t i = 0; i < commands_found.GetSize(); ++i) {
- size_t len = strlen(commands_found.GetStringAtIndex(i));
- if (len > max_len)
- max_len = len;
- }
+ const size_t max_len = commands_found.GetMaxStringLength();
for (size_t i = 0; i < commands_found.GetSize(); ++i)
m_interpreter.OutputFormattedHelpText(
@@ -85,7 +79,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
const bool dump_qualified_name = true;
result.AppendMessageWithFormatv(
"\nThe following settings variables may relate to '{0}': \n\n",
- args[0].ref);
+ args[0].ref());
for (size_t i = 0; i < num_properties; ++i)
properties[i]->DumpDescription(
m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index c33f3834cb13..ad699975b507 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -16,6 +16,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
@@ -44,21 +45,9 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
// Modifiable Breakpoint Options
#pragma mark Modify::CommandOptions
-static constexpr OptionDefinition g_breakpoint_modify_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
- { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
- { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
- { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
- { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
- { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
- { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
- { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable the breakpoint." },
- { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disable the breakpoint." },
- { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_modify
+#include "CommandOptions.inc"
+
class lldb_private::BreakpointOptionGroup : public OptionGroup
{
public:
@@ -153,9 +142,7 @@ public:
}
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -171,7 +158,7 @@ public:
{
if (!m_commands.empty())
{
- auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+ auto cmd_data = std::make_unique<BreakpointOptions::CommandData>();
for (std::string &str : m_commands)
cmd_data->user_source.AppendString(str);
@@ -192,12 +179,9 @@ public:
BreakpointOptions m_bp_opts;
};
-static constexpr OptionDefinition g_breakpoint_dummy_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
- "which prime new targets." },
- // clang-format on
-};
+
+#define LLDB_OPTIONS_breakpoint_dummy
+#include "CommandOptions.inc"
class BreakpointDummyOptionGroup : public OptionGroup
{
@@ -221,9 +205,7 @@ public:
m_use_dummy = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -237,88 +219,8 @@ public:
};
-// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
-// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
-#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_10)
-#define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
-#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10)
-#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2)
-#define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
-#define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
-
-static constexpr OptionDefinition g_breakpoint_set_options[] = {
- // clang-format off
- { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
- "multiple times to specify multiple shared libraries." },
- { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
- { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
- "lldb only looks for files that are #included if they use the standard include "
- "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
- "#included, set target.inline-breakpoint-strategy to \"always\"." },
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
-
- // Comment out this option for the moment, as we don't actually use it, but
- // will in the future. This way users won't see it, but the infrastructure is
- // left in place.
- // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
- // "Set the breakpoint by source location at this particular column."},
-
- { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
- "a particular binary, then the address will be converted to a \"file\" "
- "address, so that the breakpoint will track that binary+offset no matter where "
- "the binary eventually loads. Alternately, if you also specify the module - "
- "with the -s option - then the address will be treated as a file address in "
- "that module, and resolved accordingly. Again, this will allow lldb to track "
- "that offset on subsequent reloads. The module need not have been loaded at "
- "the time you specify this breakpoint, and will get resolved when the module "
- "is loaded." },
- { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
- "one breakpoint for multiple names" },
- { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
- "functions. Can be repeated multiple times." },
- { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
- "namespaces and all arguments, and for Objective-C this means a full function "
- "prototype with class and selector. Can be repeated multiple times to make "
- "one breakpoint for multiple names." },
- { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
- "make one breakpoint for multiple Selectors." },
- { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
- "make one breakpoint for multiple methods." },
- { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
- "the function name(s)." },
- { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
- "ignored). Can be repeated multiple times to make one breakpoint for multiple "
- "symbols." },
- { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
- "against the source text in a source file or files specified with the -f "
- "option. The -f option can be specified more than once. If no source files "
- "are specified, uses the current \"default source file\". If you want to "
- "match against all source files, pass the \"--all-files\" option." },
- { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "All files are searched for source pattern matches." },
- { LLDB_OPT_SET_11, true, "python-class", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that implement a scripted breakpoint." },
- { LLDB_OPT_SET_11, false, "python-class-key", 'k', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The key for a key/value pair passed to the class that implements a scripted breakpoint. Can be specified more than once." },
- { LLDB_OPT_SET_11, false, "python-class-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The value for the previous key in the pair passed to the class that implements a scripted breakpoint. Can be specified more than once." },
- { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
- "options, on throw but not catch.)" },
- { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
- { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
-
- // Don't add this option till it actually does something useful...
- // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
- // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
-
- { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
- "(note: currently only implemented for setting breakpoints on identifiers). "
- "If not set the target.language setting is used." },
- { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
- "If not set the target.skip-prologue setting is used." },
- { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
- { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
- "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
- { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
- "setting is used." },
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_set
+#include "CommandOptions.inc"
// CommandObjectBreakpointSet
@@ -340,15 +242,18 @@ public:
interpreter, "breakpoint set",
"Sets a breakpoint or set of breakpoints in the executable.",
"breakpoint set <cmd-options>"),
- m_bp_opts(), m_options() {
- // We're picking up all the normal options, commands and disable.
- m_all_options.Append(&m_bp_opts,
- LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
- LLDB_OPT_SET_ALL);
- m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
- m_all_options.Append(&m_options);
- m_all_options.Finalize();
- }
+ m_bp_opts(), m_python_class_options("scripted breakpoint", 'P'),
+ m_options() {
+ // We're picking up all the normal options, commands and disable.
+ m_all_options.Append(&m_python_class_options, LLDB_OPT_SET_1,
+ LLDB_OPT_SET_11);
+ m_all_options.Append(&m_bp_opts,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
+ LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
+ }
~CommandObjectBreakpointSet() override = default;
@@ -451,14 +356,6 @@ public:
m_hardware = true;
break;
- case 'k': {
- if (m_current_key.empty())
- m_current_key.assign(option_arg);
- else
- error.SetErrorStringWithFormat("Key: %s missing value.",
- m_current_key.c_str());
-
- } break;
case 'K': {
bool success;
bool value;
@@ -540,10 +437,6 @@ public:
m_source_text_regexp.assign(option_arg);
break;
- case 'P':
- m_python_class.assign(option_arg);
- break;
-
case 'r':
m_func_regexp.assign(option_arg);
break;
@@ -557,16 +450,6 @@ public:
m_func_name_type_mask |= eFunctionNameTypeSelector;
break;
- case 'v': {
- if (!m_current_key.empty()) {
- m_extra_args_sp->AddStringItem(m_current_key, option_arg);
- m_current_key.clear();
- }
- else
- error.SetErrorStringWithFormat("Value \"%s\" missing matching key.",
- option_arg.str().c_str());
- } break;
-
case 'w': {
bool success;
m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
@@ -581,9 +464,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -611,8 +492,6 @@ public:
m_exception_extra_args.Clear();
m_move_to_nearest_code = eLazyBoolCalculate;
m_source_regex_func_names.clear();
- m_python_class.clear();
- m_extra_args_sp = std::make_shared<StructuredData::Dictionary>();
m_current_key.clear();
}
@@ -644,21 +523,12 @@ public:
Args m_exception_extra_args;
LazyBool m_move_to_nearest_code;
std::unordered_set<std::string> m_source_regex_func_names;
- std::string m_python_class;
- StructuredData::DictionarySP m_extra_args_sp;
std::string m_current_key;
};
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
-
- if (target == nullptr) {
- result.AppendError("Invalid target. Must set target before setting "
- "breakpoints (see 'target create' command).");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
// The following are the various types of breakpoints that could be set:
// 1). -f -l -p [-s -g] (setting breakpoint by source location)
@@ -673,7 +543,7 @@ protected:
BreakpointSetType break_type = eSetTypeInvalid;
- if (!m_options.m_python_class.empty())
+ if (!m_python_class_options.GetClassName().empty())
break_type = eSetTypeScripted;
else if (m_options.m_line_num != 0)
break_type = eSetTypeFileAndLine;
@@ -720,16 +590,11 @@ protected:
// Only check for inline functions if
LazyBool check_inlines = eLazyBoolCalculate;
- bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
- file,
- m_options.m_line_num,
- m_options.m_column,
- m_options.m_offset_addr,
- check_inlines,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code);
+ bp_sp = target.CreateBreakpoint(
+ &(m_options.m_modules), file, m_options.m_line_num,
+ m_options.m_column, m_options.m_offset_addr, check_inlines,
+ m_options.m_skip_prologue, internal, m_options.m_hardware,
+ m_options.m_move_to_nearest_code);
} break;
case eSetTypeAddress: // Breakpoint by address
@@ -741,12 +606,11 @@ protected:
if (num_modules_specified == 1) {
const FileSpec *file_spec =
m_options.m_modules.GetFileSpecPointerAtIndex(0);
- bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
- internal, file_spec,
- m_options.m_hardware);
+ bp_sp = target.CreateAddressInModuleBreakpoint(
+ m_options.m_load_addr, internal, file_spec, m_options.m_hardware);
} else if (num_modules_specified == 0) {
- bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
- m_options.m_hardware);
+ bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal,
+ m_options.m_hardware);
} else {
result.AppendError("Only one shared library can be specified for "
"address breakpoints.");
@@ -762,38 +626,29 @@ protected:
if (name_type_mask == 0)
name_type_mask = eFunctionNameTypeAuto;
- bp_sp = target->CreateBreakpoint(&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options.m_func_names,
- name_type_mask,
- m_options.m_language,
- m_options.m_offset_addr,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware);
+ bp_sp = target.CreateBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_func_names, name_type_mask, m_options.m_language,
+ m_options.m_offset_addr, m_options.m_skip_prologue, internal,
+ m_options.m_hardware);
} break;
case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
// name
{
RegularExpression regexp(m_options.m_func_regexp);
- if (!regexp.IsValid()) {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ if (llvm::Error err = regexp.GetError()) {
result.AppendErrorWithFormat(
"Function name regular expression could not be compiled: \"%s\"",
- err_str);
+ llvm::toString(std::move(err)).c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules),
- &(m_options.m_filenames),
- regexp,
- m_options.m_language,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware);
+ bp_sp = target.CreateFuncRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp),
+ m_options.m_language, m_options.m_skip_prologue, internal,
+ m_options.m_hardware);
}
break;
case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
@@ -813,39 +668,29 @@ protected:
}
RegularExpression regexp(m_options.m_source_text_regexp);
- if (!regexp.IsValid()) {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ if (llvm::Error err = regexp.GetError()) {
result.AppendErrorWithFormat(
"Source text regular expression could not be compiled: \"%s\"",
- err_str);
+ llvm::toString(std::move(err)).c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- bp_sp =
- target->CreateSourceRegexBreakpoint(&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options
- .m_source_regex_func_names,
- regexp,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code);
+ bp_sp = target.CreateSourceRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_source_regex_func_names, std::move(regexp), internal,
+ m_options.m_hardware, m_options.m_move_to_nearest_code);
} break;
case eSetTypeException: {
Status precond_error;
- bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language,
- m_options.m_catch_bp,
- m_options.m_throw_bp,
- internal,
- &m_options
- .m_exception_extra_args,
- &precond_error);
+ bp_sp = target.CreateExceptionBreakpoint(
+ m_options.m_exception_language, m_options.m_catch_bp,
+ m_options.m_throw_bp, internal, &m_options.m_exception_extra_args,
+ &precond_error);
if (precond_error.Fail()) {
result.AppendErrorWithFormat(
"Error setting extra exception arguments: %s",
precond_error.AsCString());
- target->RemoveBreakpointByID(bp_sp->GetID());
+ target.RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -853,18 +698,15 @@ protected:
case eSetTypeScripted: {
Status error;
- bp_sp = target->CreateScriptedBreakpoint(m_options.m_python_class,
- &(m_options.m_modules),
- &(m_options.m_filenames),
- false,
- m_options.m_hardware,
- m_options.m_extra_args_sp,
- &error);
+ bp_sp = target.CreateScriptedBreakpoint(
+ m_python_class_options.GetClassName().c_str(), &(m_options.m_modules),
+ &(m_options.m_filenames), false, m_options.m_hardware,
+ m_python_class_options.GetStructuredData(), &error);
if (error.Fail()) {
result.AppendErrorWithFormat(
"Error setting extra exception arguments: %s",
error.AsCString());
- target->RemoveBreakpointByID(bp_sp->GetID());
+ target.RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -880,11 +722,11 @@ protected:
if (!m_options.m_breakpoint_names.empty()) {
Status name_error;
for (auto name : m_options.m_breakpoint_names) {
- target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
+ target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
if (name_error.Fail()) {
result.AppendErrorWithFormat("Invalid breakpoint name: %s",
name.c_str());
- target->RemoveBreakpointByID(bp_sp->GetID());
+ target.RemoveBreakpointByID(bp_sp->GetID());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -897,7 +739,7 @@ protected:
const bool show_locations = false;
bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
show_locations);
- if (target == GetDebugger().GetDummyTarget())
+ if (&target == &GetDummyTarget())
output_stream.Printf("Breakpoint set in dummy target, will get copied "
"into future targets.\n");
else {
@@ -919,12 +761,12 @@ protected:
}
private:
- bool GetDefaultFile(Target *target, FileSpec &file,
+ bool GetDefaultFile(Target &target, FileSpec &file,
CommandReturnObject &result) {
uint32_t default_line;
// First use the Source Manager's default file. Then use the current stack
// frame's file.
- if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
+ if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
if (cur_frame == nullptr) {
result.AppendError(
@@ -954,6 +796,7 @@ private:
BreakpointOptionGroup m_bp_opts;
BreakpointDummyOptionGroup m_dummy_options;
+ OptionGroupPythonClassWithDict m_python_class_options;
CommandOptions m_options;
OptionGroupOptions m_all_options;
};
@@ -993,20 +836,15 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -1016,7 +854,7 @@ protected:
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *bp =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocation *location =
bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
@@ -1062,17 +900,12 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget();
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1084,7 +917,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; enable all currently set breakpoints.
- target->EnableAllowedBreakpoints();
+ target.EnableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1093,7 +926,7 @@ protected:
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -1105,7 +938,7 @@ protected:
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *breakpoint =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocation *location =
breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
@@ -1175,17 +1008,11 @@ the second re-enables the first location.");
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
+ Target &target = GetSelectedOrDummyTarget();
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0) {
@@ -1196,7 +1023,7 @@ protected:
if (command.empty()) {
// No breakpoint selected; disable all currently set breakpoints.
- target->DisableAllowedBreakpoints();
+ target.DisableAllowedBreakpoints();
result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
" breakpoints)\n",
(uint64_t)num_breakpoints);
@@ -1206,7 +1033,7 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -1218,7 +1045,7 @@ protected:
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *breakpoint =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocation *location =
breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
@@ -1245,12 +1072,8 @@ protected:
// CommandObjectBreakpointList
#pragma mark List::CommandOptions
-static constexpr OptionDefinition g_breakpoint_list_options[] = {
- // FIXME: We need to add an "internal" command, and then add this sort of
- // thing to it. But I need to see it for now, and don't want to wait.
#define LLDB_OPTIONS_breakpoint_list
#include "CommandOptions.inc"
-};
#pragma mark List
@@ -1311,9 +1134,7 @@ public:
m_internal = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1339,18 +1160,12 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr) {
- result.AppendError("Invalid target. No current target or breakpoints.");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
const BreakpointList &breakpoints =
- target->GetBreakpointList(m_options.m_internal);
+ target.GetBreakpointList(m_options.m_internal);
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
+ target.GetBreakpointList(m_options.m_internal).GetListMutex(lock);
size_t num_breakpoints = breakpoints.GetSize();
@@ -1376,14 +1191,14 @@ protected:
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
Breakpoint *breakpoint =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
AddBreakpointDescription(&output_stream, breakpoint,
m_options.m_level);
}
@@ -1404,12 +1219,8 @@ private:
// CommandObjectBreakpointClear
#pragma mark Clear::CommandOptions
-static constexpr OptionDefinition g_breakpoint_clear_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_clear
+#include "CommandOptions.inc"
#pragma mark Clear
@@ -1449,9 +1260,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1474,12 +1283,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget();
// The following are the various types of breakpoints that could be
// cleared:
@@ -1491,9 +1295,9 @@ protected:
break_type = eClearTypeFileAndLine;
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- BreakpointList &breakpoints = target->GetBreakpointList();
+ BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
// Early return if there's no breakpoint at all.
@@ -1527,7 +1331,7 @@ protected:
if (loc_coll.GetSize() == 0) {
bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
ss.EOL();
- target->RemoveBreakpointByID(bp->GetID());
+ target.RemoveBreakpointByID(bp->GetID());
++num_cleared;
}
}
@@ -1557,12 +1361,8 @@ private:
};
// CommandObjectBreakpointDelete
-static constexpr OptionDefinition g_breakpoint_delete_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_delete
+#include "CommandOptions.inc"
#pragma mark Delete
@@ -1607,9 +1407,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1631,18 +1429,12 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1659,7 +1451,7 @@ protected:
true)) {
result.AppendMessage("Operation cancelled...");
} else {
- target->RemoveAllowedBreakpoints();
+ target.RemoveAllowedBreakpoints();
result.AppendMessageWithFormat(
"All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
(uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
@@ -1669,7 +1461,7 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
@@ -1682,7 +1474,7 @@ protected:
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *breakpoint =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
BreakpointLocation *location =
breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
// It makes no sense to try to delete individual locations, so we
@@ -1692,7 +1484,7 @@ protected:
++disable_count;
}
} else {
- target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
+ target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
++delete_count;
}
}
@@ -1711,15 +1503,9 @@ private:
};
// CommandObjectBreakpointName
+#define LLDB_OPTIONS_breakpoint_name
+#include "CommandOptions.inc"
-static constexpr OptionDefinition g_breakpoint_name_options[] = {
- // clang-format off
- {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
- {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
- {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
- {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A help string describing the purpose of this name."},
- // clang-format on
-};
class BreakpointNameOptionGroup : public OptionGroup {
public:
BreakpointNameOptionGroup()
@@ -1760,9 +1546,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1781,13 +1565,8 @@ public:
OptionValueString m_help_string;
};
-static constexpr OptionDefinition g_breakpoint_access_options[] = {
- // clang-format off
- {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
- {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
- {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_access
+#include "CommandOptions.inc"
class BreakpointAccessOptionGroup : public OptionGroup {
public:
@@ -1835,7 +1614,8 @@ public:
"invalid boolean value '%s' passed for -L option",
option_arg.str().c_str());
} break;
-
+ default:
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1897,23 +1677,16 @@ protected:
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- Target *target =
- GetSelectedOrDummyTarget(false);
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget(false);
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
// Make a pass through first to see that all the names are legal.
for (auto &entry : command.entries()) {
Status error;
- if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
+ if (!BreakpointID::StringIsBreakpointName(entry.ref(), error))
{
result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
entry.c_str(), error.AsCString());
@@ -1927,7 +1700,7 @@ protected:
if (m_bp_id.m_breakpoint.OptionWasSet())
{
lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
- bp_sp = target->GetBreakpointByID(bp_id);
+ bp_sp = target.GetBreakpointByID(bp_id);
if (!bp_sp)
{
result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
@@ -1940,18 +1713,17 @@ protected:
Status error;
for (auto &entry : command.entries()) {
ConstString name(entry.c_str());
- BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
+ BreakpointName *bp_name = target.FindBreakpointName(name, true, error);
if (!bp_name)
continue;
if (m_bp_id.m_help_string.OptionWasSet())
bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str());
if (bp_sp)
- target->ConfigureBreakpointName(*bp_name,
- *bp_sp->GetOptions(),
+ target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(),
m_access_options.GetPermissions());
else
- target->ConfigureBreakpointName(*bp_name,
+ target.ConfigureBreakpointName(*bp_name,
m_bp_opts.GetBreakpointOptions(),
m_access_options.GetPermissions());
}
@@ -1996,19 +1768,13 @@ protected:
return false;
}
- Target *target =
+ Target &target =
GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0) {
@@ -2020,7 +1786,7 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
@@ -2037,7 +1803,7 @@ protected:
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- target->AddNameToBreakpoint(bp_sp, bp_name, error);
+ target.AddNameToBreakpoint(bp_sp, bp_name, error);
}
}
@@ -2081,19 +1847,13 @@ protected:
return false;
}
- Target *target =
+ Target &target =
GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0) {
@@ -2105,7 +1865,7 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
@@ -2120,7 +1880,7 @@ protected:
lldb::break_id_t bp_id =
valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- target->RemoveNameFromBreakpoint(bp_sp, bp_name);
+ target.RemoveNameFromBreakpoint(bp_sp, bp_name);
}
}
@@ -2151,19 +1911,12 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target =
+ Target &target =
GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
-
std::vector<std::string> name_list;
if (command.empty()) {
- target->GetBreakpointNames(name_list);
+ target.GetBreakpointNames(name_list);
} else {
for (const Args::ArgEntry &arg : command)
{
@@ -2178,9 +1931,8 @@ protected:
const char *name = name_str.c_str();
// First print out the options for the name:
Status error;
- BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
- false,
- error);
+ BreakpointName *bp_name =
+ target.FindBreakpointName(ConstString(name), false, error);
if (bp_name)
{
StreamString s;
@@ -2191,9 +1943,9 @@ protected:
}
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
- BreakpointList &breakpoints = target->GetBreakpointList();
+ BreakpointList &breakpoints = target.GetBreakpointList();
bool any_set = false;
for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
if (bp_sp->MatchesName(name)) {
@@ -2246,12 +1998,8 @@ public:
// CommandObjectBreakpointRead
#pragma mark Read::CommandOptions
-static constexpr OptionDefinition g_breakpoint_read_options[] = {
- // clang-format off
- {LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
- {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_read
+#include "CommandOptions.inc"
#pragma mark Read
@@ -2301,9 +2049,7 @@ public:
break;
}
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -2326,21 +2072,16 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget();
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
FileSpec input_spec(m_options.m_filename);
FileSystem::Instance().Resolve(input_spec);
BreakpointIDList new_bps;
- Status error = target->CreateBreakpointsFromFile(
- input_spec, m_options.m_names, new_bps);
+ Status error = target.CreateBreakpointsFromFile(input_spec,
+ m_options.m_names, new_bps);
if (!error.Success()) {
result.AppendError(error.AsCString());
@@ -2358,7 +2099,7 @@ protected:
result.AppendMessage("New breakpoints:");
for (size_t i = 0; i < num_breakpoints; ++i) {
BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
- Breakpoint *bp = target->GetBreakpointList()
+ Breakpoint *bp = target.GetBreakpointList()
.FindBreakpointByID(bp_id.GetBreakpointID())
.get();
if (bp)
@@ -2375,12 +2116,8 @@ private:
// CommandObjectBreakpointWrite
#pragma mark Write::CommandOptions
-static constexpr OptionDefinition g_breakpoint_write_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
- { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_write
+#include "CommandOptions.inc"
#pragma mark Write
class CommandObjectBreakpointWrite : public CommandObjectParsed {
@@ -2423,9 +2160,7 @@ public:
m_append = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -2448,20 +2183,15 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget();
std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ target.GetBreakpointList().GetListMutex(lock);
BreakpointIDList valid_bp_ids;
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (!result.Succeeded()) {
@@ -2471,8 +2201,8 @@ protected:
}
FileSpec file_spec(m_options.m_filename);
FileSystem::Instance().Resolve(file_spec);
- Status error = target->SerializeBreakpointsToFile(file_spec, valid_bp_ids,
- m_options.m_append);
+ Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids,
+ m_options.m_append);
if (!error.Success()) {
result.AppendErrorWithFormat("error serializing breakpoints: %s.",
error.AsCString());
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index 3f9d83cd86a8..a6bcd1d8dc32 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -26,33 +26,33 @@
using namespace lldb;
using namespace lldb_private;
-// CommandObjectBreakpointCommandAdd
-
// FIXME: "script-type" needs to have its contents determined dynamically, so
-// somebody can add a new scripting
-// language to lldb and have it pickable here without having to change this
-// enumeration by hand and rebuild lldb proper.
-
+// somebody can add a new scripting language to lldb and have it pickable here
+// without having to change this enumeration by hand and rebuild lldb proper.
static constexpr OptionEnumValueElement g_script_option_enumeration[] = {
- {eScriptLanguageNone, "command",
- "Commands are in the lldb command interpreter language"},
- {eScriptLanguagePython, "python", "Commands are in the Python language."},
- {eSortOrderByName, "default-script",
- "Commands are in the default scripting language."} };
+ {
+ eScriptLanguageNone,
+ "command",
+ "Commands are in the lldb command interpreter language",
+ },
+ {
+ eScriptLanguagePython,
+ "python",
+ "Commands are in the Python language.",
+ },
+ {
+ eSortOrderByName,
+ "default-script",
+ "Commands are in the default scripting language.",
+ },
+};
static constexpr OptionEnumValues ScriptOptionEnum() {
return OptionEnumValues(g_script_option_enumeration);
}
-static constexpr OptionDefinition g_breakpoint_add_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." },
- { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." },
- { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." },
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_command_add
+#include "CommandOptions.inc"
class CommandObjectBreakpointCommandAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -221,7 +221,7 @@ are no syntax errors may indicate that a function was declared but never called.
Options *GetOptions() override { return &m_options; }
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(g_reader_instructions);
output_sp->Flush();
@@ -238,7 +238,7 @@ are no syntax errors may indicate that a function was declared but never called.
if (!bp_options)
continue;
- auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+ auto cmd_data = std::make_unique<BreakpointOptions::CommandData>();
cmd_data->user_source.SplitIntoLines(line.c_str(), line.size());
bp_options->SetCommandDataCallback(cmd_data);
}
@@ -260,7 +260,7 @@ are no syntax errors may indicate that a function was declared but never called.
SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec,
const char *oneliner) {
for (auto bp_options : bp_options_vec) {
- auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+ auto cmd_data = std::make_unique<BreakpointOptions::CommandData>();
cmd_data->user_source.AppendString(oneliner);
cmd_data->stop_on_error = m_options.m_stop_on_error;
@@ -291,7 +291,8 @@ are no syntax errors may indicate that a function was declared but never called.
case 's':
m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
- option_arg, g_breakpoint_add_options[option_idx].enum_values,
+ option_arg,
+ g_breakpoint_command_add_options[option_idx].enum_values,
eScriptLanguageNone, error);
if (m_script_language == eScriptLanguagePython ||
@@ -323,7 +324,7 @@ are no syntax errors may indicate that a function was declared but never called.
break;
default:
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -341,7 +342,7 @@ are no syntax errors may indicate that a function was declared but never called.
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_breakpoint_add_options);
+ return llvm::makeArrayRef(g_breakpoint_command_add_options);
}
// Instance variables to hold the values for command options.
@@ -360,16 +361,9 @@ are no syntax errors may indicate that a function was declared but never called.
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "breakpoints to which to add commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0) {
@@ -388,7 +382,7 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
m_bp_options_vec.clear();
@@ -400,7 +394,7 @@ protected:
BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *bp =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
BreakpointOptions *bp_options = nullptr;
if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) {
// This breakpoint does not have an associated location.
@@ -469,11 +463,8 @@ const char *CommandObjectBreakpointCommandAdd::g_reader_instructions =
// CommandObjectBreakpointCommandDelete
-static constexpr OptionDefinition g_breakpoint_delete_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
- // clang-format on
-};
+#define LLDB_OPTIONS_breakpoint_command_delete
+#include "CommandOptions.inc"
class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {
public:
@@ -518,9 +509,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -531,7 +520,7 @@ public:
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_breakpoint_delete_options);
+ return llvm::makeArrayRef(g_breakpoint_command_delete_options);
}
// Instance variables to hold the values for command options.
@@ -540,16 +529,9 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "breakpoints from which to delete commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0) {
@@ -567,7 +549,7 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, &target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
@@ -576,7 +558,7 @@ protected:
BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
Breakpoint *bp =
- target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
BreakpointLocationSP bp_loc_sp(
bp->FindLocationByID(cur_bp_id.GetLocationID()));
@@ -607,10 +589,10 @@ private:
class CommandObjectBreakpointCommandList : public CommandObjectParsed {
public:
CommandObjectBreakpointCommandList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "list", "List the script or set of "
- "commands to be executed when "
- "the breakpoint is hit.",
- nullptr) {
+ : CommandObjectParsed(interpreter, "list",
+ "List the script or set of commands to be "
+ "executed when the breakpoint is hit.",
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandArgumentData bp_id_arg;
@@ -630,14 +612,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "breakpoints for which to list commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -657,7 +632,7 @@ protected:
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, target, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
diff --git a/source/Commands/CommandObjectBugreport.cpp b/source/Commands/CommandObjectBugreport.cpp
deleted file mode 100644
index 515cc9a113b1..000000000000
--- a/source/Commands/CommandObjectBugreport.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-//===-- CommandObjectBugreport.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 "CommandObjectBugreport.h"
-
-#include <cstdio>
-
-
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionGroupOutputFile.h"
-#include "lldb/Target/Thread.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// "bugreport unwind"
-
-class CommandObjectBugreportUnwind : public CommandObjectParsed {
-public:
- CommandObjectBugreportUnwind(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "bugreport unwind",
- "Create a bugreport for a bug in the stack unwinding code.",
- nullptr),
- m_option_group(), m_outfile_options() {
- m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
- LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
- m_option_group.Finalize();
- }
-
- ~CommandObjectBugreportUnwind() override {}
-
- Options *GetOptions() override { return &m_option_group; }
-
-protected:
- bool DoExecute(Args &command, CommandReturnObject &result) override {
- StringList commands;
- commands.AppendString("thread backtrace");
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (thread) {
- char command_buffer[256];
-
- uint32_t frame_count = thread->GetStackFrameCount();
- for (uint32_t i = 0; i < frame_count; ++i) {
- StackFrameSP frame = thread->GetStackFrameAtIndex(i);
- lldb::addr_t pc = frame->GetStackID().GetPC();
-
- snprintf(command_buffer, sizeof(command_buffer),
- "disassemble --bytes --address 0x%" PRIx64, pc);
- commands.AppendString(command_buffer);
-
- snprintf(command_buffer, sizeof(command_buffer),
- "image show-unwind --address 0x%" PRIx64, pc);
- commands.AppendString(command_buffer);
- }
- }
-
- const FileSpec &outfile_spec =
- m_outfile_options.GetFile().GetCurrentValue();
- if (outfile_spec) {
-
- uint32_t open_options =
- File::eOpenOptionWrite | File::eOpenOptionCanCreate |
- File::eOpenOptionAppend | File::eOpenOptionCloseOnExec;
-
- const bool append = m_outfile_options.GetAppend().GetCurrentValue();
- if (!append)
- open_options |= File::eOpenOptionTruncate;
-
- StreamFileSP outfile_stream = std::make_shared<StreamFile>();
- File &file = outfile_stream->GetFile();
- Status error =
- FileSystem::Instance().Open(file, outfile_spec, open_options);
- if (error.Fail()) {
- auto path = outfile_spec.GetPath();
- result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
- path.c_str(), append ? "append" : "write",
- error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- result.SetImmediateOutputStream(outfile_stream);
- }
-
- CommandInterpreterRunOptions options;
- options.SetStopOnError(false);
- options.SetEchoCommands(true);
- options.SetPrintResults(true);
- options.SetPrintErrors(true);
- options.SetAddToHistory(false);
- m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);
-
- return result.Succeeded();
- }
-
-private:
- OptionGroupOptions m_option_group;
- OptionGroupOutputFile m_outfile_options;
-};
-
-#pragma mark CommandObjectMultiwordBugreport
-
-// CommandObjectMultiwordBugreport
-
-CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(
- CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "bugreport",
- "Commands for creating domain-specific bug reports.",
- "bugreport <subcommand> [<subcommand-options>]") {
-
- LoadSubCommand(
- "unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
-}
-
-CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport() {}
diff --git a/source/Commands/CommandObjectBugreport.h b/source/Commands/CommandObjectBugreport.h
deleted file mode 100644
index 24ce6d237d56..000000000000
--- a/source/Commands/CommandObjectBugreport.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===-- CommandObjectBugreport.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_CommandObjectBugreport_h_
-#define liblldb_CommandObjectBugreport_h_
-
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-
-namespace lldb_private {
-
-// CommandObjectMultiwordBugreport
-
-class CommandObjectMultiwordBugreport : public CommandObjectMultiword {
-public:
- CommandObjectMultiwordBugreport(CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordBugreport() override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_CommandObjectBugreport_h_
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 4092e76be6ac..259affbe6e0a 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -31,14 +31,8 @@ using namespace lldb_private;
// CommandObjectCommandsSource
-static constexpr OptionDefinition g_history_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "How many history commands to print." },
- { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." },
- { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." },
- { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeBoolean, "Clears the current command history." },
- // clang-format on
-};
+#define LLDB_OPTIONS_history
+#include "CommandOptions.inc"
class CommandObjectCommandsHistory : public CommandObjectParsed {
public:
@@ -91,9 +85,7 @@ protected:
m_clear.SetOptionWasSet();
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -188,13 +180,8 @@ protected:
// CommandObjectCommandsSource
-static constexpr OptionDefinition g_source_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on error." },
- { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on continue." },
- { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true don't echo commands while executing." },
- // clang-format on
-};
+#define LLDB_OPTIONS_source
+#include "CommandOptions.inc"
class CommandObjectCommandsSource : public CommandObjectParsed {
public:
@@ -226,13 +213,12 @@ public:
return "";
}
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }
@@ -265,9 +251,7 @@ protected:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -299,7 +283,7 @@ protected:
return false;
}
- FileSpec cmd_file(command[0].ref);
+ FileSpec cmd_file(command[0].ref());
FileSystem::Instance().Resolve(cmd_file);
ExecutionContext *exe_ctx = nullptr; // Just use the default context.
@@ -343,12 +327,8 @@ protected:
#pragma mark CommandObjectCommandsAlias
// CommandObjectCommandsAlias
-static constexpr OptionDefinition g_alias_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Help text for this command" },
- { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Long help text for this command" },
- // clang-format on
-};
+#define LLDB_OPTIONS_alias
+#include "CommandOptions.inc"
static const char *g_python_command_instructions =
"Enter your Python command(s). Type 'DONE' to end.\n"
@@ -386,9 +366,7 @@ protected:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -568,7 +546,7 @@ protected:
// Get the alias command.
- auto alias_command = args[0].ref;
+ auto alias_command = args[0].ref();
if (alias_command.startswith("-")) {
result.AppendError("aliases starting with a dash are not supported");
if (alias_command == "--help" || alias_command == "--long-help") {
@@ -675,8 +653,8 @@ protected:
}
// Save these in std::strings since we're going to shift them off.
- const std::string alias_command(args[0].ref);
- const std::string actual_command(args[1].ref);
+ const std::string alias_command(args[0].ref());
+ const std::string actual_command(args[1].ref());
args.Shift(); // Shift the alias command word off the argument vector.
args.Shift(); // Shift the old command word off the argument vector.
@@ -708,7 +686,7 @@ protected:
OptionArgVectorSP(new OptionArgVector);
while (cmd_obj->IsMultiwordObject() && !args.empty()) {
- auto sub_command = args[0].ref;
+ auto sub_command = args[0].ref();
assert(!sub_command.empty());
subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command);
if (!subcommand_obj_sp) {
@@ -802,7 +780,7 @@ protected:
return false;
}
- auto command_name = args[0].ref;
+ auto command_name = args[0].ref();
cmd_obj = m_interpreter.GetCommandObject(command_name);
if (!cmd_obj) {
result.AppendErrorWithFormat(
@@ -881,9 +859,10 @@ protected:
"defined regular expression command names",
GetCommandName().str().c_str());
result.SetStatus(eReturnStatusFailed);
+ return false;
}
- auto command_name = args[0].ref;
+ auto command_name = args[0].ref();
if (!m_interpreter.CommandExists(command_name)) {
StreamString error_msg_stream;
const bool generate_upropos = true;
@@ -911,12 +890,8 @@ protected:
// CommandObjectCommandsAddRegex
-static constexpr OptionDefinition g_regex_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The help text to display for this command." },
- { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." },
- // clang-format on
-};
+#define LLDB_OPTIONS_regex
+#include "CommandOptions.inc"
#pragma mark CommandObjectCommandsAddRegex
@@ -970,7 +945,7 @@ a number follows 'f':"
protected:
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString("Enter one or more sed substitution commands in "
"the form: 's/<regex>/<subst>/'.\nTerminate the "
@@ -985,11 +960,9 @@ protected:
if (m_regex_cmd_up) {
StringList lines;
if (lines.SplitIntoLines(data)) {
- const size_t num_lines = lines.GetSize();
bool check_only = false;
- for (size_t i = 0; i < num_lines; ++i) {
- llvm::StringRef bytes_strref(lines[i]);
- Status error = AppendRegexSubstitution(bytes_strref, check_only);
+ for (const std::string &line : lines) {
+ Status error = AppendRegexSubstitution(line, check_only);
if (error.Fail()) {
if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) {
StreamSP out_stream = GetDebugger().GetAsyncOutputStream();
@@ -1015,8 +988,8 @@ protected:
}
Status error;
- auto name = command[0].ref;
- m_regex_cmd_up = llvm::make_unique<CommandObjectRegexCommand>(
+ auto name = command[0].ref();
+ m_regex_cmd_up = std::make_unique<CommandObjectRegexCommand>(
m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10, 0,
true);
@@ -1040,7 +1013,7 @@ protected:
} else {
for (auto &entry : command.entries().drop_front()) {
bool check_only = false;
- error = AppendRegexSubstitution(entry.ref, check_only);
+ error = AppendRegexSubstitution(entry.ref(), check_only);
if (error.Fail())
break;
}
@@ -1183,9 +1156,7 @@ private:
m_syntax.assign(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1315,8 +1286,6 @@ public:
bool IsRemovable() const override { return true; }
- StructuredData::GenericSP GetImplementingObject() { return m_cmd_obj_sp; }
-
ScriptedCommandSynchronicity GetSynchronicity() { return m_synchro; }
llvm::StringRef GetHelp() override {
@@ -1385,12 +1354,8 @@ private:
};
// CommandObjectCommandsScriptImport
-
-static constexpr OptionDefinition g_script_import_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." },
- // clang-format on
-};
+#define LLDB_OPTIONS_script_import
+#include "CommandOptions.inc"
class CommandObjectCommandsScriptImport : public CommandObjectParsed {
public:
@@ -1415,13 +1380,12 @@ public:
~CommandObjectCommandsScriptImport() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }
@@ -1443,9 +1407,7 @@ protected:
m_allow_reload = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1509,25 +1471,29 @@ protected:
// CommandObjectCommandsScriptAdd
static constexpr OptionEnumValueElement g_script_synchro_type[] = {
- {eScriptedCommandSynchronicitySynchronous, "synchronous",
- "Run synchronous"},
- {eScriptedCommandSynchronicityAsynchronous, "asynchronous",
- "Run asynchronous"},
- {eScriptedCommandSynchronicityCurrentValue, "current",
- "Do not alter current setting"} };
+ {
+ eScriptedCommandSynchronicitySynchronous,
+ "synchronous",
+ "Run synchronous",
+ },
+ {
+ eScriptedCommandSynchronicityAsynchronous,
+ "asynchronous",
+ "Run asynchronous",
+ },
+ {
+ eScriptedCommandSynchronicityCurrentValue,
+ "current",
+ "Do not alter current setting",
+ },
+};
static constexpr OptionEnumValues ScriptSynchroType() {
return OptionEnumValues(g_script_synchro_type);
}
-static constexpr OptionDefinition g_script_add_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." },
- { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." },
- { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "The help text to display for this command." },
- { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, ScriptSynchroType(), 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." },
- // clang-format on
-};
+#define LLDB_OPTIONS_script_add
+#include "CommandOptions.inc"
class CommandObjectCommandsScriptAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -1593,9 +1559,7 @@ protected:
option_arg.str().c_str());
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1621,7 +1585,7 @@ protected:
};
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(g_python_command_instructions);
output_sp->Flush();
@@ -1630,7 +1594,7 @@ protected:
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
if (interpreter) {
@@ -1692,7 +1656,7 @@ protected:
}
// Store the options in case we get multi-line input
- m_cmd_name = command[0].ref;
+ m_cmd_name = command[0].ref();
m_short_help.assign(m_options.m_short_help);
m_synchronicity = m_options.m_synchronicity;
@@ -1761,6 +1725,12 @@ public:
~CommandObjectCommandsScriptList() override = default;
bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.GetArgumentCount() != 0) {
+ result.AppendError("'command script list' doesn't take any arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef);
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1781,6 +1751,12 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.GetArgumentCount() != 0) {
+ result.AppendError("'command script clear' doesn't take any arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
m_interpreter.RemoveAllUser();
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1822,7 +1798,7 @@ protected:
return false;
}
- auto cmd_name = command[0].ref;
+ auto cmd_name = command[0].ref();
if (cmd_name.empty() || !m_interpreter.HasUserCommands() ||
!m_interpreter.UserCommandExists(cmd_name)) {
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 5972555b2499..69e2d757b5fe 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -30,32 +30,8 @@
using namespace lldb;
using namespace lldb_private;
-static constexpr OptionDefinition g_disassemble_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show opcode bytes when disassembling." },
- { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of context lines of source to show." },
- { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable mixed source and assembly display." },
- { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print raw disassembly with no symbol information." },
- { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." },
- { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
- "Currently the only valid options are default, and for Intel "
- "architectures, att and intel." },
- { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." },
- { LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." },
- { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." },
- { LLDB_OPT_SET_2 |
- LLDB_OPT_SET_3 |
- LLDB_OPT_SET_4 |
- LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of instructions to display." },
- { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." },
- { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." },
- { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble around the current pc." },
- { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line "
- "table information, else disassemble around the pc." },
- { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." },
- // clang-format on
-};
+#define LLDB_OPTIONS_disassemble
+#include "CommandOptions.inc"
CommandObjectDisassemble::CommandOptions::CommandOptions()
: Options(), num_lines_context(0), num_instructions(0), func_name(),
@@ -171,9 +147,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
} break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -238,20 +212,15 @@ CommandObjectDisassemble::CommandObjectDisassemble(
"Disassemble specified instructions in the current target. "
"Defaults to the current function for the current thread and "
"stack frame.",
- "disassemble [<cmd-options>]"),
+ "disassemble [<cmd-options>]", eCommandRequiresTarget),
m_options() {}
CommandObjectDisassemble::~CommandObjectDisassemble() = default;
bool CommandObjectDisassemble::DoExecute(Args &command,
CommandReturnObject &result) {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
+
if (!m_options.arch.IsValid())
m_options.arch = target->GetArchitecture();
@@ -541,7 +510,7 @@ bool CommandObjectDisassemble::DoExecute(Args &command,
} else {
result.AppendErrorWithFormat(
"Failed to disassemble memory at 0x%8.8" PRIx64 ".\n",
- m_options.start_addr);
+ cur_range.GetBaseAddress().GetLoadAddress(target));
result.SetStatus(eReturnStatusFailed);
}
if (print_sc_header)
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 29e4ab695522..9bafdc149804 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -38,34 +38,24 @@ CommandObjectExpression::CommandOptions::CommandOptions() : OptionGroup() {}
CommandObjectExpression::CommandOptions::~CommandOptions() = default;
static constexpr OptionEnumValueElement g_description_verbosity_type[] = {
- {eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact",
- "Only show the description string"},
- {eLanguageRuntimeDescriptionDisplayVerbosityFull, "full",
- "Show the full output, including persistent variable's name and type"} };
+ {
+ eLanguageRuntimeDescriptionDisplayVerbosityCompact,
+ "compact",
+ "Only show the description string",
+ },
+ {
+ eLanguageRuntimeDescriptionDisplayVerbosityFull,
+ "full",
+ "Show the full output, including persistent variable's name and type",
+ },
+};
static constexpr OptionEnumValues DescriptionVerbosityTypes() {
return OptionEnumValues(g_description_verbosity_type);
}
-static constexpr OptionDefinition g_expression_options[] = {
- // clang-format off
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. "
- "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction "
- "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language "
- "setting is used." },
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." },
- {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, DescriptionVerbosityTypes(), 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local "
- "context. Allows declaration of persistent, top-level entities without a $ prefix."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by "
- "the interpreter (defaults to true)."}
- // clang-format on
-};
+#define LLDB_OPTIONS_expression
+#include "CommandOptions.inc"
Status CommandObjectExpression::CommandOptions::SetOptionValue(
uint32_t option_idx, llvm::StringRef option_arg,
@@ -176,9 +166,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
}
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -304,7 +292,7 @@ CommandObjectExpression::~CommandObjectExpression() = default;
Options *CommandObjectExpression::GetOptions() { return &m_option_group; }
-int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
+void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
EvaluateExpressionOptions options;
options.SetCoerceToId(m_varobj_options.use_objc);
options.SetLanguage(m_command_options.language);
@@ -321,17 +309,14 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
// This didn't work, so let's get out before we start doing things that
// expect a valid frame pointer.
if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr)
- return 0;
+ return;
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
if (!target)
- target = GetDummyTarget();
-
- if (!target)
- return 0;
+ target = &GetDummyTarget();
unsigned cursor_pos = request.GetRawCursorPos();
llvm::StringRef code = request.GetRawLine();
@@ -351,7 +336,7 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
// exit.
// FIXME: We should complete the options here.
if (cursor_pos < raw_start)
- return 0;
+ return;
// Make the cursor_pos again relative to the start of the code string.
assert(cursor_pos >= raw_start);
@@ -364,10 +349,9 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
options, nullptr, error));
if (error.Fail())
- return 0;
+ return;
expr->Complete(exe_ctx, request, cursor_pos);
- return request.GetNumberOfMatches();
}
static lldb_private::Status
@@ -393,123 +377,116 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
Target *target = exe_ctx.GetTargetPtr();
if (!target)
- target = GetDummyTarget();
-
- if (target) {
- lldb::ValueObjectSP result_valobj_sp;
- bool keep_in_memory = true;
- StackFrame *frame = exe_ctx.GetFramePtr();
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(m_varobj_options.use_objc);
- options.SetUnwindOnError(m_command_options.unwind_on_error);
- options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
- options.SetKeepInMemory(keep_in_memory);
- options.SetUseDynamic(m_varobj_options.use_dynamic);
- options.SetTryAllThreads(m_command_options.try_all_threads);
- options.SetDebug(m_command_options.debug);
- options.SetLanguage(m_command_options.language);
- options.SetExecutionPolicy(
- m_command_options.allow_jit
- ? EvaluateExpressionOptions::default_execution_policy
- : lldb_private::eExecutionPolicyNever);
-
- bool auto_apply_fixits;
- if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
- auto_apply_fixits = target->GetEnableAutoApplyFixIts();
- else
- auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes;
+ target = &GetDummyTarget();
- options.SetAutoApplyFixIts(auto_apply_fixits);
+ lldb::ValueObjectSP result_valobj_sp;
+ bool keep_in_memory = true;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(m_varobj_options.use_objc);
+ options.SetUnwindOnError(m_command_options.unwind_on_error);
+ options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
+ options.SetKeepInMemory(keep_in_memory);
+ options.SetUseDynamic(m_varobj_options.use_dynamic);
+ options.SetTryAllThreads(m_command_options.try_all_threads);
+ options.SetDebug(m_command_options.debug);
+ options.SetLanguage(m_command_options.language);
+ options.SetExecutionPolicy(
+ m_command_options.allow_jit
+ ? EvaluateExpressionOptions::default_execution_policy
+ : lldb_private::eExecutionPolicyNever);
+
+ bool auto_apply_fixits;
+ if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
+ auto_apply_fixits = target->GetEnableAutoApplyFixIts();
+ else
+ auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes;
- if (m_command_options.top_level)
- options.SetExecutionPolicy(eExecutionPolicyTopLevel);
+ options.SetAutoApplyFixIts(auto_apply_fixits);
- // If there is any chance we are going to stop and want to see what went
- // wrong with our expression, we should generate debug info
- if (!m_command_options.ignore_breakpoints ||
- !m_command_options.unwind_on_error)
- options.SetGenerateDebugInfo(true);
+ if (m_command_options.top_level)
+ options.SetExecutionPolicy(eExecutionPolicyTopLevel);
- if (m_command_options.timeout > 0)
- options.SetTimeout(std::chrono::microseconds(m_command_options.timeout));
- else
- options.SetTimeout(llvm::None);
-
- ExpressionResults success = target->EvaluateExpression(
- expr, frame, result_valobj_sp, options, &m_fixed_expression);
-
- // We only tell you about the FixIt if we applied it. The compiler errors
- // will suggest the FixIt if it parsed.
- if (error_stream && !m_fixed_expression.empty() &&
- target->GetEnableNotifyAboutFixIts()) {
- if (success == eExpressionCompleted)
- error_stream->Printf(
- " Fix-it applied, fixed expression was: \n %s\n",
- m_fixed_expression.c_str());
- }
+ // If there is any chance we are going to stop and want to see what went
+ // wrong with our expression, we should generate debug info
+ if (!m_command_options.ignore_breakpoints ||
+ !m_command_options.unwind_on_error)
+ options.SetGenerateDebugInfo(true);
- if (result_valobj_sp) {
- Format format = m_format_options.GetFormat();
-
- if (result_valobj_sp->GetError().Success()) {
- if (format != eFormatVoid) {
- if (format != eFormatDefault)
- result_valobj_sp->SetFormat(format);
-
- if (m_varobj_options.elem_count > 0) {
- Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
- if (error.Fail()) {
- result->AppendErrorWithFormat(
- "expression cannot be used with --element-count %s\n",
- error.AsCString(""));
- result->SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (m_command_options.timeout > 0)
+ options.SetTimeout(std::chrono::microseconds(m_command_options.timeout));
+ else
+ options.SetTimeout(llvm::None);
+
+ ExpressionResults success = target->EvaluateExpression(
+ expr, frame, result_valobj_sp, options, &m_fixed_expression);
+
+ // We only tell you about the FixIt if we applied it. The compiler errors
+ // will suggest the FixIt if it parsed.
+ if (error_stream && !m_fixed_expression.empty() &&
+ target->GetEnableNotifyAboutFixIts()) {
+ if (success == eExpressionCompleted)
+ error_stream->Printf(" Fix-it applied, fixed expression was: \n %s\n",
+ m_fixed_expression.c_str());
+ }
+
+ if (result_valobj_sp) {
+ Format format = m_format_options.GetFormat();
+
+ if (result_valobj_sp->GetError().Success()) {
+ if (format != eFormatVoid) {
+ if (format != eFormatDefault)
+ result_valobj_sp->SetFormat(format);
+
+ if (m_varobj_options.elem_count > 0) {
+ Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
+ if (error.Fail()) {
+ result->AppendErrorWithFormat(
+ "expression cannot be used with --element-count %s\n",
+ error.AsCString(""));
+ result->SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
- DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
- m_command_options.m_verbosity, format));
- options.SetVariableFormatDisplayLanguage(
- result_valobj_sp->GetPreferredDisplayLanguage());
+ DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
+ m_command_options.m_verbosity, format));
+ options.SetVariableFormatDisplayLanguage(
+ result_valobj_sp->GetPreferredDisplayLanguage());
- result_valobj_sp->Dump(*output_stream, options);
+ result_valobj_sp->Dump(*output_stream, options);
- if (result)
- result->SetStatus(eReturnStatusSuccessFinishResult);
+ if (result)
+ result->SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ } else {
+ if (result_valobj_sp->GetError().GetError() ==
+ UserExpression::kNoResult) {
+ if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) {
+ error_stream->PutCString("(void)\n");
}
- } else {
- if (result_valobj_sp->GetError().GetError() ==
- UserExpression::kNoResult) {
- if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) {
- error_stream->PutCString("(void)\n");
- }
- if (result)
- result->SetStatus(eReturnStatusSuccessFinishResult);
+ if (result)
+ result->SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ const char *error_cstr = result_valobj_sp->GetError().AsCString();
+ if (error_cstr && error_cstr[0]) {
+ const size_t error_cstr_len = strlen(error_cstr);
+ const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
+ if (strstr(error_cstr, "error:") != error_cstr)
+ error_stream->PutCString("error: ");
+ error_stream->Write(error_cstr, error_cstr_len);
+ if (!ends_with_newline)
+ error_stream->EOL();
} else {
- const char *error_cstr = result_valobj_sp->GetError().AsCString();
- if (error_cstr && error_cstr[0]) {
- const size_t error_cstr_len = strlen(error_cstr);
- const bool ends_with_newline =
- error_cstr[error_cstr_len - 1] == '\n';
- if (strstr(error_cstr, "error:") != error_cstr)
- error_stream->PutCString("error: ");
- error_stream->Write(error_cstr, error_cstr_len);
- if (!ends_with_newline)
- error_stream->EOL();
- } else {
- error_stream->PutCString("error: unknown error\n");
- }
-
- if (result)
- result->SetStatus(eReturnStatusFailed);
+ error_stream->PutCString("error: unknown error\n");
}
+
+ if (result)
+ result->SetStatus(eReturnStatusFailed);
}
}
- } else {
- error_stream->Printf("error: invalid execution context for expression\n");
- return false;
}
return true;
@@ -521,8 +498,8 @@ void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler,
// StreamSP output_stream =
// io_handler.GetDebugger().GetAsyncOutputStream();
// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ StreamFileSP output_sp = io_handler.GetOutputStreamFileSP();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get());
if (output_sp)
@@ -560,7 +537,7 @@ void CommandObjectExpression::GetMultilineExpression() {
1, // Show line numbers starting at 1
*this, nullptr));
- StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
+ StreamFileSP output_sp = io_handler_sp->GetOutputStreamFileSP();
if (output_sp) {
output_sp->PutCString(
"Enter expressions, then terminate with an empty line to evaluate:\n");
@@ -675,11 +652,11 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command,
}
}
- Target *target = GetSelectedOrDummyTarget();
+ Target &target = GetSelectedOrDummyTarget();
if (EvaluateExpression(expr, &(result.GetOutputStream()),
&(result.GetErrorStream()), &result)) {
- if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
+ if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
CommandHistory &history = m_interpreter.GetCommandHistory();
// FIXME: Can we figure out what the user actually typed (e.g. some alias
// for expr???)
@@ -694,12 +671,12 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command,
history.AppendString(fixed_command);
}
// Increment statistics to record this expression evaluation success.
- target->IncrementStats(StatisticKind::ExpressionSuccessful);
+ target.IncrementStats(StatisticKind::ExpressionSuccessful);
return true;
}
// Increment statistics to record this expression evaluation failure.
- target->IncrementStats(StatisticKind::ExpressionFailure);
+ target.IncrementStats(StatisticKind::ExpressionFailure);
result.SetStatus(eReturnStatusFailed);
return false;
}
diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index 89c8e1dbeceb..8ef764239069 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -54,7 +54,7 @@ public:
Options *GetOptions() override;
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
protected:
// IOHandler::Delegate functions
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index ab6a07952f19..6a7facdaff35 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -23,7 +23,6 @@
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionGroupVariable.h"
#include "lldb/Interpreter/Options.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -54,13 +53,8 @@ using namespace lldb_private;
// CommandObjectFrameDiagnose
-static constexpr OptionDefinition g_frame_diag_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegisterName, "A register to diagnose." },
- { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "An address to diagnose." },
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "An optional offset. Requires --register." }
- // clang-format on
-};
+#define LLDB_OPTIONS_frame_diag
+#include "CommandOptions.inc"
class CommandObjectFrameDiagnose : public CommandObjectParsed {
public:
@@ -98,9 +92,7 @@ public:
} break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -238,11 +230,8 @@ protected:
// CommandObjectFrameSelect
-static OptionDefinition g_frame_select_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." },
- // clang-format on
-};
+#define LLDB_OPTIONS_frame_select
+#include "CommandOptions.inc"
class CommandObjectFrameSelect : public CommandObjectParsed {
public:
@@ -257,32 +246,32 @@ public:
Status error;
const int short_option = m_getopt_table[option_idx].val;
switch (short_option) {
- case 'r':
- if (option_arg.getAsInteger(0, relative_frame_offset)) {
- relative_frame_offset = INT32_MIN;
+ case 'r': {
+ int32_t offset = 0;
+ if (option_arg.getAsInteger(0, offset) || offset == INT32_MIN) {
error.SetErrorStringWithFormat("invalid frame offset argument '%s'",
option_arg.str().c_str());
- }
+ } else
+ relative_frame_offset = offset;
break;
+ }
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
- relative_frame_offset = INT32_MIN;
+ relative_frame_offset.reset();
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::makeArrayRef(g_frame_select_options);
}
- int32_t relative_frame_offset;
+ llvm::Optional<int32_t> relative_frame_offset;
};
CommandObjectFrameSelect(CommandInterpreter &interpreter)
@@ -320,15 +309,16 @@ protected:
Thread *thread = m_exe_ctx.GetThreadPtr();
uint32_t frame_idx = UINT32_MAX;
- if (m_options.relative_frame_offset != INT32_MIN) {
+ if (m_options.relative_frame_offset.hasValue()) {
// The one and only argument is a signed relative frame index
frame_idx = thread->GetSelectedFrameIndex();
if (frame_idx == UINT32_MAX)
frame_idx = 0;
- if (m_options.relative_frame_offset < 0) {
- if (static_cast<int32_t>(frame_idx) >= -m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
+ if (*m_options.relative_frame_offset < 0) {
+ if (static_cast<int32_t>(frame_idx) >=
+ -*m_options.relative_frame_offset)
+ frame_idx += *m_options.relative_frame_offset;
else {
if (frame_idx == 0) {
// If you are already at the bottom of the stack, then just warn
@@ -339,15 +329,15 @@ protected:
} else
frame_idx = 0;
}
- } else if (m_options.relative_frame_offset > 0) {
+ } else if (*m_options.relative_frame_offset > 0) {
// I don't want "up 20" where "20" takes you past the top of the stack
// to produce
// an error, but rather to just go to the top. So I have to count the
// stack here...
const uint32_t num_frames = thread->GetStackFrameCount();
if (static_cast<int32_t>(num_frames - frame_idx) >
- m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
+ *m_options.relative_frame_offset)
+ frame_idx += *m_options.relative_frame_offset;
else {
if (frame_idx == num_frames - 1) {
// If we are already at the top of the stack, just warn and don't
@@ -371,7 +361,7 @@ protected:
}
if (command.GetArgumentCount() == 1) {
- if (command[0].ref.getAsInteger(0, frame_idx)) {
+ if (command[0].ref().getAsInteger(0, frame_idx)) {
result.AppendErrorWithFormat("invalid frame index argument '%s'.",
command[0].c_str());
result.SetStatus(eReturnStatusFailed);
@@ -460,14 +450,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Arguments are the standard source file completer.
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -541,9 +530,9 @@ protected:
for (auto &entry : command) {
if (m_option_variable.use_regex) {
const size_t regex_start_index = regex_var_list.GetSize();
- llvm::StringRef name_str = entry.ref;
+ llvm::StringRef name_str = entry.ref();
RegularExpression regex(name_str);
- if (regex.Compile(name_str)) {
+ if (regex.IsValid()) {
size_t num_matches = 0;
const size_t num_new_regex_vars =
variable_list->AppendVariablesIfUnique(regex, regex_var_list,
@@ -582,9 +571,9 @@ protected:
entry.c_str());
}
} else {
- char regex_error[1024];
- if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
- result.GetErrorStream().Printf("error: %s\n", regex_error);
+ if (llvm::Error err = regex.GetError())
+ result.GetErrorStream().Printf(
+ "error: %s\n", llvm::toString(std::move(err)).c_str());
else
result.GetErrorStream().Printf(
"error: unknown regex error when compiling '%s'\n",
@@ -600,7 +589,7 @@ protected:
StackFrame::eExpressionPathOptionsInspectAnonymousUnions;
lldb::VariableSP var_sp;
valobj_sp = frame->GetValueForVariableExpressionPath(
- entry.ref, m_varobj_options.use_dynamic, expr_path_options,
+ entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
var_sp, error);
if (valobj_sp) {
std::string scope_string;
@@ -727,11 +716,11 @@ protected:
// Increment statistics.
bool res = result.Succeeded();
- Target *target = GetSelectedOrDummyTarget();
+ Target &target = GetSelectedOrDummyTarget();
if (res)
- target->IncrementStats(StatisticKind::FrameVarSuccess);
+ target.IncrementStats(StatisticKind::FrameVarSuccess);
else
- target->IncrementStats(StatisticKind::FrameVarFailure);
+ target.IncrementStats(StatisticKind::FrameVarFailure);
return res;
}
@@ -744,14 +733,8 @@ protected:
#pragma mark CommandObjectFrameRecognizer
-static OptionDefinition g_frame_recognizer_add_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Name of the module or shared library that this recognizer applies to." },
- { LLDB_OPT_SET_ALL, false, "function", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeName, "Name of the function that this recognizer applies to." },
- { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Give the name of a Python class to use for this frame recognizer." },
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Function name and module name are actually regular expressions." }
- // clang-format on
-};
+#define LLDB_OPTIONS_frame_recognizer_add
+#include "CommandOptions.inc"
class CommandObjectFrameRecognizerAdd : public CommandObjectParsed {
private:
@@ -779,9 +762,7 @@ private:
m_regex = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Commands/CommandObjectGUI.cpp b/source/Commands/CommandObjectGUI.cpp
index 21ed510d1264..fac2e9627783 100644
--- a/source/Commands/CommandObjectGUI.cpp
+++ b/source/Commands/CommandObjectGUI.cpp
@@ -28,9 +28,10 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) {
if (args.GetArgumentCount() == 0) {
Debugger &debugger = GetDebugger();
- lldb::StreamFileSP input_sp = debugger.GetInputFile();
- if (input_sp && input_sp->GetFile().GetIsRealTerminal() &&
- input_sp->GetFile().GetIsInteractive()) {
+ File &input = debugger.GetInputFile();
+ File &output = debugger.GetOutputFile();
+ if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() &&
+ input.GetIsInteractive()) {
IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger));
if (io_handler_sp)
debugger.PushIOHandler(io_handler_sp);
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index ab557919d0a0..c02a583bf9df 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -65,10 +65,8 @@ CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter)
CommandObjectHelp::~CommandObjectHelp() = default;
-static constexpr OptionDefinition g_help_options[] = {
#define LLDB_OPTIONS_help
#include "CommandOptions.inc"
-};
llvm::ArrayRef<OptionDefinition>
CommandObjectHelp::CommandOptions::GetDefinitions() {
@@ -98,7 +96,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
// Get command object for the first command argument. Only search built-in
// command dictionary.
StringList matches;
- auto command_name = command[0].ref;
+ auto command_name = command[0].ref();
cmd_obj = m_interpreter.GetCommandObject(command_name, &matches);
if (cmd_obj != nullptr) {
@@ -109,7 +107,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
// object that corresponds to the help command entered.
std::string sub_command;
for (auto &entry : command.entries().drop_front()) {
- sub_command = entry.ref;
+ sub_command = entry.ref();
matches.Clear();
if (sub_cmd_obj->IsAlias())
sub_cmd_obj =
@@ -203,24 +201,23 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
return result.Succeeded();
}
-int CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
+void CommandObjectHelp::HandleCompletion(CompletionRequest &request) {
// Return the completions of the commands in the help system:
if (request.GetCursorIndex() == 0) {
- return m_interpreter.HandleCompletionMatches(request);
- } else {
- CommandObject *cmd_obj =
- m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref);
+ m_interpreter.HandleCompletionMatches(request);
+ return;
+ }
+ CommandObject *cmd_obj =
+ m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref());
- // The command that they are getting help on might be ambiguous, in which
- // case we should complete that, otherwise complete with the command the
- // user is getting help on...
+ // The command that they are getting help on might be ambiguous, in which
+ // case we should complete that, otherwise complete with the command the
+ // user is getting help on...
- if (cmd_obj) {
- request.GetParsedLine().Shift();
- request.SetCursorIndex(request.GetCursorIndex() - 1);
- return cmd_obj->HandleCompletion(request);
- } else {
- return m_interpreter.HandleCompletionMatches(request);
- }
+ if (cmd_obj) {
+ request.ShiftArguments();
+ cmd_obj->HandleCompletion(request);
+ return;
}
+ m_interpreter.HandleCompletionMatches(request);
}
diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h
index a641b19a46d0..52a00ac79ff9 100644
--- a/source/Commands/CommandObjectHelp.h
+++ b/source/Commands/CommandObjectHelp.h
@@ -23,7 +23,7 @@ public:
~CommandObjectHelp() override;
- int HandleCompletion(CompletionRequest &request) override;
+ void HandleCompletion(CompletionRequest &request) override;
static void GenerateAdditionalHelpAvenuesMessage(
Stream *s, llvm::StringRef command, llvm::StringRef prefix,
@@ -52,9 +52,7 @@ public:
m_show_hidden = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index 2ad61de1a3e9..31a876c3430e 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -31,20 +31,23 @@
using namespace lldb;
using namespace lldb_private;
-static constexpr OptionDefinition g_log_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Set the destination file to log to." },
- { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
- { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose logging." },
- { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
- { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
- { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
- { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
- { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
- { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
- { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." },
- // clang-format on
-};
+#define LLDB_OPTIONS_log
+#include "CommandOptions.inc"
+
+/// Common completion logic for log enable/disable.
+static void CompleteEnableDisable(CompletionRequest &request) {
+ size_t arg_index = request.GetCursorIndex();
+ if (arg_index == 0) { // We got: log enable/disable x[tab]
+ for (llvm::StringRef channel : Log::ListChannels())
+ request.TryCompleteCurrentArg(channel);
+ } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab]
+ llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0);
+ Log::ForEachChannelCategory(
+ channel, [&request](llvm::StringRef name, llvm::StringRef desc) {
+ request.TryCompleteCurrentArg(name, desc);
+ });
+ }
+}
class CommandObjectLogEnable : public CommandObjectParsed {
public:
@@ -125,9 +128,7 @@ public:
log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -148,17 +149,24 @@ public:
uint32_t log_options;
};
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CompleteEnableDisable(request);
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
if (args.GetArgumentCount() < 2) {
result.AppendErrorWithFormat(
"%s takes a log channel and one or more log types.\n",
m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
}
// Store into a std::string since we're about to shift the channel off.
- const std::string channel = args[0].ref;
+ const std::string channel = args[0].ref();
args.Shift(); // Shift off the channel
char log_file[PATH_MAX];
if (m_options.log_file)
@@ -215,16 +223,23 @@ public:
~CommandObjectLogDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CompleteEnableDisable(request);
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
if (args.empty()) {
result.AppendErrorWithFormat(
"%s takes a log channel and one or more log types.\n",
m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- const std::string channel = args[0].ref;
+ const std::string channel = args[0].ref();
args.Shift(); // Shift off the channel
if (channel == "all") {
Log::DisableAllLogChannels();
@@ -266,6 +281,13 @@ public:
~CommandObjectLogList() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ for (llvm::StringRef channel : Log::ListChannels())
+ request.TryCompleteCurrentArg(channel);
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
std::string output;
@@ -277,7 +299,7 @@ protected:
bool success = true;
for (const auto &entry : args.entries())
success =
- success && Log::ListChannelCategories(entry.ref, output_stream);
+ success && Log::ListChannelCategories(entry.ref(), output_stream);
if (success)
result.SetStatus(eReturnStatusSuccessFinishResult);
}
@@ -303,7 +325,7 @@ protected:
result.SetStatus(eReturnStatusFailed);
if (args.GetArgumentCount() == 1) {
- auto sub_command = args[0].ref;
+ auto sub_command = args[0].ref();
if (sub_command.equals_lower("enable")) {
Timer::SetDisplayDepth(UINT32_MAX);
@@ -320,8 +342,8 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
}
} else if (args.GetArgumentCount() == 2) {
- auto sub_command = args[0].ref;
- auto param = args[1].ref;
+ auto sub_command = args[0].ref();
+ auto param = args[1].ref();
if (sub_command.equals_lower("enable")) {
uint32_t depth;
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 1afcac71318d..38bd3d179096 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -46,20 +46,8 @@
using namespace lldb;
using namespace lldb_private;
-static constexpr OptionDefinition g_read_memory_options[] = {
- // clang-format off
- {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." },
- {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that "
- "uses the format, size, count and number per line settings." },
- {LLDB_OPT_SET_3 |
- LLDB_OPT_SET_4, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "The name of a type to view memory as." },
- {LLDB_OPT_SET_4, false, "language", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "The language of the type to view memory as."},
- {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." },
- {LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 |
- LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." },
- // clang-format on
-};
+#define LLDB_OPTIONS_memory_read
+#include "CommandOptions.inc"
class OptionGroupReadMemory : public OptionGroup {
public:
@@ -70,13 +58,13 @@ public:
~OptionGroupReadMemory() override = default;
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_read_memory_options);
+ return llvm::makeArrayRef(g_memory_read_options);
}
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
ExecutionContext *execution_context) override {
Status error;
- const int short_option = g_read_memory_options[option_idx].short_option;
+ const int short_option = g_memory_read_options[option_idx].short_option;
switch (short_option) {
case 'l':
@@ -108,9 +96,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -175,6 +161,7 @@ public:
case eFormatOctal:
case eFormatDecimal:
case eFormatEnum:
+ case eFormatUnicode8:
case eFormatUnicode16:
case eFormatUnicode32:
case eFormatUnsigned:
@@ -606,7 +593,7 @@ protected:
}
if (argc > 0)
- addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref,
+ addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(),
LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
@@ -618,7 +605,7 @@ protected:
if (argc == 2) {
lldb::addr_t end_addr = OptionArgParser::ToAddress(
- &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, nullptr);
+ &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, nullptr);
if (end_addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid end address expression.");
result.AppendError(error.AsCString());
@@ -778,26 +765,27 @@ protected:
m_prev_varobj_options = m_varobj_options;
m_prev_compiler_type = compiler_type;
- StreamFile outfile_stream;
- Stream *output_stream = nullptr;
+ std::unique_ptr<Stream> output_stream_storage;
+ Stream *output_stream_p = nullptr;
const FileSpec &outfile_spec =
m_outfile_options.GetFile().GetCurrentValue();
std::string path = outfile_spec.GetPath();
if (outfile_spec) {
- uint32_t open_options =
- File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+ auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
const bool append = m_outfile_options.GetAppend().GetCurrentValue();
if (append)
open_options |= File::eOpenOptionAppend;
- Status error = FileSystem::Instance().Open(outfile_stream.GetFile(),
- outfile_spec, open_options);
- if (error.Success()) {
+ auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);
+
+ if (outfile) {
+ auto outfile_stream_up =
+ std::make_unique<StreamFile>(std::move(outfile.get()));
if (m_memory_options.m_output_as_binary) {
const size_t bytes_written =
- outfile_stream.Write(data_sp->GetBytes(), bytes_read);
+ outfile_stream_up->Write(data_sp->GetBytes(), bytes_read);
if (bytes_written > 0) {
result.GetOutputStream().Printf(
"%zi bytes %s to '%s'\n", bytes_written,
@@ -813,16 +801,19 @@ protected:
} else {
// We are going to write ASCII to the file just point the
// output_stream to our outfile_stream...
- output_stream = &outfile_stream;
+ output_stream_storage = std::move(outfile_stream_up);
+ output_stream_p = output_stream_storage.get();
}
} else {
- result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n",
+ result.AppendErrorWithFormat("Failed to open file '%s' for %s:\n",
path.c_str(), append ? "append" : "write");
+
+ result.AppendError(llvm::toString(outfile.takeError()));
result.SetStatus(eReturnStatusFailed);
return false;
}
} else {
- output_stream = &result.GetOutputStream();
+ output_stream_p = &result.GetOutputStream();
}
ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
@@ -842,7 +833,7 @@ protected:
DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
eLanguageRuntimeDescriptionDisplayVerbosityFull, format));
- valobj_sp->Dump(*output_stream, options);
+ valobj_sp->Dump(*output_stream_p, options);
} else {
result.AppendErrorWithFormat(
"failed to create a value object for: (%s) %s\n",
@@ -882,13 +873,13 @@ protected:
}
}
- assert(output_stream);
+ assert(output_stream_p);
size_t bytes_dumped = DumpDataExtractor(
- data, output_stream, 0, format, item_byte_size, item_count,
+ data, output_stream_p, 0, format, item_byte_size, item_count,
num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0,
exe_scope);
m_next_addr = addr + bytes_dumped;
- output_stream->EOL();
+ output_stream_p->EOL();
return true;
}
@@ -906,14 +897,8 @@ protected:
CompilerType m_prev_compiler_type;
};
-static constexpr OptionDefinition g_memory_find_option_table[] = {
- // clang-format off
- {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
- {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Use text to find a byte pattern."},
- {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many times to perform the search."},
- {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
- // clang-format on
-};
+#define LLDB_OPTIONS_memory_find
+#include "CommandOptions.inc"
// Find the specified data in memory
class CommandObjectMemoryFind : public CommandObjectParsed {
@@ -925,14 +910,13 @@ public:
~OptionGroupFindMemory() override = default;
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_memory_find_option_table);
+ return llvm::makeArrayRef(g_memory_find_options);
}
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
ExecutionContext *execution_context) override {
Status error;
- const int short_option =
- g_memory_find_option_table[option_idx].short_option;
+ const int short_option = g_memory_find_options[option_idx].short_option;
switch (short_option) {
case 'e':
@@ -954,9 +938,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1056,13 +1038,13 @@ protected:
Status error;
lldb::addr_t low_addr = OptionArgParser::ToAddress(
- &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
+ &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
result.AppendError("invalid low address");
return false;
}
lldb::addr_t high_addr = OptionArgParser::ToAddress(
- &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, &error);
+ &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, &error);
if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
result.AppendError("invalid high address");
return false;
@@ -1203,12 +1185,8 @@ protected:
OptionGroupFindMemory m_memory_options;
};
-static constexpr OptionDefinition g_memory_write_option_table[] = {
- // clang-format off
- {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Write memory using the contents of a file."},
- {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
- // clang-format on
-};
+#define LLDB_OPTIONS_memory_write
+#include "CommandOptions.inc"
// Write memory to the inferior process
class CommandObjectMemoryWrite : public CommandObjectParsed {
@@ -1220,14 +1198,13 @@ public:
~OptionGroupWriteMemory() override = default;
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_memory_write_option_table);
+ return llvm::makeArrayRef(g_memory_write_options);
}
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
ExecutionContext *execution_context) override {
Status error;
- const int short_option =
- g_memory_write_option_table[option_idx].short_option;
+ const int short_option = g_memory_write_options[option_idx].short_option;
switch (short_option) {
case 'i':
@@ -1249,9 +1226,7 @@ public:
} break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1368,7 +1343,7 @@ protected:
Status error;
lldb::addr_t addr = OptionArgParser::ToAddress(
- &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
+ &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid address expression\n");
@@ -1435,6 +1410,7 @@ protected:
case eFormatBytesWithASCII:
case eFormatComplex:
case eFormatEnum:
+ case eFormatUnicode8:
case eFormatUnicode16:
case eFormatUnicode32:
case eFormatVectorOfChar:
@@ -1470,10 +1446,10 @@ protected:
// Be careful, getAsInteger with a radix of 16 rejects "0xab" so we
// have to special case that:
bool success = false;
- if (entry.ref.startswith("0x"))
- success = !entry.ref.getAsInteger(0, uval64);
+ if (entry.ref().startswith("0x"))
+ success = !entry.ref().getAsInteger(0, uval64);
if (!success)
- success = !entry.ref.getAsInteger(16, uval64);
+ success = !entry.ref().getAsInteger(16, uval64);
if (!success) {
result.AppendErrorWithFormat(
"'%s' is not a valid hex string value.\n", entry.c_str());
@@ -1491,7 +1467,7 @@ protected:
break;
}
case eFormatBoolean:
- uval64 = OptionArgParser::ToBoolean(entry.ref, false, &success);
+ uval64 = OptionArgParser::ToBoolean(entry.ref(), false, &success);
if (!success) {
result.AppendErrorWithFormat(
"'%s' is not a valid boolean string value.\n", entry.c_str());
@@ -1502,7 +1478,7 @@ protected:
break;
case eFormatBinary:
- if (entry.ref.getAsInteger(2, uval64)) {
+ if (entry.ref().getAsInteger(2, uval64)) {
result.AppendErrorWithFormat(
"'%s' is not a valid binary string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -1521,10 +1497,10 @@ protected:
case eFormatCharArray:
case eFormatChar:
case eFormatCString: {
- if (entry.ref.empty())
+ if (entry.ref().empty())
break;
- size_t len = entry.ref.size();
+ size_t len = entry.ref().size();
// Include the NULL for C strings...
if (m_format_options.GetFormat() == eFormatCString)
++len;
@@ -1541,7 +1517,7 @@ protected:
break;
}
case eFormatDecimal:
- if (entry.ref.getAsInteger(0, sval64)) {
+ if (entry.ref().getAsInteger(0, sval64)) {
result.AppendErrorWithFormat(
"'%s' is not a valid signed decimal value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -1559,7 +1535,7 @@ protected:
case eFormatUnsigned:
- if (!entry.ref.getAsInteger(0, uval64)) {
+ if (!entry.ref().getAsInteger(0, uval64)) {
result.AppendErrorWithFormat(
"'%s' is not a valid unsigned decimal string value.\n",
entry.c_str());
@@ -1577,7 +1553,7 @@ protected:
break;
case eFormatOctal:
- if (entry.ref.getAsInteger(8, uval64)) {
+ if (entry.ref().getAsInteger(8, uval64)) {
result.AppendErrorWithFormat(
"'%s' is not a valid octal string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -1663,7 +1639,7 @@ protected:
Status error;
lldb::addr_t addr = OptionArgParser::ToAddress(
- &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error);
+ &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS) {
result.AppendError("invalid address expression");
@@ -1728,7 +1704,7 @@ protected:
result.SetStatus(eReturnStatusFailed);
} else {
if (command.GetArgumentCount() == 1) {
- auto load_addr_str = command[0].ref;
+ auto load_addr_str = command[0].ref();
load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
LLDB_INVALID_ADDRESS, &error);
if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index 4011cceb8a26..03a3770d8df7 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -93,9 +93,11 @@ bool CommandObjectMultiword::Execute(const char *args_string,
return result.Succeeded();
}
- auto sub_command = args[0].ref;
- if (sub_command.empty())
+ auto sub_command = args[0].ref();
+ if (sub_command.empty()) {
+ result.AppendError("Need to specify a non-empty subcommand.");
return result.Succeeded();
+ }
if (sub_command.equals_lower("help")) {
this->CommandObject::GenerateHelpText(result);
@@ -136,9 +138,9 @@ bool CommandObjectMultiword::Execute(const char *args_string,
if (num_subcmd_matches > 0) {
error_msg.append(" Possible completions:");
- for (size_t i = 0; i < matches.GetSize(); i++) {
+ for (const std::string &match : matches) {
error_msg.append("\n\t");
- error_msg.append(matches.GetStringAtIndex(i));
+ error_msg.append(match);
}
}
error_msg.append("\n");
@@ -179,12 +181,8 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
"'help <command> <subcommand>'.\n");
}
-int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
- // Any of the command matches will provide a complete word, otherwise the
- // individual completers will override this.
- request.SetWordComplete(true);
-
- auto arg0 = request.GetParsedLine()[0].ref;
+void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
+ auto arg0 = request.GetParsedLine()[0].ref();
if (request.GetCursorIndex() == 0) {
StringList new_matches, descriptions;
AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches,
@@ -197,32 +195,28 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) {
StringList temp_matches;
CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
if (cmd_obj != nullptr) {
- if (request.GetParsedLine().GetArgumentCount() == 1) {
- request.SetWordComplete(true);
- } else {
+ if (request.GetParsedLine().GetArgumentCount() != 1) {
request.GetParsedLine().Shift();
- request.SetCursorCharPosition(0);
- request.GetParsedLine().AppendArgument(llvm::StringRef());
- return cmd_obj->HandleCompletion(request);
+ request.AppendEmptyArgument();
+ cmd_obj->HandleCompletion(request);
}
}
}
- return new_matches.GetSize();
- } else {
- StringList new_matches;
- CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
- if (sub_command_object == nullptr) {
- request.AddCompletions(new_matches);
- return request.GetNumberOfMatches();
- } else {
- // Remove the one match that we got from calling GetSubcommandObject.
- new_matches.DeleteStringAtIndex(0);
- request.AddCompletions(new_matches);
- request.GetParsedLine().Shift();
- request.SetCursorIndex(request.GetCursorIndex() - 1);
- return sub_command_object->HandleCompletion(request);
- }
+ return;
}
+
+ StringList new_matches;
+ CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches);
+ if (sub_command_object == nullptr) {
+ request.AddCompletions(new_matches);
+ return;
+ }
+
+ // Remove the one match that we got from calling GetSubcommandObject.
+ new_matches.DeleteStringAtIndex(0);
+ request.AddCompletions(new_matches);
+ request.ShiftArguments();
+ sub_command_object->HandleCompletion(request);
}
const char *CommandObjectMultiword::GetRepeatCommand(Args &current_command_args,
@@ -231,7 +225,7 @@ const char *CommandObjectMultiword::GetRepeatCommand(Args &current_command_args,
if (current_command_args.GetArgumentCount() <= index)
return nullptr;
CommandObject *sub_command_object =
- GetSubcommandObject(current_command_args[index].ref);
+ GetSubcommandObject(current_command_args[index].ref());
if (sub_command_object == nullptr)
return nullptr;
return sub_command_object->GetRepeatCommand(current_command_args, index);
@@ -360,19 +354,17 @@ Options *CommandObjectProxy::GetOptions() {
return nullptr;
}
-int CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
+void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->HandleCompletion(request);
- return 0;
+ proxy_command->HandleCompletion(request);
}
-int CommandObjectProxy::HandleArgumentCompletion(
+void CommandObjectProxy::HandleArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->HandleArgumentCompletion(request, opt_element_vector);
- return 0;
+ proxy_command->HandleArgumentCompletion(request, opt_element_vector);
}
const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 53549cdeee32..fbd13aa37bda 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -58,21 +58,8 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) {
return user | group | world;
}
-static constexpr OptionDefinition g_permissions_options[] = {
- // clang-format off
- {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"},
- {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."},
- {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to read."},
- {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to write."},
- {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to execute."},
- {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to read."},
- {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to write."},
- {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to execute."},
- {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to read."},
- {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to write."},
- {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to execute."},
- // clang-format on
-};
+#define LLDB_OPTIONS_permissions
+#include "CommandOptions.inc"
class OptionPermissions : public OptionGroup {
public:
@@ -130,8 +117,7 @@ public:
m_permissions |= lldb::eFilePermissionsWorldExecute;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -171,10 +157,9 @@ public:
~CommandObjectPlatformSelect() override = default;
- int HandleCompletion(CompletionRequest &request) override {
+ void HandleCompletion(CompletionRequest &request) override {
CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
nullptr);
- return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_option_group; }
@@ -585,12 +570,8 @@ public:
// "platform fread"
-static constexpr OptionDefinition g_platform_fread_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Number of bytes to read from the file." },
- // clang-format on
-};
+#define LLDB_OPTIONS_platform_fread
+#include "CommandOptions.inc"
class CommandObjectPlatformFRead : public CommandObjectParsed {
public:
@@ -650,9 +631,7 @@ protected:
option_arg.str().c_str());
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -678,12 +657,8 @@ protected:
// "platform fwrite"
-static constexpr OptionDefinition g_platform_fwrite_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Text to write to the file." },
- // clang-format on
-};
+#define LLDB_OPTIONS_platform_fwrite
+#include "CommandOptions.inc"
class CommandObjectPlatformFWrite : public CommandObjectParsed {
public:
@@ -740,9 +715,7 @@ protected:
m_data.assign(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1056,24 +1029,9 @@ protected:
// "platform process list"
-static OptionDefinition g_platform_process_list_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "List the process info for a specific process ID." },
- { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." },
- { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." },
- { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." },
- { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." },
- { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "Find processes that have a matching parent process ID." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." },
- { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." },
- { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." },
- { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose output." },
- // clang-format on
-};
+static PosixPlatformCommandOptionValidator posix_validator;
+#define LLDB_OPTIONS_platform_process_list
+#include "CommandOptions.inc"
class CommandObjectPlatformProcessList : public CommandObjectParsed {
public:
@@ -1195,23 +1153,6 @@ protected:
public:
CommandOptions()
: Options(), match_info(), show_args(false), verbose(false) {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
- PosixPlatformCommandOptionValidator *posix_validator =
- new PosixPlatformCommandOptionValidator();
- for (auto &Option : g_platform_process_list_options) {
- switch (Option.short_option) {
- case 'u':
- case 'U':
- case 'g':
- case 'G':
- Option.validator = posix_validator;
- break;
- default:
- break;
- }
- }
- });
}
~CommandOptions() override = default;
@@ -1323,10 +1264,12 @@ protected:
verbose = true;
break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
+ case 'x':
+ match_info.SetMatchAllUsers(true);
break;
+
+ default:
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1397,9 +1340,9 @@ protected:
Stream &ostrm = result.GetOutputStream();
for (auto &entry : args.entries()) {
lldb::pid_t pid;
- if (entry.ref.getAsInteger(0, pid)) {
+ if (entry.ref().getAsInteger(0, pid)) {
result.AppendErrorWithFormat("invalid process ID argument '%s'",
- entry.ref.str().c_str());
+ entry.ref().str().c_str());
result.SetStatus(eReturnStatusFailed);
break;
} else {
@@ -1436,14 +1379,8 @@ protected:
}
};
-static constexpr OptionDefinition g_platform_process_attach_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
- { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." },
- { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." },
- { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." },
- // clang-format on
-};
+#define LLDB_OPTIONS_platform_process_attach
+#include "CommandOptions.inc"
class CommandObjectPlatformProcessAttach : public CommandObjectParsed {
public:
@@ -1486,9 +1423,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1501,7 +1436,7 @@ public:
return llvm::makeArrayRef(g_platform_process_attach_options);
}
- bool HandleOptionArgumentCompletion(
+ void HandleOptionArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector,
int opt_element_index, CommandInterpreter &interpreter) override {
int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
@@ -1509,37 +1444,36 @@ public:
// We are only completing the name option for now...
- if (GetDefinitions()[opt_defs_index].short_option == 'n') {
- // Are we in the name?
+ // Are we in the name?
+ if (GetDefinitions()[opt_defs_index].short_option != 'n')
+ return;
- // Look to see if there is a -P argument provided, and if so use that
- // plugin, otherwise use the default plugin.
+ // Look to see if there is a -P argument provided, and if so use that
+ // plugin, otherwise use the default plugin.
- const char *partial_name = nullptr;
- partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
+ const char *partial_name = nullptr;
+ partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (platform_sp) {
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const uint32_t num_matches = process_infos.GetSize();
- if (num_matches > 0) {
- for (uint32_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(llvm::StringRef(
- process_infos.GetProcessNameAtIndex(i),
- process_infos.GetProcessNameLengthAtIndex(i)));
- }
- }
- }
+ PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ if (partial_name) {
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ partial_name, FileSpec::Style::native);
+ match_info.SetNameMatchType(NameMatch::StartsWith);
}
+ platform_sp->FindProcesses(match_info, process_infos);
+ const uint32_t num_matches = process_infos.GetSize();
+ if (num_matches == 0)
+ return;
- return false;
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ request.AddCompletion(process_infos.GetProcessNameAtIndex(i));
+ }
+ return;
}
// Options table: Required for subclasses of Options.
@@ -1615,11 +1549,8 @@ private:
};
// "platform shell"
-static constexpr OptionDefinition g_platform_shell_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." },
- // clang-format on
-};
+#define LLDB_OPTIONS_platform_shell
+#include "CommandOptions.inc"
class CommandObjectPlatformShell : public CommandObjectRaw {
public:
@@ -1650,9 +1581,7 @@ public:
timeout = std::chrono::seconds(timeout_sec);
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp
index 89e01ba52027..b70885061385 100644
--- a/source/Commands/CommandObjectPlugin.cpp
+++ b/source/Commands/CommandObjectPlugin.cpp
@@ -37,13 +37,12 @@ public:
~CommandObjectPluginLoad() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -58,7 +57,7 @@ protected:
Status error;
- FileSpec dylib_fspec(command[0].ref);
+ FileSpec dylib_fspec(command[0].ref());
FileSystem::Instance().Resolve(dylib_fspec);
if (GetDebugger().LoadPlugin(dylib_fspec, error))
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index b20a2d533332..e5aa78afabb3 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -127,14 +127,13 @@ public:
~CommandObjectProcessLaunch() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_options; }
@@ -255,16 +254,8 @@ protected:
ProcessLaunchCommandOptions m_options;
};
-static constexpr OptionDefinition g_process_attach_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Immediately continue the process once attached." },
- { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
- { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." },
- { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." },
- { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include existing processes when doing attach -w." },
- { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." },
- // clang-format on
-};
+#define LLDB_OPTIONS_process_attach
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessAttach
class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
@@ -316,9 +307,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -331,7 +320,7 @@ public:
return llvm::makeArrayRef(g_process_attach_options);
}
- bool HandleOptionArgumentCompletion(
+ void HandleOptionArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector,
int opt_element_index, CommandInterpreter &interpreter) override {
int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
@@ -339,37 +328,33 @@ public:
// We are only completing the name option for now...
- if (GetDefinitions()[opt_defs_index].short_option == 'n') {
- // Are we in the name?
-
- // Look to see if there is a -P argument provided, and if so use that
- // plugin, otherwise use the default plugin.
-
- const char *partial_name = nullptr;
- partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (platform_sp) {
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const size_t num_matches = process_infos.GetSize();
- if (num_matches > 0) {
- for (size_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(llvm::StringRef(
- process_infos.GetProcessNameAtIndex(i),
- process_infos.GetProcessNameLengthAtIndex(i)));
- }
- }
- }
+ // Are we in the name?
+ if (GetDefinitions()[opt_defs_index].short_option != 'n')
+ return;
+
+ // Look to see if there is a -P argument provided, and if so use that
+ // plugin, otherwise use the default plugin.
+
+ const char *partial_name = nullptr;
+ partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
+
+ PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ if (partial_name) {
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ partial_name, FileSpec::Style::native);
+ match_info.SetNameMatchType(NameMatch::StartsWith);
+ }
+ platform_sp->FindProcesses(match_info, process_infos);
+ const size_t num_matches = process_infos.GetSize();
+ if (num_matches == 0)
+ return;
+ for (size_t i = 0; i < num_matches; ++i) {
+ request.AddCompletion(process_infos.GetProcessNameAtIndex(i));
}
-
- return false;
}
// Instance variables to hold the values for command options.
@@ -444,7 +429,6 @@ protected:
result.AppendMessage(stream.GetString());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
result.SetDidChangeProcessState(true);
- result.SetAbnormalStopWasExpected(true);
} else {
result.AppendError(
"no error returned from Target::Attach, and target has no process");
@@ -505,11 +489,8 @@ protected:
// CommandObjectProcessContinue
-static constexpr OptionDefinition g_process_continue_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread." }
- // clang-format on
-};
+#define LLDB_OPTIONS_process_continue
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessContinue
@@ -550,9 +531,7 @@ protected:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -666,11 +645,8 @@ protected:
};
// CommandObjectProcessDetach
-static constexpr OptionDefinition g_process_detach_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
- // clang-format on
-};
+#define LLDB_OPTIONS_process_detach
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessDetach
@@ -703,9 +679,7 @@ public:
}
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -762,12 +736,8 @@ protected:
};
// CommandObjectProcessConnect
-
-static constexpr OptionDefinition g_process_connect_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
- // clang-format on
-};
+#define LLDB_OPTIONS_process_connect
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessConnect
@@ -794,9 +764,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -887,12 +855,8 @@ public:
};
// CommandObjectProcessLoad
-
-static constexpr OptionDefinition g_process_load_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." },
- // clang-format on
-};
+#define LLDB_OPTIONS_process_load
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessLoad
@@ -919,9 +883,7 @@ public:
install_path.SetFile(option_arg, FileSpec::Style::native);
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -960,7 +922,7 @@ protected:
for (auto &entry : command.entries()) {
Status error;
PlatformSP platform = process->GetTarget().GetPlatform();
- llvm::StringRef image_path = entry.ref;
+ llvm::StringRef image_path = entry.ref();
uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
if (!m_options.do_install) {
@@ -1022,9 +984,9 @@ protected:
for (auto &entry : command.entries()) {
uint32_t image_token;
- if (entry.ref.getAsInteger(0, image_token)) {
+ if (entry.ref().getAsInteger(0, image_token)) {
result.AppendErrorWithFormat("invalid image index argument '%s'",
- entry.ref.str().c_str());
+ entry.ref().str().c_str());
result.SetStatus(eReturnStatusFailed);
break;
} else {
@@ -1271,14 +1233,8 @@ public:
};
// CommandObjectProcessHandle
-
-static constexpr OptionDefinition g_process_handle_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
- { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
- { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }
- // clang-format on
-};
+#define LLDB_OPTIONS_process_handle
+#include "CommandOptions.inc"
#pragma mark CommandObjectProcessHandle
@@ -1306,9 +1262,7 @@ public:
pass = option_arg;
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1335,7 +1289,7 @@ public:
"Manage LLDB handling of OS signals for the "
"current target process. Defaults to showing "
"current policy.",
- nullptr),
+ nullptr, eCommandRequiresTarget),
m_options() {
SetHelpLong("\nIf no signals are specified, update them all. If no update "
"option is specified, list the current values.");
@@ -1420,15 +1374,7 @@ public:
protected:
bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
- TargetSP target_sp = GetDebugger().GetSelectedTarget();
-
- if (!target_sp) {
- result.AppendError("No current target;"
- " cannot handle signals until you have a valid target "
- "and process.\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target_sp = &GetSelectedTarget();
ProcessSP process_sp = target_sp->GetProcessSP();
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index 34482a8b1e4f..13266f8fce35 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -32,14 +32,8 @@ using namespace lldb;
using namespace lldb_private;
// "register read"
-
-static constexpr OptionDefinition g_register_read_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." },
- { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Specify which register sets to dump by index." },
- { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show all register sets." },
- // clang-format on
-};
+#define LLDB_OPTIONS_register_read
+#include "CommandOptions.inc"
class CommandObjectRegisterRead : public CommandObjectParsed {
public:
@@ -212,7 +206,7 @@ protected:
// consistent towards the user and allow them to say reg read $rbx -
// internally, however, we should be strict and not allow ourselves
// to call our registers $rbx in our own API
- auto arg_str = entry.ref;
+ auto arg_str = entry.ref();
arg_str.consume_front("$");
reg_info = reg_ctx->GetRegisterInfoByName(arg_str);
@@ -278,9 +272,7 @@ protected:
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -343,8 +335,8 @@ protected:
"register write takes exactly 2 arguments: <reg-name> <value>");
result.SetStatus(eReturnStatusFailed);
} else {
- auto reg_name = command[0].ref;
- auto value_str = command[1].ref;
+ auto reg_name = command[0].ref();
+ auto value_str = command[1].ref();
// in most LLDB commands we accept $rbx as the name for register RBX -
// and here we would reject it and non-existant. we should be more
diff --git a/source/Commands/CommandObjectReproducer.cpp b/source/Commands/CommandObjectReproducer.cpp
index 4b0e9e36d202..dc4579c20fc2 100644
--- a/source/Commands/CommandObjectReproducer.cpp
+++ b/source/Commands/CommandObjectReproducer.cpp
@@ -8,6 +8,8 @@
#include "CommandObjectReproducer.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -16,7 +18,58 @@
#include "lldb/Interpreter/OptionGroupBoolean.h"
using namespace lldb;
+using namespace llvm;
using namespace lldb_private;
+using namespace lldb_private::repro;
+
+enum ReproducerProvider {
+ eReproducerProviderCommands,
+ eReproducerProviderFiles,
+ eReproducerProviderGDB,
+ eReproducerProviderVersion,
+ eReproducerProviderWorkingDirectory,
+ eReproducerProviderNone
+};
+
+static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
+ {
+ eReproducerProviderCommands,
+ "commands",
+ "Command Interpreter Commands",
+ },
+ {
+ eReproducerProviderFiles,
+ "files",
+ "Files",
+ },
+ {
+ eReproducerProviderGDB,
+ "gdb",
+ "GDB Remote Packets",
+ },
+ {
+ eReproducerProviderVersion,
+ "version",
+ "Version",
+ },
+ {
+ eReproducerProviderWorkingDirectory,
+ "cwd",
+ "Working Directory",
+ },
+ {
+ eReproducerProviderNone,
+ "none",
+ "None",
+ },
+};
+
+static constexpr OptionEnumValues ReproducerProviderType() {
+ return OptionEnumValues(g_reproducer_provider_type);
+}
+
+#define LLDB_OPTIONS_reproducer
+#include "CommandOptions.inc"
class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
@@ -38,10 +91,10 @@ protected:
return false;
}
- auto &r = repro::Reproducer::Instance();
+ auto &r = Reproducer::Instance();
if (auto generator = r.GetGenerator()) {
generator->Keep();
- } else if (r.GetLoader()) {
+ } else if (r.IsReplaying()) {
// Make this operation a NOP in replay mode.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
@@ -84,10 +137,10 @@ protected:
return false;
}
- auto &r = repro::Reproducer::Instance();
- if (r.GetGenerator()) {
+ auto &r = Reproducer::Instance();
+ if (r.IsCapturing()) {
result.GetOutputStream() << "Reproducer is in capture mode.\n";
- } else if (r.GetLoader()) {
+ } else if (r.IsReplaying()) {
result.GetOutputStream() << "Reproducer is in replay mode.\n";
} else {
result.GetOutputStream() << "Reproducer is off.\n";
@@ -98,17 +151,235 @@ protected:
}
};
+static void SetError(CommandReturnObject &result, Error err) {
+ result.GetErrorStream().Printf("error: %s\n",
+ toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+}
+
+class CommandObjectReproducerDump : public CommandObjectParsed {
+public:
+ CommandObjectReproducerDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer dump",
+ "Dump the information contained in a reproducer. "
+ "If no reproducer is specified during replay, it "
+ "dumps the content of the current reproducer.",
+ nullptr) {}
+
+ ~CommandObjectReproducerDump() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), file() {}
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ file.SetFile(option_arg, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file);
+ break;
+ case 'p':
+ provider = (ReproducerProvider)OptionArgParser::ToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat("unrecognized value for provider '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ file.Clear();
+ provider = eReproducerProviderNone;
+ }
+
+ ArrayRef<OptionDefinition> GetDefinitions() override {
+ return makeArrayRef(g_reproducer_options);
+ }
+
+ FileSpec file;
+ ReproducerProvider provider = eReproducerProviderNone;
+ };
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ // If no reproducer path is specified, use the loader currently used for
+ // replay. Otherwise create a new loader just for dumping.
+ llvm::Optional<Loader> loader_storage;
+ Loader *loader = nullptr;
+ if (!m_options.file) {
+ loader = Reproducer::Instance().GetLoader();
+ if (loader == nullptr) {
+ result.SetError(
+ "Not specifying a reproducer is only support during replay.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return false;
+ }
+ } else {
+ loader_storage.emplace(m_options.file);
+ loader = &(*loader_storage);
+ if (Error err = loader->LoadIndex()) {
+ SetError(result, std::move(err));
+ return false;
+ }
+ }
+
+ // If we get here we should have a valid loader.
+ assert(loader);
+
+ switch (m_options.provider) {
+ case eReproducerProviderFiles: {
+ FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>();
+
+ // Read the VFS mapping.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
+ vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath());
+ if (!buffer) {
+ SetError(result, errorCodeToError(buffer.getError()));
+ return false;
+ }
+
+ // Initialize a VFS from the given mapping.
+ IntrusiveRefCntPtr<vfs::FileSystem> vfs = vfs::getVFSFromYAML(
+ std::move(buffer.get()), nullptr, vfs_mapping.GetPath());
+
+ // Dump the VFS to a buffer.
+ std::string str;
+ raw_string_ostream os(str);
+ static_cast<vfs::RedirectingFileSystem &>(*vfs).dump(os);
+ os.flush();
+
+ // Return the string.
+ result.AppendMessage(str);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderVersion: {
+ Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
+ if (!version) {
+ SetError(result, version.takeError());
+ return false;
+ }
+ result.AppendMessage(*version);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderWorkingDirectory: {
+ Expected<std::string> cwd =
+ loader->LoadBuffer<WorkingDirectoryProvider>();
+ if (!cwd) {
+ SetError(result, cwd.takeError());
+ return false;
+ }
+ result.AppendMessage(*cwd);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderCommands: {
+ // Create a new command loader.
+ std::unique_ptr<repro::CommandLoader> command_loader =
+ repro::CommandLoader::Create(loader);
+ if (!command_loader) {
+ SetError(result,
+ make_error<StringError>(llvm::inconvertibleErrorCode(),
+ "Unable to create command loader."));
+ return false;
+ }
+
+ // Iterate over the command files and dump them.
+ while (true) {
+ llvm::Optional<std::string> command_file =
+ command_loader->GetNextFile();
+ if (!command_file)
+ break;
+
+ auto command_buffer = llvm::MemoryBuffer::getFile(*command_file);
+ if (auto err = command_buffer.getError()) {
+ SetError(result, errorCodeToError(err));
+ return false;
+ }
+ result.AppendMessage((*command_buffer)->getBuffer());
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderGDB: {
+ FileSpec gdb_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ auto error_or_file = MemoryBuffer::getFile(gdb_file.GetPath());
+ if (auto err = error_or_file.getError()) {
+ SetError(result, errorCodeToError(err));
+ return false;
+ }
+
+ std::vector<GDBRemotePacket> packets;
+ yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> packets;
+
+ if (auto err = yin.error()) {
+ SetError(result, errorCodeToError(err));
+ return false;
+ }
+
+ for (GDBRemotePacket &packet : packets) {
+ packet.Dump(result.GetOutputStream());
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ case eReproducerProviderNone:
+ result.SetError("No valid provider specified.");
+ return false;
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
CommandObjectReproducer::CommandObjectReproducer(
CommandInterpreter &interpreter)
: CommandObjectMultiword(
interpreter, "reproducer",
- "Commands to inspect and manipulate the reproducer functionality.",
- "log <subcommand> [<command-options>]") {
+ "Commands for manipulating reproducers. Reproducers make it possible "
+ "to capture full debug sessions with all its dependencies. The "
+ "resulting reproducer is used to replay the debug session while "
+ "debugging the debugger.\n"
+ "Because reproducers need the whole the debug session from "
+ "beginning to end, you need to launch the debugger in capture or "
+ "replay mode, commonly though the command line driver.\n"
+ "Reproducers are unrelated record-replay debugging, as you cannot "
+ "interact with the debugger during replay.\n",
+ "reproducer <subcommand> [<subcommand-options>]") {
LoadSubCommand(
"generate",
CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
LoadSubCommand("status", CommandObjectSP(
new CommandObjectReproducerStatus(interpreter)));
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectReproducerDump(interpreter)));
}
CommandObjectReproducer::~CommandObjectReproducer() = default;
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index 55a0002c5997..248a04613d7a 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -20,11 +20,8 @@ using namespace lldb;
using namespace lldb_private;
// CommandObjectSettingsSet
-
-static constexpr OptionDefinition g_settings_set_options[] = {
#define LLDB_OPTIONS_settings_set
#include "CommandOptions.inc"
-};
class CommandObjectSettingsSet : public CommandObjectRaw {
public:
@@ -107,9 +104,7 @@ insert-before or insert-after.");
m_global = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized options '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -129,15 +124,14 @@ insert-before or insert-after.");
bool m_force;
};
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
const size_t argc = request.GetParsedLine().GetArgumentCount();
const char *arg = nullptr;
- int setting_var_idx;
- for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
- ++setting_var_idx) {
+ size_t setting_var_idx;
+ for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
if (arg && arg[0] != '-')
break; // We found our setting variable name index
@@ -147,27 +141,27 @@ insert-before or insert-after.");
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
- } else {
+ return;
+ }
arg =
request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
- if (arg) {
- if (arg[0] == '-') {
- // Complete option name
- } else {
- // Complete setting value
- const char *setting_var_name =
- request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
- Status error;
- lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
- &m_exe_ctx, setting_var_name, false, error));
- if (value_sp) {
- value_sp->AutoComplete(m_interpreter, request);
- }
- }
- }
- }
- return request.GetNumberOfMatches();
+ if (!arg)
+ return;
+
+ // Complete option name
+ if (arg[0] != '-')
+ return;
+
+ // Complete setting value
+ const char *setting_var_name =
+ request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
+ Status error;
+ lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
+ &m_exe_ctx, setting_var_name, false, error));
+ if (!value_sp)
+ return;
+ value_sp->AutoComplete(m_interpreter, request);
}
protected:
@@ -210,16 +204,13 @@ protected:
}
// Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, false, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.ltrim();
Status error;
- if (m_options.m_global) {
+ if (m_options.m_global)
error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
- var_name, var_value_cstr);
- }
+ var_name, var_value);
if (error.Success()) {
// FIXME this is the same issue as the one in commands script import
@@ -230,7 +221,7 @@ protected:
ExecutionContext exe_ctx(m_exe_ctx);
m_exe_ctx.Clear();
error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
- var_name, var_value_cstr);
+ var_name, var_value);
}
if (error.Fail()) {
@@ -274,13 +265,12 @@ public:
~CommandObjectSettingsShow() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -290,7 +280,7 @@ protected:
if (!args.empty()) {
for (const auto &arg : args) {
Status error(GetDebugger().DumpPropertyValue(
- &m_exe_ctx, result.GetOutputStream(), arg.ref,
+ &m_exe_ctx, result.GetOutputStream(), arg.ref(),
OptionValue::eDumpGroupValue));
if (error.Success()) {
result.GetOutputStream().EOL();
@@ -309,11 +299,8 @@ protected:
};
// CommandObjectSettingsWrite -- Write settings to file
-
-static constexpr OptionDefinition g_settings_write_options[] = {
#define LLDB_OPTIONS_settings_write
#include "CommandOptions.inc"
-};
class CommandObjectSettingsWrite : public CommandObjectParsed {
public:
@@ -363,9 +350,7 @@ public:
m_append = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -390,12 +375,11 @@ protected:
FileSpec file_spec(m_options.m_filename);
FileSystem::Instance().Resolve(file_spec);
std::string path(file_spec.GetPath());
- uint32_t options = File::OpenOptions::eOpenOptionWrite |
- File::OpenOptions::eOpenOptionCanCreate;
+ auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
if (m_options.m_append)
- options |= File::OpenOptions::eOpenOptionAppend;
+ options |= File::eOpenOptionAppend;
else
- options |= File::OpenOptions::eOpenOptionTruncate;
+ options |= File::eOpenOptionTruncate;
StreamFile out_file(path.c_str(), options,
lldb::eFilePermissionsFileDefault);
@@ -417,7 +401,7 @@ protected:
for (const auto &arg : args) {
Status error(GetDebugger().DumpPropertyValue(
- &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
+ &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
if (!error.Success()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -432,11 +416,8 @@ private:
};
// CommandObjectSettingsRead -- Read settings from file
-
-static constexpr OptionDefinition g_settings_read_options[] = {
#define LLDB_OPTIONS_settings_read
#include "CommandOptions.inc"
-};
class CommandObjectSettingsRead : public CommandObjectParsed {
public:
@@ -467,9 +448,7 @@ public:
m_filename.assign(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -536,13 +515,12 @@ public:
~CommandObjectSettingsList() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -622,14 +600,15 @@ public:
~CommandObjectSettingsRemove() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -645,8 +624,8 @@ protected:
const size_t argc = cmd_args.GetArgumentCount();
if (argc == 0) {
- result.AppendError("'settings set' takes an array or dictionary item, or "
- "an array followed by one or more indexes, or a "
+ result.AppendError("'settings remove' takes an array or dictionary item, "
+ "or an array followed by one or more indexes, or a "
"dictionary followed by one or more key names to "
"remove");
result.SetStatus(eReturnStatusFailed);
@@ -656,19 +635,17 @@ protected:
const char *var_name = cmd_args.GetArgumentAtIndex(0);
if ((var_name == nullptr) || (var_name[0] == '\0')) {
result.AppendError(
- "'settings set' command requires a valid variable name");
+ "'settings remove' command requires a valid variable name");
result.SetStatus(eReturnStatusFailed);
return false;
}
// Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, true, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
Status error(GetDebugger().SetPropertyValue(
- &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
+ &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -735,16 +712,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
-
- return request.GetNumberOfMatches();
}
protected:
@@ -762,13 +737,11 @@ protected:
}
// Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, true, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
Status error(GetDebugger().SetPropertyValue(
- &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
+ &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -833,16 +806,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
-
- return request.GetNumberOfMatches();
}
protected:
@@ -868,13 +839,11 @@ protected:
}
// Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, true, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
Status error(GetDebugger().SetPropertyValue(
- &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
+ &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -936,16 +905,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
-
- return request.GetNumberOfMatches();
}
protected:
@@ -971,13 +938,11 @@ protected:
}
// Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, true, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
Status error(GetDebugger().SetPropertyValue(
- &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
+ &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1028,16 +993,14 @@ public:
// !WantsRawCommandString.
bool WantsCompletion() override { return true; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
-
- return request.GetNumberOfMatches();
}
protected:
@@ -1065,13 +1028,11 @@ protected:
// character string later on.
// Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr =
- Args::StripSpaces(var_value_string, true, true, false);
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
Status error(GetDebugger().SetPropertyValue(
- &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
+ &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
if (error.Fail()) {
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1107,16 +1068,14 @@ public:
~CommandObjectSettingsClear() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
// Attempting to complete variable name
if (request.GetCursorIndex() < 2)
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
request, nullptr);
-
- return request.GetNumberOfMatches();
}
protected:
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 1b515d0f1099..78c8bc811926 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -33,18 +33,8 @@ using namespace lldb_private;
#pragma mark CommandObjectSourceInfo
// CommandObjectSourceInfo - debug line entries dumping command
-
-static constexpr OptionDefinition g_source_info_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of line entries to display." },
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." },
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
- { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." },
- { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." },
- { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
- { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
- // clang-format on
-};
+#define LLDB_OPTIONS_source_info
+#include "CommandOptions.inc"
class CommandObjectSourceInfo : public CommandObjectParsed {
class CommandOptions : public Options {
@@ -92,9 +82,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
modules.push_back(std::string(option_arg));
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -404,17 +392,18 @@ protected:
// const.
ModuleList module_list =
(m_module_list.GetSize() > 0) ? m_module_list : target->GetImages();
- size_t num_matches =
- module_list.FindFunctions(name, eFunctionNameTypeAuto,
- /*include_symbols=*/false,
- /*include_inlines=*/true,
- /*append=*/true, sc_list_funcs);
+ module_list.FindFunctions(name, eFunctionNameTypeAuto,
+ /*include_symbols=*/false,
+ /*include_inlines=*/true, sc_list_funcs);
+ size_t num_matches = sc_list_funcs.GetSize();
+
if (!num_matches) {
// If we didn't find any functions with that name, try searching for
// symbols that line up exactly with function addresses.
SymbolContextList sc_list_symbols;
- size_t num_symbol_matches = module_list.FindFunctionSymbols(
+ module_list.FindFunctionSymbols(
name, eFunctionNameTypeAuto, sc_list_symbols);
+ size_t num_symbol_matches = sc_list_symbols.GetSize();
for (size_t i = 0; i < num_symbol_matches; i++) {
SymbolContext sc;
sc_list_symbols.GetContextAtIndex(i, sc);
@@ -592,7 +581,8 @@ protected:
FileSpec module_file_spec(m_options.modules[i]);
if (module_file_spec) {
ModuleSpec module_spec(module_file_spec);
- if (target->GetImages().FindModules(module_spec, m_module_list) == 0)
+ target->GetImages().FindModules(module_spec, m_module_list);
+ if (m_module_list.IsEmpty())
result.AppendWarningWithFormat("No module found for '%s'.\n",
m_options.modules[i].c_str());
}
@@ -643,19 +633,8 @@ protected:
#pragma mark CommandObjectSourceList
// CommandObjectSourceList
-
-static constexpr OptionDefinition g_source_list_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of source lines to display." },
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." },
- { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." },
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
- { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the display source." },
- { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
- { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
- { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." },
- // clang-format on
-};
+#define LLDB_OPTIONS_source_list
+#include "CommandOptions.inc"
class CommandObjectSourceList : public CommandObjectParsed {
class CommandOptions : public Options {
@@ -704,9 +683,7 @@ class CommandObjectSourceList : public CommandObjectParsed {
reverse = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -759,7 +736,7 @@ public:
// the arguments directly.
auto iter =
llvm::find_if(current_command_args, [](const Args::ArgEntry &e) {
- return e.ref == "-r" || e.ref == "--reverse";
+ return e.ref() == "-r" || e.ref() == "--reverse";
});
if (iter == current_command_args.end())
return m_cmd_name.c_str();
@@ -897,13 +874,11 @@ protected:
// these somewhere, there should probably be a module-filter-list that can be
// passed to the various ModuleList::Find* calls, which would either be a
// vector of string names or a ModuleSpecList.
- size_t FindMatchingFunctions(Target *target, ConstString name,
+ void FindMatchingFunctions(Target *target, ConstString name,
SymbolContextList &sc_list) {
// Displaying the source for a symbol:
bool include_inlines = true;
- bool append = true;
bool include_symbols = false;
- size_t num_matches = 0;
if (m_options.num_lines == 0)
m_options.num_lines = 10;
@@ -917,22 +892,20 @@ protected:
ModuleSpec module_spec(module_file_spec);
matching_modules.Clear();
target->GetImages().FindModules(module_spec, matching_modules);
- num_matches += matching_modules.FindFunctions(
+ matching_modules.FindFunctions(
name, eFunctionNameTypeAuto, include_symbols, include_inlines,
- append, sc_list);
+ sc_list);
}
}
} else {
- num_matches = target->GetImages().FindFunctions(
- name, eFunctionNameTypeAuto, include_symbols, include_inlines, append,
- sc_list);
+ target->GetImages().FindFunctions(name, eFunctionNameTypeAuto,
+ include_symbols, include_inlines,
+ sc_list);
}
- return num_matches;
}
- size_t FindMatchingFunctionSymbols(Target *target, ConstString name,
- SymbolContextList &sc_list) {
- size_t num_matches = 0;
+ void FindMatchingFunctionSymbols(Target *target, ConstString name,
+ SymbolContextList &sc_list) {
const size_t num_modules = m_options.modules.size();
if (num_modules > 0) {
ModuleList matching_modules;
@@ -942,15 +915,14 @@ protected:
ModuleSpec module_spec(module_file_spec);
matching_modules.Clear();
target->GetImages().FindModules(module_spec, matching_modules);
- num_matches += matching_modules.FindFunctionSymbols(
- name, eFunctionNameTypeAuto, sc_list);
+ matching_modules.FindFunctionSymbols(name, eFunctionNameTypeAuto,
+ sc_list);
}
}
} else {
- num_matches = target->GetImages().FindFunctionSymbols(
- name, eFunctionNameTypeAuto, sc_list);
+ target->GetImages().FindFunctionSymbols(name, eFunctionNameTypeAuto,
+ sc_list);
}
- return num_matches;
}
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -970,13 +942,15 @@ protected:
ConstString name(m_options.symbol_name.c_str());
// Displaying the source for a symbol. Search for function named name.
- size_t num_matches = FindMatchingFunctions(target, name, sc_list);
+ FindMatchingFunctions(target, name, sc_list);
+ size_t num_matches = sc_list.GetSize();
if (!num_matches) {
// If we didn't find any functions with that name, try searching for
// symbols that line up exactly with function addresses.
SymbolContextList sc_list_symbols;
- size_t num_symbol_matches =
- FindMatchingFunctionSymbols(target, name, sc_list_symbols);
+ FindMatchingFunctionSymbols(target, name, sc_list_symbols);
+ size_t num_symbol_matches =sc_list_symbols.GetSize();
+
for (size_t i = 0; i < num_symbol_matches; i++) {
SymbolContext sc;
sc_list_symbols.GetContextAtIndex(i, sc);
diff --git a/source/Commands/CommandObjectStats.cpp b/source/Commands/CommandObjectStats.cpp
index a73c2a8e0409..e3a1f9433662 100644
--- a/source/Commands/CommandObjectStats.cpp
+++ b/source/Commands/CommandObjectStats.cpp
@@ -26,15 +26,15 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
+ Target &target = GetSelectedOrDummyTarget();
- if (target->GetCollectingStats()) {
+ if (target.GetCollectingStats()) {
result.AppendError("statistics already enabled");
result.SetStatus(eReturnStatusFailed);
return false;
}
- target->SetCollectingStats(true);
+ target.SetCollectingStats(true);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -51,15 +51,15 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
+ Target &target = GetSelectedOrDummyTarget();
- if (!target->GetCollectingStats()) {
+ if (!target.GetCollectingStats()) {
result.AppendError("need to enable statistics before disabling them");
result.SetStatus(eReturnStatusFailed);
return false;
}
- target->SetCollectingStats(false);
+ target.SetCollectingStats(false);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -75,10 +75,10 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
+ Target &target = GetSelectedOrDummyTarget();
uint32_t i = 0;
- for (auto &stat : target->GetStatistics()) {
+ for (auto &stat : target.GetStatistics()) {
result.AppendMessageWithFormat(
"%s : %u\n",
lldb_private::GetStatDescription(static_cast<lldb_private::StatisticKind>(i))
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index e913a28501f2..abf7895a7384 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -37,7 +37,6 @@
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
@@ -135,22 +134,27 @@ static uint32_t DumpTargetList(TargetList &target_list,
}
// Note that the negation in the argument name causes a slightly confusing
-// mapping of the enum values,
+// mapping of the enum values.
static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
- {eLoadDependentsDefault, "default",
- "Only load dependents when the target is an executable."},
- {eLoadDependentsNo, "true",
- "Don't load dependents, even if the target is an executable."},
- {eLoadDependentsYes, "false",
- "Load dependents, even if the target is not an executable."}};
-
-static constexpr OptionDefinition g_dependents_options[] = {
- {LLDB_OPT_SET_1, false, "no-dependents", 'd',
- OptionParser::eOptionalArgument, nullptr,
- OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue,
- "Whether or not to load dependents when creating a target. If the option "
- "is not specified, the value is implicitly 'default'. If the option is "
- "specified but without a value, the value is implicitly 'true'."}};
+ {
+ eLoadDependentsDefault,
+ "default",
+ "Only load dependents when the target is an executable.",
+ },
+ {
+ eLoadDependentsNo,
+ "true",
+ "Don't load dependents, even if the target is an executable.",
+ },
+ {
+ eLoadDependentsYes,
+ "false",
+ "Load dependents, even if the target is not an executable.",
+ },
+};
+
+#define LLDB_OPTIONS_target_dependents
+#include "CommandOptions.inc"
class OptionGroupDependents : public OptionGroup {
public:
@@ -159,7 +163,7 @@ public:
~OptionGroupDependents() override {}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_dependents_options);
+ return llvm::makeArrayRef(g_target_dependents_options);
}
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
@@ -172,11 +176,13 @@ public:
return error;
}
- const char short_option = g_dependents_options[option_idx].short_option;
+ const char short_option =
+ g_target_dependents_options[option_idx].short_option;
if (short_option == 'd') {
LoadDependentFiles tmp_load_dependents;
tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
- option_value, g_dependents_options[option_idx].enum_values, 0, error);
+ option_value, g_target_dependents_options[option_idx].enum_values, 0,
+ error);
if (error.Success())
m_load_dependent_files = tmp_load_dependents;
} else {
@@ -252,13 +258,12 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -444,7 +449,8 @@ protected:
}
} else {
result.AppendMessageWithFormat(
- "Current executable set to '%s' (%s).\n", file_path,
+ "Current executable set to '%s' (%s).\n",
+ file_spec.GetPath().c_str(),
target_sp->GetArchitecture().GetArchitectureName());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
@@ -619,7 +625,7 @@ protected:
for (auto &entry : args.entries()) {
uint32_t target_idx;
- if (entry.ref.getAsInteger(0, target_idx)) {
+ if (entry.ref().getAsInteger(0, target_idx)) {
result.AppendErrorWithFormat("invalid target index '%s'\n",
entry.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -792,12 +798,12 @@ public:
static size_t GetVariableCallback(void *baton, const char *name,
VariableList &variable_list) {
+ size_t old_size = variable_list.GetSize();
Target *target = static_cast<Target *>(baton);
- if (target) {
- return target->GetImages().FindGlobalVariables(ConstString(name),
- UINT32_MAX, variable_list);
- }
- return 0;
+ if (target)
+ target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
+ variable_list);
+ return variable_list.GetSize() - old_size;
}
Options *GetOptions() override { return &m_option_group; }
@@ -860,8 +866,9 @@ protected:
return false;
}
use_var_name = true;
- matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
- variable_list);
+ target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
+ variable_list);
+ matches = variable_list.GetSize();
} else {
Status error(Variable::GetValuesForVariableExpressionPath(
arg, m_exe_ctx.GetBestExecutionContextScope(),
@@ -936,7 +943,6 @@ protected:
}
} else {
SymbolContextList sc_list;
- const bool append = true;
// We have one or more compile unit or shlib
if (num_shlibs > 0) {
for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
@@ -949,8 +955,7 @@ protected:
if (num_compile_units > 0) {
for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
module_sp->FindCompileUnits(
- compile_units.GetFileSpecAtIndex(cu_idx), append,
- sc_list);
+ compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
} else {
SymbolContext sc;
sc.module_sp = module_sp;
@@ -968,7 +973,7 @@ protected:
// units files that were specified
for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
target->GetImages().FindCompileUnits(
- compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
+ compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
}
const uint32_t num_scs = sc_list.GetSize();
@@ -1024,7 +1029,7 @@ public:
: CommandObjectParsed(interpreter, "target modules search-paths add",
"Add new image search paths substitution pairs to "
"the current target.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandArgumentData old_prefix_arg;
CommandArgumentData new_prefix_arg;
@@ -1053,41 +1058,37 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target) {
- const size_t argc = command.GetArgumentCount();
- if (argc & 1) {
- result.AppendError("add requires an even number of arguments\n");
- result.SetStatus(eReturnStatusFailed);
- } else {
- for (size_t i = 0; i < argc; i += 2) {
- const char *from = command.GetArgumentAtIndex(i);
- const char *to = command.GetArgumentAtIndex(i + 1);
-
- if (from[0] && to[0]) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log) {
- log->Printf("target modules search path adding ImageSearchPath "
- "pair: '%s' -> '%s'",
- from, to);
- }
- bool last_pair = ((argc - i) == 2);
- target->GetImageSearchPathList().Append(
- ConstString(from), ConstString(to),
- last_pair); // Notify if this is the last pair
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- if (from[0])
- result.AppendError("<path-prefix> can't be empty\n");
- else
- result.AppendError("<new-path-prefix> can't be empty\n");
- result.SetStatus(eReturnStatusFailed);
+ Target *target = &GetSelectedTarget();
+ const size_t argc = command.GetArgumentCount();
+ if (argc & 1) {
+ result.AppendError("add requires an even number of arguments\n");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ for (size_t i = 0; i < argc; i += 2) {
+ const char *from = command.GetArgumentAtIndex(i);
+ const char *to = command.GetArgumentAtIndex(i + 1);
+
+ if (from[0] && to[0]) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log) {
+ LLDB_LOGF(log,
+ "target modules search path adding ImageSearchPath "
+ "pair: '%s' -> '%s'",
+ from, to);
}
+ bool last_pair = ((argc - i) == 2);
+ target->GetImageSearchPathList().Append(
+ ConstString(from), ConstString(to),
+ last_pair); // Notify if this is the last pair
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (from[0])
+ result.AppendError("<path-prefix> can't be empty\n");
+ else
+ result.AppendError("<new-path-prefix> can't be empty\n");
+ result.SetStatus(eReturnStatusFailed);
}
}
- } else {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
@@ -1101,21 +1102,17 @@ public:
: CommandObjectParsed(interpreter, "target modules search-paths clear",
"Clear all current image search path substitution "
"pairs from the current target.",
- "target modules search-paths clear") {}
+ "target modules search-paths clear",
+ eCommandRequiresTarget) {}
~CommandObjectTargetModulesSearchPathsClear() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target) {
- bool notify = true;
- target->GetImageSearchPathList().Clear(notify);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
- }
+ Target *target = &GetSelectedTarget();
+ bool notify = true;
+ target->GetImageSearchPathList().Clear(notify);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
};
@@ -1128,7 +1125,7 @@ public:
: CommandObjectParsed(interpreter, "target modules search-paths insert",
"Insert a new image search path substitution pair "
"into the current target at the specified index.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
CommandArgumentData index_arg;
@@ -1168,55 +1165,49 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target) {
- size_t argc = command.GetArgumentCount();
- // check for at least 3 arguments and an odd number of parameters
- if (argc >= 3 && argc & 1) {
- bool success = false;
+ Target *target = &GetSelectedTarget();
+ size_t argc = command.GetArgumentCount();
+ // check for at least 3 arguments and an odd number of parameters
+ if (argc >= 3 && argc & 1) {
+ bool success = false;
- uint32_t insert_idx = StringConvert::ToUInt32(
- command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
+ uint32_t insert_idx = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
- if (!success) {
- result.AppendErrorWithFormat(
- "<index> parameter is not an integer: '%s'.\n",
- command.GetArgumentAtIndex(0));
- result.SetStatus(eReturnStatusFailed);
- return result.Succeeded();
- }
+ if (!success) {
+ result.AppendErrorWithFormat(
+ "<index> parameter is not an integer: '%s'.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
- // shift off the index
- command.Shift();
- argc = command.GetArgumentCount();
+ // shift off the index
+ command.Shift();
+ argc = command.GetArgumentCount();
- for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
- const char *from = command.GetArgumentAtIndex(i);
- const char *to = command.GetArgumentAtIndex(i + 1);
+ for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
+ const char *from = command.GetArgumentAtIndex(i);
+ const char *to = command.GetArgumentAtIndex(i + 1);
- if (from[0] && to[0]) {
- bool last_pair = ((argc - i) == 2);
- target->GetImageSearchPathList().Insert(
- ConstString(from), ConstString(to), insert_idx, last_pair);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- if (from[0])
- result.AppendError("<path-prefix> can't be empty\n");
- else
- result.AppendError("<new-path-prefix> can't be empty\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (from[0] && to[0]) {
+ bool last_pair = ((argc - i) == 2);
+ target->GetImageSearchPathList().Insert(
+ ConstString(from), ConstString(to), insert_idx, last_pair);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (from[0])
+ result.AppendError("<path-prefix> can't be empty\n");
+ else
+ result.AppendError("<new-path-prefix> can't be empty\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- } else {
- result.AppendError("insert requires at least three arguments\n");
- result.SetStatus(eReturnStatusFailed);
- return result.Succeeded();
}
-
} else {
- result.AppendError("invalid target\n");
+ result.AppendError("insert requires at least three arguments\n");
result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
}
return result.Succeeded();
}
@@ -1230,26 +1221,22 @@ public:
: CommandObjectParsed(interpreter, "target modules search-paths list",
"List all current image search path substitution "
"pairs in the current target.",
- "target modules search-paths list") {}
+ "target modules search-paths list",
+ eCommandRequiresTarget) {}
~CommandObjectTargetModulesSearchPathsList() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target) {
- if (command.GetArgumentCount() != 0) {
- result.AppendError("list takes no arguments\n");
- result.SetStatus(eReturnStatusFailed);
- return result.Succeeded();
- }
-
- target->GetImageSearchPathList().Dump(&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendError("invalid target\n");
+ Target *target = &GetSelectedTarget();
+ if (command.GetArgumentCount() != 0) {
+ result.AppendError("list takes no arguments\n");
result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
}
+
+ target->GetImageSearchPathList().Dump(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
@@ -1262,7 +1249,7 @@ public:
: CommandObjectParsed(
interpreter, "target modules search-paths query",
"Transform a path using the first applicable image search path.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandArgumentData path_arg;
@@ -1282,26 +1269,21 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target) {
- if (command.GetArgumentCount() != 1) {
- result.AppendError("query requires one argument\n");
- result.SetStatus(eReturnStatusFailed);
- return result.Succeeded();
- }
-
- ConstString orig(command.GetArgumentAtIndex(0));
- ConstString transformed;
- if (target->GetImageSearchPathList().RemapPath(orig, transformed))
- result.GetOutputStream().Printf("%s\n", transformed.GetCString());
- else
- result.GetOutputStream().Printf("%s\n", orig.GetCString());
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendError("invalid target\n");
+ Target *target = &GetSelectedTarget();
+ if (command.GetArgumentCount() != 1) {
+ result.AppendError("query requires one argument\n");
result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
}
+
+ ConstString orig(command.GetArgumentAtIndex(0));
+ ConstString transformed;
+ if (target->GetImageSearchPathList().RemapPath(orig, transformed))
+ result.GetOutputStream().Printf("%s\n", transformed.GetCString());
+ else
+ result.GetOutputStream().Printf("%s\n", orig.GetCString());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
@@ -1439,15 +1421,11 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
Module *module, SortOrder sort_order) {
- if (module) {
- SymbolVendor *sym_vendor = module->GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
- sort_order);
- }
- }
+ if (!module)
+ return;
+ if (Symtab *symtab = module->GetSymtab())
+ symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
+ sort_order);
}
static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
@@ -1467,11 +1445,10 @@ static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
}
}
-static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
+static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
if (module) {
- SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
- if (symbol_vendor) {
- symbol_vendor->Dump(&strm);
+ if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
+ symbol_file->Dump(strm);
return true;
}
}
@@ -1553,47 +1530,44 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
Stream &strm, Module *module,
const char *name, bool name_is_regex,
bool verbose) {
- if (module) {
- SymbolContext sc;
+ if (!module)
+ return 0;
- SymbolVendor *sym_vendor = module->GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab) {
- std::vector<uint32_t> match_indexes;
- ConstString symbol_name(name);
- uint32_t num_matches = 0;
- if (name_is_regex) {
- RegularExpression name_regexp(symbol_name.GetStringRef());
- num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
- name_regexp, eSymbolTypeAny, match_indexes);
- } else {
- num_matches =
- symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
- }
+ Symtab *symtab = module->GetSymtab();
+ if (!symtab)
+ return 0;
- if (num_matches > 0) {
- strm.Indent();
- strm.Printf("%u symbols match %s'%s' in ", num_matches,
- name_is_regex ? "the regular expression " : "", name);
- DumpFullpath(strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- strm.IndentMore();
- for (uint32_t i = 0; i < num_matches; ++i) {
- Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
- if (symbol && symbol->ValueIsAddress()) {
- DumpAddress(interpreter.GetExecutionContext()
- .GetBestExecutionContextScope(),
- symbol->GetAddressRef(), verbose, strm);
- }
- }
- strm.IndentLess();
- return num_matches;
- }
+ SymbolContext sc;
+ std::vector<uint32_t> match_indexes;
+ ConstString symbol_name(name);
+ uint32_t num_matches = 0;
+ if (name_is_regex) {
+ RegularExpression name_regexp(symbol_name.GetStringRef());
+ num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
+ name_regexp, eSymbolTypeAny, match_indexes);
+ } else {
+ num_matches =
+ symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
+ }
+
+ if (num_matches > 0) {
+ strm.Indent();
+ strm.Printf("%u symbols match %s'%s' in ", num_matches,
+ name_is_regex ? "the regular expression " : "", name);
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ strm.IndentMore();
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
+ if (symbol && symbol->ValueIsAddress()) {
+ DumpAddress(
+ interpreter.GetExecutionContext().GetBestExecutionContextScope(),
+ symbol->GetAddressRef(), verbose, strm);
}
}
+ strm.IndentLess();
}
- return 0;
+ return num_matches;
}
static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
@@ -1623,19 +1597,17 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
bool verbose) {
if (module && name && name[0]) {
SymbolContextList sc_list;
- const bool append = true;
size_t num_matches = 0;
if (name_is_regex) {
RegularExpression function_name_regex((llvm::StringRef(name)));
- num_matches = module->FindFunctions(function_name_regex, include_symbols,
- include_inlines, append, sc_list);
+ module->FindFunctions(function_name_regex, include_symbols,
+ include_inlines, sc_list);
} else {
ConstString function_name(name);
- num_matches = module->FindFunctions(
- function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
- include_inlines, append, sc_list);
+ module->FindFunctions(function_name, nullptr, eFunctionNameTypeAuto,
+ include_symbols, include_inlines, sc_list);
}
-
+ num_matches = sc_list.GetSize();
if (num_matches) {
strm.Indent();
strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
@@ -1654,75 +1626,30 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
Module *module, const char *name_cstr,
bool name_is_regex) {
+ TypeList type_list;
if (module && name_cstr && name_cstr[0]) {
- TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
size_t num_matches = 0;
bool name_is_fully_qualified = false;
ConstString name(name_cstr);
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- num_matches =
- module->FindTypes(name, name_is_fully_qualified, max_num_matches,
- searched_symbol_files, type_list);
+ module->FindTypes(name, name_is_fully_qualified, max_num_matches,
+ searched_symbol_files, type_list);
- if (num_matches) {
- strm.Indent();
- strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
- num_matches > 1 ? "es" : "");
- DumpFullpath(strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- for (TypeSP type_sp : type_list.Types()) {
- if (type_sp) {
- // Resolve the clang type so that any forward references to types
- // that haven't yet been parsed will get parsed.
- type_sp->GetFullCompilerType();
- type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
- // Print all typedef chains
- TypeSP typedef_type_sp(type_sp);
- TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
- while (typedefed_type_sp) {
- strm.EOL();
- strm.Printf(" typedef '%s': ",
- typedef_type_sp->GetName().GetCString());
- typedefed_type_sp->GetFullCompilerType();
- typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
- true);
- typedef_type_sp = typedefed_type_sp;
- typedefed_type_sp = typedef_type_sp->GetTypedefType();
- }
- }
- strm.EOL();
- }
- }
- return num_matches;
- }
- return 0;
-}
-
-static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
- Module &module, const char *name_cstr,
- bool name_is_regex) {
- TypeList type_list;
- const uint32_t max_num_matches = UINT32_MAX;
- size_t num_matches = 1;
- bool name_is_fully_qualified = false;
+ if (type_list.Empty())
+ return 0;
- ConstString name(name_cstr);
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches,
- searched_symbol_files, type_list);
-
- if (num_matches) {
strm.Indent();
- strm.PutCString("Best match found in ");
- DumpFullpath(strm, &module.GetFileSpec(), 0);
+ strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
+ num_matches > 1 ? "es" : "");
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
-
- TypeSP type_sp(type_list.GetTypeAtIndex(0));
- if (type_sp) {
- // Resolve the clang type so that any forward references to types that
- // haven't yet been parsed will get parsed.
+ for (TypeSP type_sp : type_list.Types()) {
+ if (!type_sp)
+ continue;
+ // Resolve the clang type so that any forward references to types
+ // that haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
// Print all typedef chains
@@ -1740,7 +1667,50 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
}
strm.EOL();
}
- return num_matches;
+ return type_list.GetSize();
+}
+
+static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
+ Module &module, const char *name_cstr,
+ bool name_is_regex) {
+ TypeList type_list;
+ const uint32_t max_num_matches = UINT32_MAX;
+ bool name_is_fully_qualified = false;
+
+ ConstString name(name_cstr);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module.FindTypes(name, name_is_fully_qualified, max_num_matches,
+ searched_symbol_files, type_list);
+
+ if (type_list.Empty())
+ return 0;
+
+ strm.Indent();
+ strm.PutCString("Best match found in ");
+ DumpFullpath(strm, &module.GetFileSpec(), 0);
+ strm.PutCString(":\n");
+
+ TypeSP type_sp(type_list.GetTypeAtIndex(0));
+ if (type_sp) {
+ // Resolve the clang type so that any forward references to types that
+ // haven't yet been parsed will get parsed.
+ type_sp->GetFullCompilerType();
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ // Print all typedef chains
+ TypeSP typedef_type_sp(type_sp);
+ TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
+ while (typedefed_type_sp) {
+ strm.EOL();
+ strm.Printf(" typedef '%s': ",
+ typedef_type_sp->GetName().GetCString());
+ typedefed_type_sp->GetFullCompilerType();
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedef_type_sp = typedefed_type_sp;
+ typedefed_type_sp = typedef_type_sp->GetTypedefType();
+ }
+ }
+ strm.EOL();
+ return type_list.GetSize();
}
static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
@@ -1797,8 +1767,8 @@ static size_t FindModulesByName(Target *target, const char *module_name,
}
} else {
if (target) {
- const size_t num_matches =
- target->GetImages().FindModules(module_spec, module_list);
+ target->GetImages().FindModules(module_spec, module_list);
+ const size_t num_matches = module_list.GetSize();
// Not found in our module list for our target, check the main shared
// module list in case it is a extra file used somewhere else
@@ -1825,8 +1795,9 @@ public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
const char *name,
const char *help,
- const char *syntax)
- : CommandObjectParsed(interpreter, name, help, syntax) {
+ const char *syntax,
+ uint32_t flags = 0)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {
CommandArgumentEntry arg;
CommandArgumentData file_arg;
@@ -1844,13 +1815,12 @@ public:
~CommandObjectTargetModulesModuleAutoComplete() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
nullptr);
- return request.GetNumberOfMatches();
}
};
@@ -1883,13 +1853,12 @@ public:
~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
};
@@ -1902,19 +1871,13 @@ public:
: CommandObjectTargetModulesModuleAutoComplete(
interpreter, "target modules dump objfile",
"Dump the object file headers from one or more target modules.",
- nullptr) {}
+ nullptr, eCommandRequiresTarget) {}
~CommandObjectTargetModulesDumpObjfile() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
result.GetOutputStream().SetAddressByteSize(addr_byte_size);
@@ -1961,15 +1924,25 @@ protected:
#pragma mark CommandObjectTargetModulesDumpSymtab
static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
- {eSortOrderNone, "none",
- "No sorting, use the original symbol table order."},
- {eSortOrderByAddress, "address", "Sort output by symbol address."},
- {eSortOrderByName, "name", "Sort output by symbol name."} };
+ {
+ eSortOrderNone,
+ "none",
+ "No sorting, use the original symbol table order.",
+ },
+ {
+ eSortOrderByAddress,
+ "address",
+ "Sort output by symbol address.",
+ },
+ {
+ eSortOrderByName,
+ "name",
+ "Sort output by symbol name.",
+ },
+};
-static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = {
#define LLDB_OPTIONS_target_modules_dump_symtab
#include "CommandOptions.inc"
-};
class CommandObjectTargetModulesDumpSymtab
: public CommandObjectTargetModulesModuleAutoComplete {
@@ -1977,7 +1950,8 @@ public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
: CommandObjectTargetModulesModuleAutoComplete(
interpreter, "target modules dump symtab",
- "Dump the symbol table from one or more target modules.", nullptr),
+ "Dump the symbol table from one or more target modules.", nullptr,
+ eCommandRequiresTarget),
m_options() {}
~CommandObjectTargetModulesDumpSymtab() override = default;
@@ -2003,9 +1977,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -2023,82 +1995,75 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- uint32_t num_dumped = 0;
+ Target *target = &GetSelectedTarget();
+ uint32_t num_dumped = 0;
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- if (command.GetArgumentCount() == 0) {
- // Dump all sections for all modules images
- std::lock_guard<std::recursive_mutex> guard(
- target->GetImages().GetMutex());
- const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
- if (num_dumped > 0) {
- result.GetOutputStream().EOL();
- result.GetOutputStream().EOL();
- }
- if (m_interpreter.WasInterrupted())
- break;
- num_dumped++;
- DumpModuleSymtab(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
- m_options.m_sort_order);
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ std::lock_guard<std::recursive_mutex> guard(
+ target->GetImages().GetMutex());
+ const size_t num_modules = target->GetImages().GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (num_dumped > 0) {
+ result.GetOutputStream().EOL();
+ result.GetOutputStream().EOL();
}
- } else {
- result.AppendError("the target has no associated executable images");
- result.SetStatus(eReturnStatusFailed);
- return false;
+ if (m_interpreter.WasInterrupted())
+ break;
+ num_dumped++;
+ DumpModuleSymtab(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
+ m_options.m_sort_order);
}
} else {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0;
- (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
- ++arg_idx) {
- ModuleList module_list;
- const size_t num_matches =
- FindModulesByName(target, arg_cstr, module_list, true);
- if (num_matches > 0) {
- for (size_t i = 0; i < num_matches; ++i) {
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module) {
- if (num_dumped > 0) {
- result.GetOutputStream().EOL();
- result.GetOutputStream().EOL();
- }
- if (m_interpreter.WasInterrupted())
- break;
- num_dumped++;
- DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
- module, m_options.m_sort_order);
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ if (num_dumped > 0) {
+ result.GetOutputStream().EOL();
+ result.GetOutputStream().EOL();
}
+ if (m_interpreter.WasInterrupted())
+ break;
+ num_dumped++;
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module,
+ m_options.m_sort_order);
}
- } else
- result.AppendWarningWithFormat(
- "Unable to find an image that matches '%s'.\n", arg_cstr);
- }
+ }
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
+ }
- if (num_dumped > 0)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else {
- result.AppendError("no matching executable images found");
- result.SetStatus(eReturnStatusFailed);
- }
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
@@ -2118,82 +2083,75 @@ public:
interpreter, "target modules dump sections",
"Dump the sections from one or more target modules.",
//"target modules dump sections [<file1> ...]")
- nullptr) {}
+ nullptr, eCommandRequiresTarget) {}
~CommandObjectTargetModulesDumpSections() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- uint32_t num_dumped = 0;
+ Target *target = &GetSelectedTarget();
+ uint32_t num_dumped = 0;
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- if (command.GetArgumentCount() == 0) {
- // Dump all sections for all modules images
- const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping sections for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ const size_t num_modules = target->GetImages().GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping sections for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ num_dumped++;
+ DumpModuleSections(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndex(image_idx));
+ }
+ } else {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
if (m_interpreter.WasInterrupted())
break;
- num_dumped++;
- DumpModuleSections(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndex(image_idx));
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ num_dumped++;
+ DumpModuleSections(m_interpreter, result.GetOutputStream(),
+ module);
+ }
}
} else {
- result.AppendError("the target has no associated executable images");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0;
- (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
- ++arg_idx) {
- ModuleList module_list;
- const size_t num_matches =
- FindModulesByName(target, arg_cstr, module_list, true);
- if (num_matches > 0) {
- for (size_t i = 0; i < num_matches; ++i) {
- if (m_interpreter.WasInterrupted())
- break;
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module) {
- num_dumped++;
- DumpModuleSections(m_interpreter, result.GetOutputStream(),
- module);
- }
- }
- } else {
- // Check the global list
- std::lock_guard<std::recursive_mutex> guard(
- Module::GetAllocationModuleCollectionMutex());
+ // Check the global list
+ std::lock_guard<std::recursive_mutex> guard(
+ Module::GetAllocationModuleCollectionMutex());
- result.AppendWarningWithFormat(
- "Unable to find an image that matches '%s'.\n", arg_cstr);
- }
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
}
+ }
- if (num_dumped > 0)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else {
- result.AppendError("no matching executable images found");
- result.SetStatus(eReturnStatusFailed);
- }
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
@@ -2211,19 +2169,13 @@ public:
interpreter, "target modules dump ast",
"Dump the clang ast for a given module's symbol file.",
//"target modules dump ast [<file1> ...]")
- nullptr) {}
+ nullptr, eCommandRequiresTarget) {}
~CommandObjectTargetModulesDumpClangAST() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
const size_t num_modules = target->GetImages().GetSize();
if (num_modules == 0) {
@@ -2241,8 +2193,8 @@ protected:
if (m_interpreter.WasInterrupted())
break;
Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
- SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
- sf->DumpClangAST(result.GetOutputStream());
+ if (SymbolFile *sf = m->GetSymbolFile())
+ sf->DumpClangAST(result.GetOutputStream());
}
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
@@ -2267,8 +2219,8 @@ protected:
if (m_interpreter.WasInterrupted())
break;
Module *m = module_list.GetModulePointerAtIndex(i);
- SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
- sf->DumpClangAST(result.GetOutputStream());
+ if (SymbolFile *sf = m->GetSymbolFile())
+ sf->DumpClangAST(result.GetOutputStream());
}
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2288,84 +2240,79 @@ public:
interpreter, "target modules dump symfile",
"Dump the debug symbol file for one or more target modules.",
//"target modules dump symfile [<file1> ...]")
- nullptr) {}
+ nullptr, eCommandRequiresTarget) {}
~CommandObjectTargetModulesDumpSymfile() override = default;
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- uint32_t num_dumped = 0;
+ Target *target = &GetSelectedTarget();
+ uint32_t num_dumped = 0;
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- if (command.GetArgumentCount() == 0) {
- // Dump all sections for all modules images
- const ModuleList &target_modules = target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
- if (m_interpreter.WasInterrupted())
- break;
- if (DumpModuleSymbolVendor(
- result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
- num_dumped++;
- }
- } else {
- result.AppendError("the target has no associated executable images");
- result.SetStatus(eReturnStatusFailed);
- return false;
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ const ModuleList &target_modules = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ if (DumpModuleSymbolFile(
+ result.GetOutputStream(),
+ target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
+ num_dumped++;
}
} else {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0;
- (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
- ++arg_idx) {
- ModuleList module_list;
- const size_t num_matches =
- FindModulesByName(target, arg_cstr, module_list, true);
- if (num_matches > 0) {
- for (size_t i = 0; i < num_matches; ++i) {
- if (m_interpreter.WasInterrupted())
- break;
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module) {
- if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
- num_dumped++;
- }
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ if (DumpModuleSymbolFile(result.GetOutputStream(), module))
+ num_dumped++;
}
- } else
- result.AppendWarningWithFormat(
- "Unable to find an image that matches '%s'.\n", arg_cstr);
- }
+ }
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
+ }
- if (num_dumped > 0)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else {
- result.AppendError("no matching executable images found");
- result.SetStatus(eReturnStatusFailed);
- }
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
}
};
#pragma mark CommandObjectTargetModulesDumpLineTable
+#define LLDB_OPTIONS_target_modules_dump
+#include "CommandOptions.inc"
// Image debug line table dumping command
@@ -2454,19 +2401,7 @@ protected:
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- static constexpr OptionDefinition g_options[] = {
- {LLDB_OPT_SET_ALL,
- false,
- "verbose",
- 'v',
- OptionParser::eNoArgument,
- nullptr,
- {},
- 0,
- eArgTypeNone,
- "Enable verbose dump."},
- };
- return llvm::makeArrayRef(g_options);
+ return llvm::makeArrayRef(g_target_modules_dump_options);
}
bool m_verbose;
@@ -2518,10 +2453,11 @@ public:
CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "target modules add",
"Add a new module to the current target's modules.",
- "target modules add [<module>]"),
- m_option_group(),
- m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
- eArgTypeFilename, "Fullpath to a stand alone debug "
+ "target modules add [<module>]",
+ eCommandRequiresTarget),
+ m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
+ 0, eArgTypeFilename,
+ "Fullpath to a stand alone debug "
"symbols file for when debug symbols "
"are not in the executable.") {
m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
@@ -2534,13 +2470,12 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
protected:
@@ -2549,125 +2484,117 @@ protected:
OptionGroupFile m_symbol_file;
bool DoExecute(Args &args, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- bool flush = false;
+ Target *target = &GetSelectedTarget();
+ bool flush = false;
- const size_t argc = args.GetArgumentCount();
- if (argc == 0) {
- if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
- // We are given a UUID only, go locate the file
- ModuleSpec module_spec;
- module_spec.GetUUID() =
- m_uuid_option_group.GetOptionValue().GetCurrentValue();
- if (m_symbol_file.GetOptionValue().OptionWasSet())
- module_spec.GetSymbolFileSpec() =
- m_symbol_file.GetOptionValue().GetCurrentValue();
- if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
- ModuleSP module_sp(target->GetOrCreateModule(module_spec,
- true /* notify */));
- if (module_sp) {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- } else {
- StreamString strm;
- module_spec.GetUUID().Dump(&strm);
- if (module_spec.GetFileSpec()) {
- if (module_spec.GetSymbolFileSpec()) {
- result.AppendErrorWithFormat(
- "Unable to create the executable or symbol file with "
- "UUID %s with path %s and symbol file %s",
- strm.GetData(),
- module_spec.GetFileSpec().GetPath().c_str(),
- module_spec.GetSymbolFileSpec().GetPath().c_str());
- } else {
- result.AppendErrorWithFormat(
- "Unable to create the executable or symbol file with "
- "UUID %s with path %s",
- strm.GetData(),
- module_spec.GetFileSpec().GetPath().c_str());
- }
- } else {
- result.AppendErrorWithFormat("Unable to create the executable "
- "or symbol file with UUID %s",
- strm.GetData());
- }
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0) {
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+ // We are given a UUID only, go locate the file
+ ModuleSpec module_spec;
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() =
+ m_symbol_file.GetOptionValue().GetCurrentValue();
+ if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
+ ModuleSP module_sp(
+ target->GetOrCreateModule(module_spec, true /* notify */));
+ if (module_sp) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
} else {
StreamString strm;
module_spec.GetUUID().Dump(&strm);
- result.AppendErrorWithFormat(
- "Unable to locate the executable or symbol file with UUID %s",
- strm.GetData());
+ if (module_spec.GetFileSpec()) {
+ if (module_spec.GetSymbolFileSpec()) {
+ result.AppendErrorWithFormat(
+ "Unable to create the executable or symbol file with "
+ "UUID %s with path %s and symbol file %s",
+ strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
+ module_spec.GetSymbolFileSpec().GetPath().c_str());
+ } else {
+ result.AppendErrorWithFormat(
+ "Unable to create the executable or symbol file with "
+ "UUID %s with path %s",
+ strm.GetData(),
+ module_spec.GetFileSpec().GetPath().c_str());
+ }
+ } else {
+ result.AppendErrorWithFormat("Unable to create the executable "
+ "or symbol file with UUID %s",
+ strm.GetData());
+ }
result.SetStatus(eReturnStatusFailed);
return false;
}
} else {
- result.AppendError(
- "one or more executable image paths must be specified");
+ StreamString strm;
+ module_spec.GetUUID().Dump(&strm);
+ result.AppendErrorWithFormat(
+ "Unable to locate the executable or symbol file with UUID %s",
+ strm.GetData());
result.SetStatus(eReturnStatusFailed);
return false;
}
} else {
- for (auto &entry : args.entries()) {
- if (entry.ref.empty())
- continue;
+ result.AppendError(
+ "one or more executable image paths must be specified");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ for (auto &entry : args.entries()) {
+ if (entry.ref().empty())
+ continue;
- FileSpec file_spec(entry.ref);
- if (FileSystem::Instance().Exists(file_spec)) {
- ModuleSpec module_spec(file_spec);
- if (m_uuid_option_group.GetOptionValue().OptionWasSet())
- module_spec.GetUUID() =
- m_uuid_option_group.GetOptionValue().GetCurrentValue();
- if (m_symbol_file.GetOptionValue().OptionWasSet())
- module_spec.GetSymbolFileSpec() =
- m_symbol_file.GetOptionValue().GetCurrentValue();
- if (!module_spec.GetArchitecture().IsValid())
- module_spec.GetArchitecture() = target->GetArchitecture();
- Status error;
- ModuleSP module_sp(target->GetOrCreateModule(module_spec,
- true /* notify */, &error));
- if (!module_sp) {
- const char *error_cstr = error.AsCString();
- if (error_cstr)
- result.AppendError(error_cstr);
- else
- result.AppendErrorWithFormat("unsupported module: %s",
- entry.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- flush = true;
- }
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- std::string resolved_path = file_spec.GetPath();
+ FileSpec file_spec(entry.ref());
+ if (FileSystem::Instance().Exists(file_spec)) {
+ ModuleSpec module_spec(file_spec);
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet())
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() =
+ m_symbol_file.GetOptionValue().GetCurrentValue();
+ if (!module_spec.GetArchitecture().IsValid())
+ module_spec.GetArchitecture() = target->GetArchitecture();
+ Status error;
+ ModuleSP module_sp(target->GetOrCreateModule(
+ module_spec, true /* notify */, &error));
+ if (!module_sp) {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr)
+ result.AppendError(error_cstr);
+ else
+ result.AppendErrorWithFormat("unsupported module: %s",
+ entry.c_str());
result.SetStatus(eReturnStatusFailed);
- if (resolved_path != entry.ref) {
- result.AppendErrorWithFormat(
- "invalid module path '%s' with resolved path '%s'\n",
- entry.ref.str().c_str(), resolved_path.c_str());
- break;
- }
- result.AppendErrorWithFormat("invalid module path '%s'\n",
- entry.c_str());
+ return false;
+ } else {
+ flush = true;
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ std::string resolved_path = file_spec.GetPath();
+ result.SetStatus(eReturnStatusFailed);
+ if (resolved_path != entry.ref()) {
+ result.AppendErrorWithFormat(
+ "invalid module path '%s' with resolved path '%s'\n",
+ entry.ref().str().c_str(), resolved_path.c_str());
break;
}
+ result.AppendErrorWithFormat("invalid module path '%s'\n",
+ entry.c_str());
+ break;
}
}
+ }
- if (flush) {
- ProcessSP process = target->GetProcessSP();
- if (process)
- process->Flush();
- }
+ if (flush) {
+ ProcessSP process = target->GetProcessSP();
+ if (process)
+ process->Flush();
}
return result.Succeeded();
@@ -2679,11 +2606,12 @@ class CommandObjectTargetModulesLoad
public:
CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
: CommandObjectTargetModulesModuleAutoComplete(
- interpreter, "target modules load", "Set the load addresses for "
- "one or more sections in a "
- "target module.",
+ interpreter, "target modules load",
+ "Set the load addresses for one or more sections in a target "
+ "module.",
"target modules load [--file <module> --uuid <uuid>] <sect-name> "
- "<address> [<sect-name> <address> ....]"),
+ "<address> [<sect-name> <address> ....]",
+ eCommandRequiresTarget),
m_option_group(),
m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
"Fullpath or basename for module to load.", ""),
@@ -2712,249 +2640,241 @@ public:
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
const bool load = m_load_option.GetOptionValue().GetCurrentValue();
const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- const size_t argc = args.GetArgumentCount();
- ModuleSpec module_spec;
- bool search_using_module_spec = false;
-
- // Allow "load" option to work without --file or --uuid option.
- if (load) {
- if (!m_file_option.GetOptionValue().OptionWasSet() &&
- !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
- ModuleList &module_list = target->GetImages();
- if (module_list.GetSize() == 1) {
- search_using_module_spec = true;
- module_spec.GetFileSpec() =
- module_list.GetModuleAtIndex(0)->GetFileSpec();
- }
- }
- }
- if (m_file_option.GetOptionValue().OptionWasSet()) {
- search_using_module_spec = true;
- const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
- const bool use_global_module_list = true;
- ModuleList module_list;
- const size_t num_matches = FindModulesByName(
- target, arg_cstr, module_list, use_global_module_list);
- if (num_matches == 1) {
+ const size_t argc = args.GetArgumentCount();
+ ModuleSpec module_spec;
+ bool search_using_module_spec = false;
+
+ // Allow "load" option to work without --file or --uuid option.
+ if (load) {
+ if (!m_file_option.GetOptionValue().OptionWasSet() &&
+ !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+ ModuleList &module_list = target->GetImages();
+ if (module_list.GetSize() == 1) {
+ search_using_module_spec = true;
module_spec.GetFileSpec() =
module_list.GetModuleAtIndex(0)->GetFileSpec();
- } else if (num_matches > 1) {
- search_using_module_spec = false;
- result.AppendErrorWithFormat(
- "more than 1 module matched by name '%s'\n", arg_cstr);
- result.SetStatus(eReturnStatusFailed);
- } else {
- search_using_module_spec = false;
- result.AppendErrorWithFormat("no object file for module '%s'\n",
- arg_cstr);
- result.SetStatus(eReturnStatusFailed);
}
}
+ }
- if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
- search_using_module_spec = true;
- module_spec.GetUUID() =
- m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ if (m_file_option.GetOptionValue().OptionWasSet()) {
+ search_using_module_spec = true;
+ const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
+ const bool use_global_module_list = true;
+ ModuleList module_list;
+ const size_t num_matches = FindModulesByName(
+ target, arg_cstr, module_list, use_global_module_list);
+ if (num_matches == 1) {
+ module_spec.GetFileSpec() =
+ module_list.GetModuleAtIndex(0)->GetFileSpec();
+ } else if (num_matches > 1) {
+ search_using_module_spec = false;
+ result.AppendErrorWithFormat(
+ "more than 1 module matched by name '%s'\n", arg_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ search_using_module_spec = false;
+ result.AppendErrorWithFormat("no object file for module '%s'\n",
+ arg_cstr);
+ result.SetStatus(eReturnStatusFailed);
}
+ }
- if (search_using_module_spec) {
- ModuleList matching_modules;
- const size_t num_matches =
- target->GetImages().FindModules(module_spec, matching_modules);
-
- char path[PATH_MAX];
- if (num_matches == 1) {
- Module *module = matching_modules.GetModulePointerAtIndex(0);
- if (module) {
- ObjectFile *objfile = module->GetObjectFile();
- if (objfile) {
- SectionList *section_list = module->GetSectionList();
- if (section_list) {
- bool changed = false;
- if (argc == 0) {
- if (m_slide_option.GetOptionValue().OptionWasSet()) {
- const addr_t slide =
- m_slide_option.GetOptionValue().GetCurrentValue();
- const bool slide_is_offset = true;
- module->SetLoadAddress(*target, slide, slide_is_offset,
- changed);
- } else {
- result.AppendError("one or more section name + load "
- "address pair must be specified");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+ search_using_module_spec = true;
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ }
+
+ if (search_using_module_spec) {
+ ModuleList matching_modules;
+ target->GetImages().FindModules(module_spec, matching_modules);
+ const size_t num_matches = matching_modules.GetSize();
+
+ char path[PATH_MAX];
+ if (num_matches == 1) {
+ Module *module = matching_modules.GetModulePointerAtIndex(0);
+ if (module) {
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile) {
+ SectionList *section_list = module->GetSectionList();
+ if (section_list) {
+ bool changed = false;
+ if (argc == 0) {
+ if (m_slide_option.GetOptionValue().OptionWasSet()) {
+ const addr_t slide =
+ m_slide_option.GetOptionValue().GetCurrentValue();
+ const bool slide_is_offset = true;
+ module->SetLoadAddress(*target, slide, slide_is_offset,
+ changed);
} else {
- if (m_slide_option.GetOptionValue().OptionWasSet()) {
- result.AppendError("The \"--slide <offset>\" option can't "
- "be used in conjunction with setting "
- "section load addresses.\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ result.AppendError("one or more section name + load "
+ "address pair must be specified");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ if (m_slide_option.GetOptionValue().OptionWasSet()) {
+ result.AppendError("The \"--slide <offset>\" option can't "
+ "be used in conjunction with setting "
+ "section load addresses.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- for (size_t i = 0; i < argc; i += 2) {
- const char *sect_name = args.GetArgumentAtIndex(i);
- const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
- if (sect_name && load_addr_cstr) {
- ConstString const_sect_name(sect_name);
- bool success = false;
- addr_t load_addr = StringConvert::ToUInt64(
- load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
- if (success) {
- SectionSP section_sp(
- section_list->FindSectionByName(const_sect_name));
- if (section_sp) {
- if (section_sp->IsThreadSpecific()) {
- result.AppendErrorWithFormat(
- "thread specific sections are not yet "
- "supported (section '%s')\n",
- sect_name);
- result.SetStatus(eReturnStatusFailed);
- break;
- } else {
- if (target->GetSectionLoadList()
- .SetSectionLoadAddress(section_sp,
- load_addr))
- changed = true;
- result.AppendMessageWithFormat(
- "section '%s' loaded at 0x%" PRIx64 "\n",
- sect_name, load_addr);
- }
- } else {
- result.AppendErrorWithFormat("no section found that "
- "matches the section "
- "name '%s'\n",
- sect_name);
+ for (size_t i = 0; i < argc; i += 2) {
+ const char *sect_name = args.GetArgumentAtIndex(i);
+ const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
+ if (sect_name && load_addr_cstr) {
+ ConstString const_sect_name(sect_name);
+ bool success = false;
+ addr_t load_addr = StringConvert::ToUInt64(
+ load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
+ if (success) {
+ SectionSP section_sp(
+ section_list->FindSectionByName(const_sect_name));
+ if (section_sp) {
+ if (section_sp->IsThreadSpecific()) {
+ result.AppendErrorWithFormat(
+ "thread specific sections are not yet "
+ "supported (section '%s')\n",
+ sect_name);
result.SetStatus(eReturnStatusFailed);
break;
+ } else {
+ if (target->GetSectionLoadList()
+ .SetSectionLoadAddress(section_sp, load_addr))
+ changed = true;
+ result.AppendMessageWithFormat(
+ "section '%s' loaded at 0x%" PRIx64 "\n",
+ sect_name, load_addr);
}
} else {
- result.AppendErrorWithFormat(
- "invalid load address string '%s'\n",
- load_addr_cstr);
+ result.AppendErrorWithFormat("no section found that "
+ "matches the section "
+ "name '%s'\n",
+ sect_name);
result.SetStatus(eReturnStatusFailed);
break;
}
} else {
- if (sect_name)
- result.AppendError("section names must be followed by "
- "a load address.\n");
- else
- result.AppendError("one or more section name + load "
- "address pair must be specified.\n");
+ result.AppendErrorWithFormat(
+ "invalid load address string '%s'\n", load_addr_cstr);
result.SetStatus(eReturnStatusFailed);
break;
}
+ } else {
+ if (sect_name)
+ result.AppendError("section names must be followed by "
+ "a load address.\n");
+ else
+ result.AppendError("one or more section name + load "
+ "address pair must be specified.\n");
+ result.SetStatus(eReturnStatusFailed);
+ break;
}
}
+ }
- if (changed) {
- target->ModulesDidLoad(matching_modules);
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process)
- process->Flush();
+ if (changed) {
+ target->ModulesDidLoad(matching_modules);
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
+ process->Flush();
+ }
+ if (load) {
+ ProcessSP process = target->CalculateProcess();
+ Address file_entry = objfile->GetEntryPointAddress();
+ if (!process) {
+ result.AppendError("No process");
+ return false;
}
- if (load) {
- ProcessSP process = target->CalculateProcess();
- Address file_entry = objfile->GetEntryPointAddress();
- if (!process) {
- result.AppendError("No process");
- return false;
- }
- if (set_pc && !file_entry.IsValid()) {
- result.AppendError("No entry address in object file");
- return false;
- }
- std::vector<ObjectFile::LoadableData> loadables(
- objfile->GetLoadableData(*target));
- if (loadables.size() == 0) {
- result.AppendError("No loadable sections");
- return false;
- }
- Status error = process->WriteObjectFile(std::move(loadables));
- if (error.Fail()) {
- result.AppendError(error.AsCString());
- return false;
- }
- if (set_pc) {
- ThreadList &thread_list = process->GetThreadList();
- RegisterContextSP reg_context(
- thread_list.GetSelectedThread()->GetRegisterContext());
- addr_t file_entry_addr = file_entry.GetLoadAddress(target);
- if (!reg_context->SetPC(file_entry_addr)) {
- result.AppendErrorWithFormat("failed to set PC value to "
- "0x%" PRIx64 "\n",
- file_entry_addr);
- result.SetStatus(eReturnStatusFailed);
- }
+ if (set_pc && !file_entry.IsValid()) {
+ result.AppendError("No entry address in object file");
+ return false;
+ }
+ std::vector<ObjectFile::LoadableData> loadables(
+ objfile->GetLoadableData(*target));
+ if (loadables.size() == 0) {
+ result.AppendError("No loadable sections");
+ return false;
+ }
+ Status error = process->WriteObjectFile(std::move(loadables));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ return false;
+ }
+ if (set_pc) {
+ ThreadList &thread_list = process->GetThreadList();
+ RegisterContextSP reg_context(
+ thread_list.GetSelectedThread()->GetRegisterContext());
+ addr_t file_entry_addr = file_entry.GetLoadAddress(target);
+ if (!reg_context->SetPC(file_entry_addr)) {
+ result.AppendErrorWithFormat("failed to set PC value to "
+ "0x%" PRIx64 "\n",
+ file_entry_addr);
+ result.SetStatus(eReturnStatusFailed);
}
}
- } else {
- module->GetFileSpec().GetPath(path, sizeof(path));
- result.AppendErrorWithFormat(
- "no sections in object file '%s'\n", path);
- result.SetStatus(eReturnStatusFailed);
}
} else {
module->GetFileSpec().GetPath(path, sizeof(path));
- result.AppendErrorWithFormat("no object file for module '%s'\n",
+ result.AppendErrorWithFormat("no sections in object file '%s'\n",
path);
result.SetStatus(eReturnStatusFailed);
}
} else {
- FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
- if (module_spec_file) {
- module_spec_file->GetPath(path, sizeof(path));
- result.AppendErrorWithFormat("invalid module '%s'.\n", path);
- } else
- result.AppendError("no module spec");
+ module->GetFileSpec().GetPath(path, sizeof(path));
+ result.AppendErrorWithFormat("no object file for module '%s'\n",
+ path);
result.SetStatus(eReturnStatusFailed);
}
} else {
- std::string uuid_str;
+ FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
+ if (module_spec_file) {
+ module_spec_file->GetPath(path, sizeof(path));
+ result.AppendErrorWithFormat("invalid module '%s'.\n", path);
+ } else
+ result.AppendError("no module spec");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ std::string uuid_str;
- if (module_spec.GetFileSpec())
- module_spec.GetFileSpec().GetPath(path, sizeof(path));
- else
- path[0] = '\0';
+ if (module_spec.GetFileSpec())
+ module_spec.GetFileSpec().GetPath(path, sizeof(path));
+ else
+ path[0] = '\0';
- if (module_spec.GetUUIDPtr())
- uuid_str = module_spec.GetUUID().GetAsString();
- if (num_matches > 1) {
- result.AppendErrorWithFormat(
- "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
- path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
- for (size_t i = 0; i < num_matches; ++i) {
- if (matching_modules.GetModulePointerAtIndex(i)
- ->GetFileSpec()
- .GetPath(path, sizeof(path)))
- result.AppendMessageWithFormat("%s\n", path);
- }
- } else {
- result.AppendErrorWithFormat(
- "no modules were found that match%s%s%s%s.\n",
- path[0] ? " file=" : "", path,
- !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
+ if (module_spec.GetUUIDPtr())
+ uuid_str = module_spec.GetUUID().GetAsString();
+ if (num_matches > 1) {
+ result.AppendErrorWithFormat(
+ "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
+ path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
+ for (size_t i = 0; i < num_matches; ++i) {
+ if (matching_modules.GetModulePointerAtIndex(i)
+ ->GetFileSpec()
+ .GetPath(path, sizeof(path)))
+ result.AppendMessageWithFormat("%s\n", path);
}
- result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendErrorWithFormat(
+ "no modules were found that match%s%s%s%s.\n",
+ path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
+ uuid_str.c_str());
}
- } else {
- result.AppendError("either the \"--file <module>\" or the \"--uuid "
- "<uuid>\" option must be specified.\n");
result.SetStatus(eReturnStatusFailed);
- return false;
}
+ } else {
+ result.AppendError("either the \"--file <module>\" or the \"--uuid "
+ "<uuid>\" option must be specified.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
return result.Succeeded();
}
@@ -2968,26 +2888,8 @@ protected:
};
// List images with associated information
-
-static constexpr OptionDefinition g_target_modules_list_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
- { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." },
- { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." },
- { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image base address as a load address if debugging, a file address otherwise." },
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image load address offset from the base file address (the slide amount)." },
- { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." },
- { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
- { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
- { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
- { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
- { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
- { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
- { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
- { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." },
- { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
- // clang-format on
-};
+#define LLDB_OPTIONS_target_modules_list
+#include "CommandOptions.inc"
class CommandObjectTargetModulesList : public CommandObjectParsed {
public:
@@ -3282,9 +3184,9 @@ protected:
case 's':
case 'S': {
- const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
- if (symbol_vendor) {
- const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
+ if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
+ const FileSpec symfile_spec =
+ symbol_file->GetObjectFile()->GetFileSpec();
if (format_char == 'S') {
// Dump symbol file only if different from module file
if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
@@ -3332,13 +3234,8 @@ protected:
#pragma mark CommandObjectTargetModulesShowUnwind
// Lookup unwind information in images
-
-static constexpr OptionDefinition g_target_modules_show_unwind_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
- { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
- // clang-format on
-};
+#define LLDB_OPTIONS_target_modules_show_unwind
+#include "CommandOptions.inc"
class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
public:
@@ -3383,8 +3280,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -3453,7 +3349,7 @@ protected:
if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
ConstString function_name(m_options.m_str.c_str());
target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
- true, false, true, sc_list);
+ true, false, sc_list);
} else if (m_options.m_type == eLookupTypeAddress && target) {
Address addr;
if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
@@ -3546,6 +3442,25 @@ protected:
result.GetOutputStream().Printf("\n");
}
+ UnwindPlanSP of_unwind_sp =
+ func_unwinders_sp->GetObjectFileUnwindPlan(*target);
+ if (of_unwind_sp) {
+ result.GetOutputStream().Printf("object file UnwindPlan:\n");
+ of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP of_unwind_augmented_sp =
+ func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
+ *thread);
+ if (of_unwind_augmented_sp) {
+ result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
+ of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
UnwindPlanSP ehframe_sp =
func_unwinders_sp->GetEHFrameUnwindPlan(*target);
if (ehframe_sp) {
@@ -3643,24 +3558,8 @@ protected:
};
// Lookup information in images
-
-static constexpr OptionDefinition g_target_modules_lookup_options[] = {
- // clang-format off
- { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
- /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
- { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
- { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
- { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
- { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
- { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
- { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
- { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
- { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." },
- { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
- // clang-format on
-};
+#define LLDB_OPTIONS_target_modules_lookup
+#include "CommandOptions.inc"
class CommandObjectTargetModulesLookup : public CommandObjectParsed {
public:
@@ -3749,6 +3648,8 @@ public:
case 'r':
m_use_regex = true;
break;
+ default:
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -3935,91 +3836,82 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- bool syntax_error = false;
- uint32_t i;
- uint32_t num_successful_lookups = 0;
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- // Dump all sections for all modules images
-
- if (command.GetArgumentCount() == 0) {
- ModuleSP current_module;
+ Target *target = &GetSelectedTarget();
+ bool syntax_error = false;
+ uint32_t i;
+ uint32_t num_successful_lookups = 0;
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ // Dump all sections for all modules images
- // Where it is possible to look in the current symbol context first,
- // try that. If this search was successful and --all was not passed,
- // don't print anything else.
- if (LookupHere(m_interpreter, result, syntax_error)) {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- if (!m_options.m_print_all) {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
+ if (command.GetArgumentCount() == 0) {
+ ModuleSP current_module;
+
+ // Where it is possible to look in the current symbol context first,
+ // try that. If this search was successful and --all was not passed,
+ // don't print anything else.
+ if (LookupHere(m_interpreter, result, syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
+ if (!m_options.m_print_all) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
}
+ }
- // Dump all sections for all other modules
+ // Dump all sections for all other modules
- const ModuleList &target_modules = target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0) {
- for (i = 0; i < num_modules && !syntax_error; ++i) {
- Module *module_pointer =
- target_modules.GetModulePointerAtIndexUnlocked(i);
-
- if (module_pointer != current_module.get() &&
- LookupInModule(
- m_interpreter,
- target_modules.GetModulePointerAtIndexUnlocked(i), result,
- syntax_error)) {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- }
+ const ModuleList &target_modules = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0) {
+ for (i = 0; i < num_modules && !syntax_error; ++i) {
+ Module *module_pointer =
+ target_modules.GetModulePointerAtIndexUnlocked(i);
+
+ if (module_pointer != current_module.get() &&
+ LookupInModule(m_interpreter,
+ target_modules.GetModulePointerAtIndexUnlocked(i),
+ result, syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
}
- } else {
- result.AppendError("the target has no associated executable images");
- result.SetStatus(eReturnStatusFailed);
- return false;
}
} else {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
- !syntax_error;
- ++i) {
- ModuleList module_list;
- const size_t num_matches =
- FindModulesByName(target, arg_cstr, module_list, false);
- if (num_matches > 0) {
- for (size_t j = 0; j < num_matches; ++j) {
- Module *module = module_list.GetModulePointerAtIndex(j);
- if (module) {
- if (LookupInModule(m_interpreter, module, result,
- syntax_error)) {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- }
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
+ !syntax_error;
+ ++i) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, false);
+ if (num_matches > 0) {
+ for (size_t j = 0; j < num_matches; ++j) {
+ Module *module = module_list.GetModulePointerAtIndex(j);
+ if (module) {
+ if (LookupInModule(m_interpreter, module, result, syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
}
}
- } else
- result.AppendWarningWithFormat(
- "Unable to find an image that matches '%s'.\n", arg_cstr);
- }
+ }
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
-
- if (num_successful_lookups > 0)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
}
+
+ if (num_successful_lookups > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
}
@@ -4129,13 +4021,12 @@ public:
~CommandObjectTargetSymbolsAdd() override = default;
- int HandleArgumentCompletion(
- CompletionRequest &request,
- OptionElementVector &opt_element_vector) override {
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
request, nullptr);
- return request.GetNumberOfMatches();
}
Options *GetOptions() override { return &m_option_group; }
@@ -4173,8 +4064,9 @@ protected:
// It has a UUID, look for this UUID in the target modules
ModuleSpec symfile_uuid_module_spec;
symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
- num_matches = target->GetImages().FindModules(
- symfile_uuid_module_spec, matching_module_list);
+ target->GetImages().FindModules(symfile_uuid_module_spec,
+ matching_module_list);
+ num_matches = matching_module_list.GetSize();
}
}
@@ -4192,8 +4084,9 @@ protected:
ModuleSpec symfile_uuid_module_spec;
symfile_uuid_module_spec.GetUUID() =
symfile_module_spec.GetUUID();
- num_matches = target->GetImages().FindModules(
- symfile_uuid_module_spec, matching_module_list);
+ target->GetImages().FindModules(symfile_uuid_module_spec,
+ matching_module_list);
+ num_matches = matching_module_list.GetSize();
}
}
}
@@ -4202,9 +4095,10 @@ protected:
// Just try to match up the file by basename if we have no matches at
// this point
- if (num_matches == 0)
- num_matches =
- target->GetImages().FindModules(module_spec, matching_module_list);
+ if (num_matches == 0) {
+ target->GetImages().FindModules(module_spec, matching_module_list);
+ num_matches = matching_module_list.GetSize();
+ }
while (num_matches == 0) {
ConstString filename_no_extension(
@@ -4221,8 +4115,8 @@ protected:
// Replace basename with one less extension
module_spec.GetFileSpec().GetFilename() = filename_no_extension;
- num_matches =
- target->GetImages().FindModules(module_spec, matching_module_list);
+ target->GetImages().FindModules(module_spec, matching_module_list);
+ num_matches = matching_module_list.GetSize();
}
if (num_matches > 1) {
@@ -4238,48 +4132,44 @@ protected:
// decides to create it!
module_sp->SetSymbolFileFileSpec(symbol_fspec);
- SymbolVendor *symbol_vendor =
- module_sp->GetSymbolVendor(true, &result.GetErrorStream());
- if (symbol_vendor) {
- SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
-
- if (symbol_file) {
- ObjectFile *object_file = symbol_file->GetObjectFile();
-
- if (object_file && object_file->GetFileSpec() == symbol_fspec) {
- // Provide feedback that the symfile has been successfully added.
- const FileSpec &module_fs = module_sp->GetFileSpec();
- result.AppendMessageWithFormat(
- "symbol file '%s' has been added to '%s'\n", symfile_path,
- module_fs.GetPath().c_str());
-
- // Let clients know something changed in the module if it is
- // currently loaded
- ModuleList module_list;
- module_list.Append(module_sp);
- target->SymbolsDidLoad(module_list);
-
- // Make sure we load any scripting resources that may be embedded
- // in the debug info files in case the platform supports that.
- Status error;
- StreamString feedback_stream;
- module_sp->LoadScriptingResourceInTarget(target, error,
- &feedback_stream);
- if (error.Fail() && error.AsCString())
- result.AppendWarningWithFormat(
- "unable to load scripting data for module %s - error "
- "reported was %s",
- module_sp->GetFileSpec()
- .GetFileNameStrippingExtension()
- .GetCString(),
- error.AsCString());
- else if (feedback_stream.GetSize())
- result.AppendWarningWithFormat("%s", feedback_stream.GetData());
-
- flush = true;
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
+ SymbolFile *symbol_file =
+ module_sp->GetSymbolFile(true, &result.GetErrorStream());
+ if (symbol_file) {
+ ObjectFile *object_file = symbol_file->GetObjectFile();
+
+ if (object_file && object_file->GetFileSpec() == symbol_fspec) {
+ // Provide feedback that the symfile has been successfully added.
+ const FileSpec &module_fs = module_sp->GetFileSpec();
+ result.AppendMessageWithFormat(
+ "symbol file '%s' has been added to '%s'\n", symfile_path,
+ module_fs.GetPath().c_str());
+
+ // Let clients know something changed in the module if it is
+ // currently loaded
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target->SymbolsDidLoad(module_list);
+
+ // Make sure we load any scripting resources that may be embedded
+ // in the debug info files in case the platform supports that.
+ Status error;
+ StreamString feedback_stream;
+ module_sp->LoadScriptingResourceInTarget(target, error,
+ &feedback_stream);
+ if (error.Fail() && error.AsCString())
+ result.AppendWarningWithFormat(
+ "unable to load scripting data for module %s - error "
+ "reported was %s",
+ module_sp->GetFileSpec()
+ .GetFileNameStrippingExtension()
+ .GetCString(),
+ error.AsCString());
+ else if (feedback_stream.GetSize())
+ result.AppendWarningWithFormat("%s", feedback_stream.GetData());
+
+ flush = true;
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
}
// Clear the symbol file spec if anything went wrong
@@ -4430,9 +4320,9 @@ protected:
PlatformSP platform_sp(target->GetPlatform());
for (auto &entry : args.entries()) {
- if (!entry.ref.empty()) {
+ if (!entry.ref().empty()) {
auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
- symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native);
+ symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
FileSystem::Instance().Resolve(symbol_file_spec);
if (file_option_set) {
module_spec.GetFileSpec() =
@@ -4456,7 +4346,7 @@ protected:
} else {
std::string resolved_symfile_path =
module_spec.GetSymbolFileSpec().GetPath();
- if (resolved_symfile_path != entry.ref) {
+ if (resolved_symfile_path != entry.ref()) {
result.AppendErrorWithFormat(
"invalid module path '%s' with resolved path '%s'\n",
entry.c_str(), resolved_symfile_path.c_str());
@@ -4511,23 +4401,8 @@ private:
#pragma mark CommandObjectTargetStopHookAdd
// CommandObjectTargetStopHookAdd
-
-static constexpr OptionDefinition g_target_stop_hook_add_options[] = {
- // clang-format off
- { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Add a command for the stop hook. Can be specified more than once, and commands will be run in the order they appear." },
- { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
- { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
- { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
- { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
- { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
- { LLDB_OPT_SET_ALL, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
- // clang-format on
-};
+#define LLDB_OPTIONS_target_stop_hook_add
+#include "CommandOptions.inc"
class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -4636,8 +4511,7 @@ public:
break;
default:
- error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -4698,7 +4572,7 @@ public:
protected:
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(
"Enter your stop hook command(s). Type 'DONE' to end.\n");
@@ -4710,7 +4584,7 @@ protected:
std::string &line) override {
if (m_stop_hook_sp) {
if (line.empty()) {
- StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
if (error_sp) {
error_sp->Printf("error: stop hook #%" PRIu64
" aborted, no commands.\n",
@@ -4722,7 +4596,7 @@ protected:
target->RemoveStopHookByID(m_stop_hook_sp->GetID());
} else {
m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp) {
output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
m_stop_hook_sp->GetID());
@@ -4737,52 +4611,50 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
m_stop_hook_sp.reset();
- Target *target = GetSelectedOrDummyTarget();
- if (target) {
- Target::StopHookSP new_hook_sp = target->CreateStopHook();
-
- // First step, make the specifier.
- std::unique_ptr<SymbolContextSpecifier> specifier_up;
- if (m_options.m_sym_ctx_specified) {
- specifier_up.reset(
- new SymbolContextSpecifier(GetDebugger().GetSelectedTarget()));
-
- if (!m_options.m_module_name.empty()) {
- specifier_up->AddSpecification(
- m_options.m_module_name.c_str(),
- SymbolContextSpecifier::eModuleSpecified);
- }
+ Target &target = GetSelectedOrDummyTarget();
+ Target::StopHookSP new_hook_sp = target.CreateStopHook();
- if (!m_options.m_class_name.empty()) {
- specifier_up->AddSpecification(
- m_options.m_class_name.c_str(),
- SymbolContextSpecifier::eClassOrNamespaceSpecified);
- }
+ // First step, make the specifier.
+ std::unique_ptr<SymbolContextSpecifier> specifier_up;
+ if (m_options.m_sym_ctx_specified) {
+ specifier_up.reset(
+ new SymbolContextSpecifier(GetDebugger().GetSelectedTarget()));
- if (!m_options.m_file_name.empty()) {
- specifier_up->AddSpecification(
- m_options.m_file_name.c_str(),
- SymbolContextSpecifier::eFileSpecified);
- }
+ if (!m_options.m_module_name.empty()) {
+ specifier_up->AddSpecification(
+ m_options.m_module_name.c_str(),
+ SymbolContextSpecifier::eModuleSpecified);
+ }
- if (m_options.m_line_start != 0) {
- specifier_up->AddLineSpecification(
- m_options.m_line_start,
- SymbolContextSpecifier::eLineStartSpecified);
- }
+ if (!m_options.m_class_name.empty()) {
+ specifier_up->AddSpecification(
+ m_options.m_class_name.c_str(),
+ SymbolContextSpecifier::eClassOrNamespaceSpecified);
+ }
- if (m_options.m_line_end != UINT_MAX) {
- specifier_up->AddLineSpecification(
- m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
- }
+ if (!m_options.m_file_name.empty()) {
+ specifier_up->AddSpecification(m_options.m_file_name.c_str(),
+ SymbolContextSpecifier::eFileSpecified);
+ }
- if (!m_options.m_function_name.empty()) {
- specifier_up->AddSpecification(
- m_options.m_function_name.c_str(),
- SymbolContextSpecifier::eFunctionSpecified);
- }
+ if (m_options.m_line_start != 0) {
+ specifier_up->AddLineSpecification(
+ m_options.m_line_start,
+ SymbolContextSpecifier::eLineStartSpecified);
}
+ if (m_options.m_line_end != UINT_MAX) {
+ specifier_up->AddLineSpecification(
+ m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
+ }
+
+ if (!m_options.m_function_name.empty()) {
+ specifier_up->AddSpecification(
+ m_options.m_function_name.c_str(),
+ SymbolContextSpecifier::eFunctionSpecified);
+ }
+ }
+
if (specifier_up)
new_hook_sp->SetSpecifier(specifier_up.release());
@@ -4825,10 +4697,6 @@ protected:
// into our IOHandlerDelegate functions
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
- }
return result.Succeeded();
}
@@ -4853,43 +4721,37 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target) {
- // FIXME: see if we can use the breakpoint id style parser?
- size_t num_args = command.GetArgumentCount();
- if (num_args == 0) {
- if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
+ Target &target = GetSelectedOrDummyTarget();
+ // FIXME: see if we can use the breakpoint id style parser?
+ size_t num_args = command.GetArgumentCount();
+ if (num_args == 0) {
+ if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ target.RemoveAllStopHooks();
+ }
+ } else {
+ bool success;
+ for (size_t i = 0; i < num_args; i++) {
+ lldb::user_id_t user_id = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
result.SetStatus(eReturnStatusFailed);
return false;
- } else {
- target->RemoveAllStopHooks();
}
- } else {
- bool success;
- for (size_t i = 0; i < num_args; i++) {
- lldb::user_id_t user_id = StringConvert::ToUInt32(
- command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success) {
- result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
- command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- success = target->RemoveStopHookByID(user_id);
- if (!success) {
- result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
- command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ success = target.RemoveStopHookByID(user_id);
+ if (!success) {
+ result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
}
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
}
-
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
};
@@ -4910,38 +4772,33 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (target) {
- // FIXME: see if we can use the breakpoint id style parser?
- size_t num_args = command.GetArgumentCount();
- bool success;
+ Target &target = GetSelectedOrDummyTarget();
+ // FIXME: see if we can use the breakpoint id style parser?
+ size_t num_args = command.GetArgumentCount();
+ bool success;
- if (num_args == 0) {
- target->SetAllStopHooksActiveState(m_enable);
- } else {
- for (size_t i = 0; i < num_args; i++) {
- lldb::user_id_t user_id = StringConvert::ToUInt32(
- command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success) {
- result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
- command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- success = target->SetStopHookActiveStateByID(user_id, m_enable);
- if (!success) {
- result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
- command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (num_args == 0) {
+ target.SetAllStopHooksActiveState(m_enable);
+ } else {
+ for (size_t i = 0; i < num_args; i++) {
+ lldb::user_id_t user_id = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ success = target.SetStopHookActiveStateByID(user_id, m_enable);
+ if (!success) {
+ result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
}
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
}
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
@@ -4964,19 +4821,14 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetSelectedOrDummyTarget();
- if (!target) {
- result.AppendError("invalid target\n");
- result.SetStatus(eReturnStatusFailed);
- return result.Succeeded();
- }
+ Target &target = GetSelectedOrDummyTarget();
- size_t num_hooks = target->GetNumStopHooks();
+ size_t num_hooks = target.GetNumStopHooks();
if (num_hooks == 0) {
result.GetOutputStream().PutCString("No stop hooks.\n");
} else {
for (size_t i = 0; i < num_hooks; i++) {
- Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
+ Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
if (i > 0)
result.GetOutputStream().PutCString("\n");
this_hook->GetDescription(&(result.GetOutputStream()),
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index ed7cf0a1a48d..8c5274553902 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -16,6 +16,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -237,11 +238,8 @@ protected:
};
// CommandObjectThreadBacktrace
-
-static constexpr OptionDefinition g_thread_backtrace_options[] = {
#define LLDB_OPTIONS_thread_backtrace
#include "CommandOptions.inc"
-};
class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
public:
@@ -284,9 +282,7 @@ public:
"invalid boolean value for option '%c'", short_option);
} break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -403,134 +399,125 @@ static constexpr OptionEnumValues TriRunningModes() {
return OptionEnumValues(g_tri_running_mode);
}
-static constexpr OptionDefinition g_thread_step_scope_options[] = {
#define LLDB_OPTIONS_thread_step_scope
#include "CommandOptions.inc"
-};
-class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
+class ThreadStepScopeOptionGroup : public OptionGroup {
public:
- class CommandOptions : public Options {
- public:
- CommandOptions() : Options() {
- // Keep default values of all options in one place: OptionParsingStarting
- // ()
- OptionParsingStarting(nullptr);
- }
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 'a': {
- bool success;
- bool avoid_no_debug =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat(
- "invalid boolean value for option '%c'", short_option);
- else {
- m_step_in_avoid_no_debug =
- avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- } break;
-
- case 'A': {
- bool success;
- bool avoid_no_debug =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat(
- "invalid boolean value for option '%c'", short_option);
- else {
- m_step_out_avoid_no_debug =
- avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- } break;
-
- case 'c':
- if (option_arg.getAsInteger(0, m_step_count))
- error.SetErrorStringWithFormat("invalid step count '%s'",
- option_arg.str().c_str());
- break;
-
- case 'C':
- m_class_name.clear();
- m_class_name.assign(option_arg);
- break;
-
- case 'm': {
- auto enum_values = GetDefinitions()[option_idx].enum_values;
- m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
- option_arg, enum_values, eOnlyDuringStepping, error);
- } break;
-
- case 'e':
- if (option_arg == "block") {
- m_end_line_is_block_end = true;
- break;
- }
- if (option_arg.getAsInteger(0, m_end_line))
- error.SetErrorStringWithFormat("invalid end line number '%s'",
- option_arg.str().c_str());
- break;
+ ThreadStepScopeOptionGroup() : OptionGroup() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- case 'r':
- m_avoid_regexp.clear();
- m_avoid_regexp.assign(option_arg);
- break;
+ ~ThreadStepScopeOptionGroup() override = default;
- case 't':
- m_step_in_target.clear();
- m_step_in_target.assign(option_arg);
- break;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_step_scope_options);
+ }
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option
+ = g_thread_step_scope_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'a': {
+ bool success;
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_in_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
+ }
+ } break;
+
+ case 'A': {
+ bool success;
+ bool avoid_no_debug =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_out_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
+ }
+ } break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, m_step_count))
+ error.SetErrorStringWithFormat("invalid step count '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'm': {
+ auto enum_values = GetDefinitions()[option_idx].enum_values;
+ m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum(
+ option_arg, enum_values, eOnlyDuringStepping, error);
+ } break;
+
+ case 'e':
+ if (option_arg == "block") {
+ m_end_line_is_block_end = true;
break;
}
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_step_in_avoid_no_debug = eLazyBoolCalculate;
- m_step_out_avoid_no_debug = eLazyBoolCalculate;
- m_run_mode = eOnlyDuringStepping;
-
- // Check if we are in Non-Stop mode
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- if (target_sp && target_sp->GetNonStopModeEnabled())
- m_run_mode = eOnlyThisThread;
+ if (option_arg.getAsInteger(0, m_end_line))
+ error.SetErrorStringWithFormat("invalid end line number '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'r':
m_avoid_regexp.clear();
+ m_avoid_regexp.assign(option_arg);
+ break;
+
+ case 't':
m_step_in_target.clear();
- m_class_name.clear();
- m_step_count = 1;
- m_end_line = LLDB_INVALID_LINE_NUMBER;
- m_end_line_is_block_end = false;
- }
+ m_step_in_target.assign(option_arg);
+ break;
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_thread_step_scope_options);
+ default:
+ llvm_unreachable("Unimplemented option");
}
+ return error;
+ }
- // Instance variables to hold the values for command options.
- LazyBool m_step_in_avoid_no_debug;
- LazyBool m_step_out_avoid_no_debug;
- RunMode m_run_mode;
- std::string m_avoid_regexp;
- std::string m_step_in_target;
- std::string m_class_name;
- uint32_t m_step_count;
- uint32_t m_end_line;
- bool m_end_line_is_block_end;
- };
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_step_in_avoid_no_debug = eLazyBoolCalculate;
+ m_step_out_avoid_no_debug = eLazyBoolCalculate;
+ m_run_mode = eOnlyDuringStepping;
+
+ // Check if we are in Non-Stop mode
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ if (target_sp && target_sp->GetNonStopModeEnabled())
+ m_run_mode = eOnlyThisThread;
+
+ m_avoid_regexp.clear();
+ m_step_in_target.clear();
+ m_step_count = 1;
+ m_end_line = LLDB_INVALID_LINE_NUMBER;
+ m_end_line_is_block_end = false;
+ }
+
+ // Instance variables to hold the values for command options.
+ LazyBool m_step_in_avoid_no_debug;
+ LazyBool m_step_out_avoid_no_debug;
+ RunMode m_run_mode;
+ std::string m_avoid_regexp;
+ std::string m_step_in_target;
+ uint32_t m_step_count;
+ uint32_t m_end_line;
+ bool m_end_line_is_block_end;
+};
+
+class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
+public:
CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter,
const char *name, const char *help,
@@ -542,7 +529,8 @@ public:
eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched |
eCommandProcessMustBePaused),
- m_step_type(step_type), m_step_scope(step_scope), m_options() {
+ m_step_type(step_type), m_step_scope(step_scope), m_options(),
+ m_class_options("scripted step", 'C') {
CommandArgumentEntry arg;
CommandArgumentData thread_id_arg;
@@ -556,11 +544,19 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back(arg);
+
+ if (step_type == eStepTypeScripted) {
+ m_all_options.Append(&m_class_options, LLDB_OPT_SET_1, LLDB_OPT_SET_1);
+ }
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
}
~CommandObjectThreadStepWithTypeAndScope() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override {
+ return &m_all_options;
+ }
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -600,15 +596,15 @@ protected:
}
if (m_step_type == eStepTypeScripted) {
- if (m_options.m_class_name.empty()) {
+ if (m_class_options.GetClassName().empty()) {
result.AppendErrorWithFormat("empty class name for scripted step.");
result.SetStatus(eReturnStatusFailed);
return false;
} else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
- m_options.m_class_name.c_str())) {
+ m_class_options.GetClassName().c_str())) {
result.AppendErrorWithFormat(
"class for scripted step: \"%s\" does not exist.",
- m_options.m_class_name.c_str());
+ m_class_options.GetClassName().c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -724,7 +720,8 @@ protected:
m_options.m_step_out_avoid_no_debug);
} else if (m_step_type == eStepTypeScripted) {
new_plan_sp = thread->QueueThreadPlanForStepScripted(
- abort_other_plans, m_options.m_class_name.c_str(),
+ abort_other_plans, m_class_options.GetClassName().c_str(),
+ m_class_options.GetStructuredData(),
bool_stop_other_threads, new_plan_status);
} else {
result.AppendError("step type is not supported");
@@ -792,7 +789,9 @@ protected:
protected:
StepType m_step_type;
StepScope m_step_scope;
- CommandOptions m_options;
+ ThreadStepScopeOptionGroup m_options;
+ OptionGroupPythonClassWithDict m_class_options;
+ OptionGroupOptions m_all_options;
};
// CommandObjectThreadContinue
@@ -828,13 +827,6 @@ public:
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool synchronous_execution = m_interpreter.GetSynchronous();
- if (!GetDebugger().GetSelectedTarget()) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
Process *process = m_exe_ctx.GetProcessPtr();
if (process == nullptr) {
result.AppendError("no process exists. Cannot continue");
@@ -856,7 +848,7 @@ public:
std::vector<Thread *> resume_threads;
for (auto &entry : command.entries()) {
uint32_t thread_idx;
- if (entry.ref.getAsInteger(0, thread_idx)) {
+ if (entry.ref().getAsInteger(0, thread_idx)) {
result.AppendErrorWithFormat(
"invalid thread index argument: \"%s\".\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -983,10 +975,8 @@ static constexpr OptionEnumValues DuoRunningModes() {
return OptionEnumValues(g_duo_running_mode);
}
-static constexpr OptionDefinition g_thread_until_options[] = {
#define LLDB_OPTIONS_thread_until
#include "CommandOptions.inc"
-};
class CommandObjectThreadUntil : public CommandObjectParsed {
public:
@@ -1044,9 +1034,7 @@ public:
}
} break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1104,13 +1092,7 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool synchronous_execution = m_interpreter.GetSynchronous();
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
Process *process = m_exe_ctx.GetProcessPtr();
if (process == nullptr) {
@@ -1402,11 +1384,8 @@ protected:
};
// CommandObjectThreadInfo
-
-static constexpr OptionDefinition g_thread_info_options[] = {
#define LLDB_OPTIONS_thread_info
#include "CommandOptions.inc"
-};
class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
public:
@@ -1436,7 +1415,7 @@ public:
break;
default:
- return Status("invalid short option character '%c'", short_option);
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1536,11 +1515,8 @@ class CommandObjectThreadException : public CommandObjectIterateOverThreads {
};
// CommandObjectThreadReturn
-
-static constexpr OptionDefinition g_thread_return_options[] = {
#define LLDB_OPTIONS_thread_return
#include "CommandOptions.inc"
-};
class CommandObjectThreadReturn : public CommandObjectRaw {
public:
@@ -1573,9 +1549,7 @@ public:
}
} break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1711,11 +1685,8 @@ protected:
};
// CommandObjectThreadJump
-
-static constexpr OptionDefinition g_thread_jump_options[] = {
#define LLDB_OPTIONS_thread_jump
#include "CommandOptions.inc"
-};
class CommandObjectThreadJump : public CommandObjectParsed {
public:
@@ -1760,7 +1731,7 @@ public:
m_force = true;
break;
default:
- return Status("invalid short option character '%c'", short_option);
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -1854,11 +1825,8 @@ protected:
// Next are the subcommands of CommandObjectMultiwordThreadPlan
// CommandObjectThreadPlanList
-
-static constexpr OptionDefinition g_thread_plan_list_options[] = {
#define LLDB_OPTIONS_thread_plan_list
#include "CommandOptions.inc"
-};
class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
public:
@@ -1885,9 +1853,7 @@ public:
m_verbose = true;
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -2102,7 +2068,11 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread(
"step-scripted",
CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
interpreter, "thread step-scripted",
- "Step as instructed by the script class passed in the -C option.",
+ "Step as instructed by the script class passed in the -C option. "
+ "You can also specify a dictionary of key (-k) and value (-v) pairs "
+ "that will be used to populate an SBStructuredData Dictionary, which "
+ "will be passed to the constructor of the class implementing the "
+ "scripted step. See the Python Reference for more details.",
nullptr, eStepTypeScripted, eStepScopeSource)));
LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 98a43f50b1b1..5e31fd5e8bce 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -80,9 +80,9 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command,
return false;
for (auto entry : llvm::enumerate(command.entries().drop_back())) {
- if (entry.value().ref != "unsigned")
+ if (entry.value().ref() != "unsigned")
continue;
- auto next = command.entries()[entry.index() + 1].ref;
+ auto next = command.entries()[entry.index() + 1].ref();
if (next == "int" || next == "short" || next == "char" || next == "long") {
result.AppendWarningWithFormat(
"unsigned %s being treated as two types. if you meant the combined "
@@ -95,10 +95,8 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command,
return false;
}
-static constexpr OptionDefinition g_type_summary_add_options[] = {
#define LLDB_OPTIONS_type_summary_add
#include "CommandOptions.inc"
-};
class CommandObjectTypeSummaryAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -153,7 +151,7 @@ public:
"for\n"
" internal_dict: an LLDB support object not to be used\"\"\"\n";
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(g_summary_addreader_instructions);
output_sp->Flush();
@@ -162,7 +160,7 @@ public:
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
#ifndef LLDB_DISABLE_PYTHON
ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
@@ -197,9 +195,7 @@ public:
Status error;
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
- const char *type_name =
- options->m_target_types.GetStringAtIndex(i);
+ for (const std::string &type_name : options->m_target_types) {
CommandObjectTypeSummaryAdd::AddSummary(
ConstString(type_name), script_format,
(options->m_regex
@@ -282,10 +278,8 @@ static const char *g_synth_addreader_instructions =
" '''Optional'''\n"
"class synthProvider:\n";
-static constexpr OptionDefinition g_type_synth_add_options[] = {
#define LLDB_OPTIONS_type_synth_add
#include "CommandOptions.inc"
-};
class CommandObjectTypeSynthAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -329,9 +323,7 @@ private:
m_regex = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -391,7 +383,7 @@ protected:
}
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(g_synth_addreader_instructions);
output_sp->Flush();
@@ -400,7 +392,7 @@ protected:
void IOHandlerInputComplete(IOHandler &io_handler,
std::string &data) override {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
#ifndef LLDB_DISABLE_PYTHON
ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
@@ -441,13 +433,10 @@ protected:
Status error;
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
- const char *type_name =
- options->m_target_types.GetStringAtIndex(i);
- ConstString const_type_name(type_name);
- if (const_type_name) {
+ for (const std::string &type_name : options->m_target_types) {
+ if (!type_name.empty()) {
if (!CommandObjectTypeSynthAdd::AddSynth(
- const_type_name, synth_provider,
+ ConstString(type_name), synth_provider,
options->m_regex
? CommandObjectTypeSynthAdd::eRegexSynth
: CommandObjectTypeSynthAdd::eRegularSynth,
@@ -503,10 +492,8 @@ public:
// CommandObjectTypeFormatAdd
-static constexpr OptionDefinition g_type_format_add_options[] = {
#define LLDB_OPTIONS_type_format_add
#include "CommandOptions.inc"
-};
class CommandObjectTypeFormatAdd : public CommandObjectParsed {
private:
@@ -559,9 +546,7 @@ private:
m_custom_type_name.assign(option_value);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -694,25 +679,26 @@ protected:
WarnOnPotentialUnquotedUnsignedType(command, result);
for (auto &arg_entry : command.entries()) {
- if (arg_entry.ref.empty()) {
+ if (arg_entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- ConstString typeCS(arg_entry.ref);
+ ConstString typeCS(arg_entry.ref());
if (m_command_options.m_regex) {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(arg_entry.ref)) {
+ RegularExpression typeRX(arg_entry.ref());
+ if (!typeRX.IsValid()) {
result.AppendError(
"regex format error (maybe this is not really a regex?)");
result.SetStatus(eReturnStatusFailed);
return false;
}
category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
- category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
+ category_sp->GetRegexTypeFormatsContainer()->Add(std::move(typeRX),
+ entry);
} else
- category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
+ category_sp->GetTypeFormatsContainer()->Add(std::move(typeCS), entry);
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -720,10 +706,8 @@ protected:
}
};
-static constexpr OptionDefinition g_type_formatter_delete_options[] = {
#define LLDB_OPTIONS_type_formatter_delete
#include "CommandOptions.inc"
-};
class CommandObjectTypeFormatterDelete : public CommandObjectParsed {
protected:
@@ -749,9 +733,7 @@ protected:
m_language = Language::GetLanguageTypeFromString(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -859,10 +841,8 @@ protected:
}
};
-static constexpr OptionDefinition g_type_formatter_clear_options[] = {
#define LLDB_OPTIONS_type_formatter_clear
#include "CommandOptions.inc"
-};
class CommandObjectTypeFormatterClear : public CommandObjectParsed {
private:
@@ -882,9 +862,7 @@ private:
m_delete_all = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -971,11 +949,8 @@ public:
"type format clear", "Delete all existing format styles.") {}
};
-
-static constexpr OptionDefinition g_type_formatter_list_options[] = {
#define LLDB_OPTIONS_type_formatter_list
#include "CommandOptions.inc"
-};
template <typename FormatterType>
class CommandObjectTypeFormatterList : public CommandObjectParsed {
@@ -1005,9 +980,7 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed {
m_category_language.SetOptionWasSet();
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1061,9 +1034,9 @@ protected:
std::unique_ptr<RegularExpression> formatter_regex;
if (m_options.m_category_regex.OptionWasSet()) {
- category_regex.reset(new RegularExpression());
- if (!category_regex->Compile(
- m_options.m_category_regex.GetCurrentValueAsRef())) {
+ category_regex.reset(new RegularExpression(
+ m_options.m_category_regex.GetCurrentValueAsRef()));
+ if (!category_regex->IsValid()) {
result.AppendErrorWithFormat(
"syntax error in category regular expression '%s'",
m_options.m_category_regex.GetCurrentValueAsRef().str().c_str());
@@ -1074,8 +1047,9 @@ protected:
if (argc == 1) {
const char *arg = command.GetArgumentAtIndex(0);
- formatter_regex.reset(new RegularExpression());
- if (!formatter_regex->Compile(llvm::StringRef::withNullAsEmpty(arg))) {
+ formatter_regex.reset(
+ new RegularExpression(llvm::StringRef::withNullAsEmpty(arg)));
+ if (!formatter_regex->IsValid()) {
result.AppendErrorWithFormat("syntax error in regular expression '%s'",
arg);
result.SetStatus(eReturnStatusFailed);
@@ -1116,13 +1090,13 @@ protected:
foreach
.SetWithRegex([&result, &formatter_regex, &any_printed](
- RegularExpressionSP regex_sp,
+ const RegularExpression &regex,
const FormatterSharedPointer &format_sp) -> bool {
if (formatter_regex) {
bool escape = true;
- if (regex_sp->GetText() == formatter_regex->GetText()) {
+ if (regex.GetText() == formatter_regex->GetText()) {
escape = false;
- } else if (formatter_regex->Execute(regex_sp->GetText())) {
+ } else if (formatter_regex->Execute(regex.GetText())) {
escape = false;
}
@@ -1132,7 +1106,7 @@ protected:
any_printed = true;
result.GetOutputStream().Printf("%s: %s\n",
- regex_sp->GetText().str().c_str(),
+ regex.GetText().str().c_str(),
format_sp->GetDescription().c_str());
return true;
});
@@ -1257,8 +1231,7 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue(
m_flags.SetHideItemNames(true);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1355,13 +1328,13 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary(
m_options.m_name, m_options.m_category);
for (auto &entry : command.entries()) {
- if (entry.ref.empty()) {
+ if (entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- options->m_target_types << entry.ref;
+ options->m_target_types << entry.ref();
}
m_interpreter.GetPythonCommandsFromIOHandler(
@@ -1382,7 +1355,7 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary(
for (auto &entry : command.entries()) {
CommandObjectTypeSummaryAdd::AddSummary(
- ConstString(entry.ref), script_format,
+ ConstString(entry.ref()), script_format,
(m_options.m_regex ? eRegexSummary : eRegularSummary),
m_options.m_category, &error);
if (error.Fail()) {
@@ -1455,12 +1428,12 @@ bool CommandObjectTypeSummaryAdd::Execute_StringSummary(
// now I have a valid format, let's add it to every type
Status error;
for (auto &arg_entry : command.entries()) {
- if (arg_entry.ref.empty()) {
+ if (arg_entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- ConstString typeCS(arg_entry.ref);
+ ConstString typeCS(arg_entry.ref());
AddSummary(typeCS, entry,
(m_options.m_regex ? eRegexSummary : eRegularSummary),
@@ -1647,8 +1620,8 @@ bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
}
if (type == eRegexSummary) {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetStringRef())) {
+ RegularExpression typeRX(type_name.GetStringRef());
+ if (!typeRX.IsValid()) {
if (error)
error->SetErrorString(
"regex format error (maybe this is not really a regex?)");
@@ -1656,7 +1629,7 @@ bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
}
category->GetRegexTypeSummariesContainer()->Delete(type_name);
- category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
+ category->GetRegexTypeSummariesContainer()->Add(std::move(typeRX), entry);
return true;
} else if (type == eNamedSummary) {
@@ -1664,7 +1637,7 @@ bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
DataVisualization::NamedSummaryFormats::Add(type_name, entry);
return true;
} else {
- category->GetTypeSummariesContainer()->Add(type_name, entry);
+ category->GetTypeSummariesContainer()->Add(std::move(type_name), entry);
return true;
}
}
@@ -1731,11 +1704,8 @@ protected:
};
// CommandObjectTypeCategoryDefine
-
-static constexpr OptionDefinition g_type_category_define_options[] = {
#define LLDB_OPTIONS_type_category_define
#include "CommandOptions.inc"
-};
class CommandObjectTypeCategoryDefine : public CommandObjectParsed {
class CommandOptions : public Options {
@@ -1759,9 +1729,7 @@ class CommandObjectTypeCategoryDefine : public CommandObjectParsed {
error = m_cate_language.SetValueFromString(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -1818,7 +1786,7 @@ protected:
for (auto &entry : command.entries()) {
TypeCategoryImplSP category_sp;
- if (DataVisualization::Categories::GetCategory(ConstString(entry.ref),
+ if (DataVisualization::Categories::GetCategory(ConstString(entry.ref()),
category_sp) &&
category_sp) {
category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
@@ -1834,11 +1802,8 @@ protected:
};
// CommandObjectTypeCategoryEnable
-
-static constexpr OptionDefinition g_type_category_enable_options[] = {
#define LLDB_OPTIONS_type_category_enable
#include "CommandOptions.inc"
-};
class CommandObjectTypeCategoryEnable : public CommandObjectParsed {
class CommandOptions : public Options {
@@ -1862,9 +1827,7 @@ class CommandObjectTypeCategoryEnable : public CommandObjectParsed {
}
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -2006,11 +1969,8 @@ protected:
};
// CommandObjectTypeCategoryDisable
-
-OptionDefinition constexpr g_type_category_disable_options[] = {
#define LLDB_OPTIONS_type_category_disable
#include "CommandOptions.inc"
-};
class CommandObjectTypeCategoryDisable : public CommandObjectParsed {
class CommandOptions : public Options {
@@ -2034,9 +1994,7 @@ class CommandObjectTypeCategoryDisable : public CommandObjectParsed {
}
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -2142,9 +2100,9 @@ protected:
std::unique_ptr<RegularExpression> regex;
if (argc == 1) {
- regex.reset(new RegularExpression());
const char *arg = command.GetArgumentAtIndex(0);
- if (!regex->Compile(llvm::StringRef::withNullAsEmpty(arg))) {
+ regex.reset(new RegularExpression(llvm::StringRef::withNullAsEmpty(arg)));
+ if (!regex->IsValid()) {
result.AppendErrorWithFormat(
"syntax error in category regular expression '%s'", arg);
result.SetStatus(eReturnStatusFailed);
@@ -2270,13 +2228,13 @@ bool CommandObjectTypeSynthAdd::Execute_HandwritePython(
m_options.m_cascade, m_options.m_regex, m_options.m_category);
for (auto &entry : command.entries()) {
- if (entry.ref.empty()) {
+ if (entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- options->m_target_types << entry.ref;
+ options->m_target_types << entry.ref();
}
m_interpreter.GetPythonCommandsFromIOHandler(
@@ -2335,13 +2293,13 @@ bool CommandObjectTypeSynthAdd::Execute_PythonClass(
Status error;
for (auto &arg_entry : command.entries()) {
- if (arg_entry.ref.empty()) {
+ if (arg_entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- ConstString typeCS(arg_entry.ref);
+ ConstString typeCS(arg_entry.ref());
if (!AddSynth(typeCS, entry,
m_options.m_regex ? eRegexSynth : eRegularSynth,
m_options.m_category, &error)) {
@@ -2396,8 +2354,8 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
}
if (type == eRegexSynth) {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetStringRef())) {
+ RegularExpression typeRX(type_name.GetStringRef());
+ if (!typeRX.IsValid()) {
if (error)
error->SetErrorString(
"regex format error (maybe this is not really a regex?)");
@@ -2405,21 +2363,18 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
}
category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
- category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
+ category->GetRegexTypeSyntheticsContainer()->Add(std::move(typeRX), entry);
return true;
} else {
- category->GetTypeSyntheticsContainer()->Add(type_name, entry);
+ category->GetTypeSyntheticsContainer()->Add(std::move(type_name), entry);
return true;
}
}
#endif // LLDB_DISABLE_PYTHON
-
-static constexpr OptionDefinition g_type_filter_add_options[] = {
#define LLDB_OPTIONS_type_filter_add
#include "CommandOptions.inc"
-};
class CommandObjectTypeFilterAdd : public CommandObjectParsed {
private:
@@ -2461,9 +2416,7 @@ private:
m_regex = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -2527,8 +2480,8 @@ private:
}
if (type == eRegexFilter) {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetStringRef())) {
+ RegularExpression typeRX(type_name.GetStringRef());
+ if (!typeRX.IsValid()) {
if (error)
error->SetErrorString(
"regex format error (maybe this is not really a regex?)");
@@ -2536,11 +2489,11 @@ private:
}
category->GetRegexTypeFiltersContainer()->Delete(type_name);
- category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
+ category->GetRegexTypeFiltersContainer()->Add(std::move(typeRX), entry);
return true;
} else {
- category->GetTypeFiltersContainer()->Add(type_name, entry);
+ category->GetTypeFiltersContainer()->Add(std::move(type_name), entry);
return true;
}
}
@@ -2641,13 +2594,13 @@ protected:
WarnOnPotentialUnquotedUnsignedType(command, result);
for (auto &arg_entry : command.entries()) {
- if (arg_entry.ref.empty()) {
+ if (arg_entry.ref().empty()) {
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
- ConstString typeCS(arg_entry.ref);
+ ConstString typeCS(arg_entry.ref());
if (!AddFilter(typeCS, entry,
m_options.m_regex ? eRegexFilter : eRegularFilter,
m_options.m_category, &error)) {
@@ -2663,10 +2616,8 @@ protected:
};
// "type lookup"
-static constexpr OptionDefinition g_type_lookup_options[] = {
#define LLDB_OPTIONS_type_lookup
#include "CommandOptions.inc"
-};
class CommandObjectTypeLookup : public CommandObjectRaw {
protected:
@@ -2717,9 +2668,7 @@ protected:
break;
default:
- error.SetErrorStringWithFormat("invalid short option character '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 98e758b7ef6a..44dfb29b19b5 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -40,11 +40,6 @@ static void AddWatchpointDescription(Stream *s, Watchpoint *wp,
static bool CheckTargetForWatchpointOperations(Target *target,
CommandReturnObject &result) {
- if (target == nullptr) {
- result.AppendError("Invalid target. No existing target or watchpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
bool process_is_valid =
target->GetProcessSP() && target->GetProcessSP()->IsAlive();
if (!process_is_valid) {
@@ -94,12 +89,12 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
// Go through the arguments and make a canonical form of arg list containing
// only numbers with possible "-" in between.
for (auto &entry : args.entries()) {
- if ((idx = WithRSAIndex(entry.ref)) == -1) {
- StrRefArgs.push_back(entry.ref);
+ if ((idx = WithRSAIndex(entry.ref())) == -1) {
+ StrRefArgs.push_back(entry.ref());
continue;
}
// The Arg contains the range specifier, split it, then.
- std::tie(first, second) = entry.ref.split(RSA[idx]);
+ std::tie(first, second) = entry.ref().split(RSA[idx]);
if (!first.empty())
StrRefArgs.push_back(first);
StrRefArgs.push_back(Minus);
@@ -146,11 +141,8 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
// CommandObjectWatchpointList::Options
#pragma mark List::CommandOptions
-
-static constexpr OptionDefinition g_watchpoint_list_options[] = {
#define LLDB_OPTIONS_watchpoint_list
#include "CommandOptions.inc"
-};
#pragma mark List
@@ -159,7 +151,8 @@ public:
CommandObjectWatchpointList(CommandInterpreter &interpreter)
: CommandObjectParsed(
interpreter, "watchpoint list",
- "List all watchpoints at configurable levels of detail.", nullptr),
+ "List all watchpoints at configurable levels of detail.", nullptr,
+ eCommandRequiresTarget),
m_options() {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
@@ -199,9 +192,7 @@ public:
m_level = lldb::eDescriptionLevelVerbose;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -222,12 +213,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
- if (target == nullptr) {
- result.AppendError("Invalid target. No current target or watchpoints.");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ Target *target = &GetSelectedTarget();
if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) {
uint32_t num_supported_hardware_watchpoints;
@@ -297,7 +283,7 @@ public:
: CommandObjectParsed(interpreter, "enable",
"Enable the specified disabled watchpoint(s). If "
"no watchpoints are specified, enable all of them.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
eArgTypeWatchpointIDRange);
@@ -310,7 +296,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
if (!CheckTargetForWatchpointOperations(target, result))
return false;
@@ -367,7 +353,7 @@ public:
"Disable the specified watchpoint(s) without "
"removing it/them. If no watchpoints are "
"specified, disable them all.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
eArgTypeWatchpointIDRange);
@@ -380,7 +366,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
if (!CheckTargetForWatchpointOperations(target, result))
return false;
@@ -439,7 +425,7 @@ public:
: CommandObjectParsed(interpreter, "watchpoint delete",
"Delete the specified watchpoint(s). If no "
"watchpoints are specified, delete them all.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
eArgTypeWatchpointIDRange);
@@ -452,7 +438,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
if (!CheckTargetForWatchpointOperations(target, result))
return false;
@@ -507,10 +493,8 @@ protected:
// CommandObjectWatchpointIgnore
#pragma mark Ignore::CommandOptions
-static constexpr OptionDefinition g_watchpoint_ignore_options[] = {
#define LLDB_OPTIONS_watchpoint_ignore
#include "CommandOptions.inc"
-};
class CommandObjectWatchpointIgnore : public CommandObjectParsed {
public:
@@ -518,7 +502,7 @@ public:
: CommandObjectParsed(interpreter, "watchpoint ignore",
"Set ignore count on the specified watchpoint(s). "
"If no watchpoints are specified, set them all.",
- nullptr),
+ nullptr, eCommandRequiresTarget),
m_options() {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
@@ -550,9 +534,7 @@ public:
option_arg.str().c_str());
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -573,7 +555,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
if (!CheckTargetForWatchpointOperations(target, result))
return false;
@@ -625,11 +607,8 @@ private:
// CommandObjectWatchpointModify
#pragma mark Modify::CommandOptions
-
-static constexpr OptionDefinition g_watchpoint_modify_options[] = {
#define LLDB_OPTIONS_watchpoint_modify
#include "CommandOptions.inc"
-};
#pragma mark Modify
@@ -643,7 +622,7 @@ public:
"If no watchpoint is specified, act on the last created "
"watchpoint. "
"Passing an empty argument clears the modification.",
- nullptr),
+ nullptr, eCommandRequiresTarget),
m_options() {
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
@@ -674,9 +653,7 @@ public:
m_condition_passed = true;
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
@@ -699,7 +676,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
+ Target *target = &GetSelectedTarget();
if (!CheckTargetForWatchpointOperations(target, result))
return false;
@@ -808,12 +785,12 @@ corresponding to the byte size of the data type.");
protected:
static size_t GetVariableCallback(void *baton, const char *name,
VariableList &variable_list) {
+ size_t old_size = variable_list.GetSize();
Target *target = static_cast<Target *>(baton);
- if (target) {
- return target->GetImages().FindGlobalVariables(ConstString(name),
- UINT32_MAX, variable_list);
- }
- return 0;
+ if (target)
+ target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
+ variable_list);
+ return variable_list.GetSize() - old_size;
}
bool DoExecute(Args &command, CommandReturnObject &result) override {
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index 2be0b5b154e0..5683381efc85 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -24,28 +24,33 @@
using namespace lldb;
using namespace lldb_private;
-// CommandObjectWatchpointCommandAdd
-
// FIXME: "script-type" needs to have its contents determined dynamically, so
-// somebody can add a new scripting
-// language to lldb and have it pickable here without having to change this
-// enumeration by hand and rebuild lldb proper.
-
+// somebody can add a new scripting language to lldb and have it pickable here
+// without having to change this enumeration by hand and rebuild lldb proper.
static constexpr OptionEnumValueElement g_script_option_enumeration[] = {
- {eScriptLanguageNone, "command",
- "Commands are in the lldb command interpreter language"},
- {eScriptLanguagePython, "python", "Commands are in the Python language."},
- {eSortOrderByName, "default-script",
- "Commands are in the default scripting language."} };
+ {
+ eScriptLanguageNone,
+ "command",
+ "Commands are in the lldb command interpreter language",
+ },
+ {
+ eScriptLanguagePython,
+ "python",
+ "Commands are in the Python language.",
+ },
+ {
+ eSortOrderByName,
+ "default-script",
+ "Commands are in the default scripting language.",
+ },
+};
static constexpr OptionEnumValues ScriptOptionEnum() {
return OptionEnumValues(g_script_option_enumeration);
}
-static constexpr OptionDefinition g_watchpoint_command_add_options[] = {
#define LLDB_OPTIONS_watchpoint_command_add
#include "CommandOptions.inc"
-};
class CommandObjectWatchpointCommandAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
@@ -54,7 +59,7 @@ public:
: CommandObjectParsed(interpreter, "add",
"Add a set of LLDB commands to a watchpoint, to be "
"executed whenever the watchpoint is hit.",
- nullptr),
+ nullptr, eCommandRequiresTarget),
IOHandlerDelegateMultiline("DONE",
IOHandlerDelegate::Completion::LLDBCommand),
m_options() {
@@ -202,7 +207,7 @@ are no syntax errors may indicate that a function was declared but never called.
Options *GetOptions() override { return &m_options; }
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(
"Enter your debugger command(s). Type 'DONE' to end.\n");
@@ -349,7 +354,7 @@ are no syntax errors may indicate that a function was declared but never called.
break;
default:
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
@@ -384,14 +389,7 @@ are no syntax errors may indicate that a function was declared but never called.
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "watchpoints to which to add commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -481,7 +479,7 @@ public:
CommandObjectWatchpointCommandDelete(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "delete",
"Delete the set of commands from a watchpoint.",
- nullptr) {
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandArgumentData wp_id_arg;
@@ -501,14 +499,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "watchpoints from which to delete commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
@@ -557,10 +548,10 @@ protected:
class CommandObjectWatchpointCommandList : public CommandObjectParsed {
public:
CommandObjectWatchpointCommandList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "list", "List the script or set of "
- "commands to be executed when "
- "the watchpoint is hit.",
- nullptr) {
+ : CommandObjectParsed(interpreter, "list",
+ "List the script or set of commands to be executed "
+ "when the watchpoint is hit.",
+ nullptr, eCommandRequiresTarget) {
CommandArgumentEntry arg;
CommandArgumentData wp_id_arg;
@@ -580,14 +571,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- Target *target = GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr) {
- result.AppendError("There is not a current executable; there are no "
- "watchpoints for which to list commands");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = &GetSelectedTarget();
const WatchpointList &watchpoints = target->GetWatchpointList();
size_t num_watchpoints = watchpoints.GetSize();
diff --git a/source/Commands/Options.td b/source/Commands/Options.td
index 9cfbcd2d4ebf..87f5506c305f 100644
--- a/source/Commands/Options.td
+++ b/source/Commands/Options.td
@@ -38,6 +38,8 @@ let Command = "settings read" in {
}
let Command = "breakpoint list" in {
+ // FIXME: We need to add an "internal" command, and then add this sort of
+ // thing to it. But I need to see it for now, and don't want to wait.
def blist_internal : Option<"internal", "i">,
Desc<"Show debugger internal breakpoints">;
def blist_brief : Option<"brief", "b">, Group<1>,
@@ -52,6 +54,823 @@ let Command = "breakpoint list" in {
"provided, which prime new targets.">;
}
+let Command = "breakpoint modify" in {
+ def breakpoint_modify_ignore_count : Option<"ignore-count", "i">, Group<1>,
+ Arg<"Count">,
+ Desc<"Set the number of times this breakpoint is skipped before stopping.">;
+ def breakpoint_modify_one_shot : Option<"one-shot", "o">, Group<1>,
+ Arg<"Boolean">,
+ Desc<"The breakpoint is deleted the first time it stop causes a stop.">;
+ def breakpoint_modify_thread_index : Option<"thread-index", "x">, Group<1>,
+ Arg<"ThreadIndex">, Desc<"The breakpoint stops only for the thread whose "
+ "index matches this argument.">;
+ def breakpoint_modify_thread_id : Option<"thread-id", "t">, Group<1>,
+ Arg<"ThreadID">, Desc<"The breakpoint stops only for the thread whose TID "
+ "matches this argument.">;
+ def breakpoint_modify_thread_name : Option<"thread-name", "T">, Group<1>,
+ Arg<"ThreadName">, Desc<"The breakpoint stops only for the thread whose "
+ "thread name matches this argument.">;
+ def breakpoint_modify_queue_name : Option<"queue-name", "q">, Group<1>,
+ Arg<"QueueName">, Desc<"The breakpoint stops only for threads in the queue "
+ "whose name is given by this argument.">;
+ def breakpoint_modify_condition : Option<"condition", "c">, Group<1>,
+ Arg<"Expression">, Desc<"The breakpoint stops only if this condition "
+ "expression evaluates to true.">;
+ def breakpoint_modify_auto_continue : Option<"auto-continue", "G">, Group<1>,
+ Arg<"Boolean">,
+ Desc<"The breakpoint will auto-continue after running its commands.">;
+ def breakpoint_modify_enable : Option<"enable", "e">, Group<2>,
+ Desc<"Enable the breakpoint.">;
+ def breakpoint_modify_disable : Option<"disable", "d">, Group<3>,
+ Desc<"Disable the breakpoint.">;
+ def breakpoint_modify_command : Option<"command", "C">, Group<4>,
+ Arg<"Command">,
+ Desc<"A command to run when the breakpoint is hit, can be provided more "
+ "than once, the commands will get run in order left to right.">;
+}
+
+let Command = "breakpoint dummy" in {
+ def breakpoint_dummy_options_dummy_breakpoints :
+ Option<"dummy-breakpoints", "D">, Group<1>,
+ Desc<"Act on Dummy breakpoints - i.e. breakpoints set before a file is "
+ "provided, which prime new targets.">;
+}
+
+let Command = "breakpoint set" in {
+ def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
+ Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10
+ Desc<"Set the breakpoint only in this shared library. Can repeat this "
+ "option multiple times to specify multiple shared libraries.">;
+ def breakpoint_set_hardware : Option<"hardware", "H">,
+ Desc<"Require the breakpoint to use hardware breakpoints.">;
+ def breakpoint_set_file : Option<"file", "f">, Arg<"Filename">,
+ Completion<"SourceFile">, Groups<[1,3,4,5,6,7,8,9,11]>,
+ Desc<"Specifies the source file in which to set this breakpoint. Note, by "
+ "default lldb only looks for files that are #included if they use the "
+ "standard include file extensions. To set breakpoints on .c/.cpp/.m/.mm "
+ "files that are #included, set target.inline-breakpoint-strategy to "
+ "\"always\".">;
+ def breakpoint_set_line : Option<"line", "l">, Group<1>, Arg<"LineNum">,
+ Required,
+ Desc<"Specifies the line number on which to set this breakpoint.">;
+ def breakpoint_set_address : Option<"address", "a">, Group<2>,
+ Arg<"AddressOrExpression">, Required,
+ Desc<"Set the breakpoint at the specified address. If the address maps "
+ "uniquely toa particular binary, then the address will be converted to "
+ "a \"file\"address, so that the breakpoint will track that binary+offset "
+ "no matter where the binary eventually loads. Alternately, if you also "
+ "specify the module - with the -s option - then the address will be "
+ "treated as a file address in that module, and resolved accordingly. "
+ "Again, this will allow lldb to track that offset on subsequent reloads. "
+ " The module need not have been loaded at the time you specify this "
+ "breakpoint, and will get resolved when the module is loaded.">;
+ def breakpoint_set_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">,
+ Completion<"Symbol">, Required,
+ Desc<"Set the breakpoint by function name. Can be repeated multiple times "
+ "to makeone breakpoint for multiple names">;
+ def breakpoint_set_source_regexp_function :
+ Option<"source-regexp-function", "X">, Group<9>, Arg<"FunctionName">,
+ Completion<"Symbol">,
+ Desc<"When used with '-p' limits the source regex to source contained in "
+ "the namedfunctions. Can be repeated multiple times.">;
+ def breakpoint_set_fullname : Option<"fullname", "F">, Group<4>,
+ Arg<"FullName">, Required, Completion<"Symbol">,
+ Desc<"Set the breakpoint by fully qualified function names. For C++ this "
+ "means namespaces and all arguments, and for Objective-C this means a full "
+ "functionprototype with class and selector. Can be repeated multiple times"
+ " to make one breakpoint for multiple names.">;
+ def breakpoint_set_selector : Option<"selector", "S">, Group<5>,
+ Arg<"Selector">, Required,
+ Desc<"Set the breakpoint by ObjC selector name. Can be repeated multiple "
+ "times tomake one breakpoint for multiple Selectors.">;
+ def breakpoint_set_method : Option<"method", "M">, Group<6>, Arg<"Method">,
+ Required, Desc<"Set the breakpoint by C++ method names. Can be repeated "
+ "multiple times tomake one breakpoint for multiple methods.">;
+ def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>,
+ Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function "
+ "name, evaluating a regular-expression to findthe function name(s).">;
+ def breakpoint_set_basename : Option<"basename", "b">, Group<8>,
+ Arg<"FunctionName">, Required, Completion<"Symbol">,
+ Desc<"Set the breakpoint by function basename (C++ namespaces and arguments"
+ " will beignored). Can be repeated multiple times to make one breakpoint "
+ "for multiplesymbols.">;
+ def breakpoint_set_source_pattern_regexp :
+ Option<"source-pattern-regexp", "p">, Group<9>, Arg<"RegularExpression">,
+ Required, Desc<"Set the breakpoint by specifying a regular expression which"
+ " is matched against the source text in a source file or files specified "
+ "with the -f can be specified more than once. If no source files "
+ "are specified, uses the current \"default source file\". If you want to "
+ "match against all source files, pass the \"--all-files\" option.">;
+ def breakpoint_set_all_files : Option<"all-files", "A">, Group<9>,
+ Desc<"All files are searched for source pattern matches.">;
+ def breakpoint_set_language_exception : Option<"language-exception", "E">,
+ Group<10>, Arg<"Language">, Required,
+ Desc<"Set the breakpoint on exceptions thrown by the specified language "
+ "(without options, on throw but not catch.)">;
+ def breakpoint_set_on_throw : Option<"on-throw", "w">, Group<10>,
+ Arg<"Boolean">, Desc<"Set the breakpoint on exception throW.">;
+ def breakpoint_set_on_catch : Option<"on-catch", "h">, Group<10>,
+ Arg<"Boolean">, Desc<"Set the breakpoint on exception catcH.">;
+ def breakpoint_set_language : Option<"language", "L">, GroupRange<3, 8>,
+ Arg<"Language">,
+ Desc<"Specifies the Language to use when interpreting the breakpoint's "
+ "expression (note: currently only implemented for setting breakpoints on "
+ "identifiers). If not set the target.language setting is used.">;
+ def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">,
+ Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>,
+ Desc<"sKip the prologue if the breakpoint is at the beginning of a "
+ "function. If not set the target.skip-prologue setting is used.">;
+ def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">,
+ Arg<"BreakpointName">,
+ Desc<"Adds this to the list of names for this breakpoint.">;
+ def breakpoint_set_address_slide : Option<"address-slide", "R">,
+ Arg<"Address">, Groups<[1,3,4,5,6,7,8]>,
+ Desc<"Add the specified offset to whatever address(es) the breakpoint "
+ "resolves to. At present this applies the offset directly as given, and "
+ "doesn't try to align it to instruction boundaries.">;
+ def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">,
+ Groups<[1, 9]>, Arg<"Boolean">,
+ Desc<"Move breakpoints to nearest code. If not set the "
+ "target.move-to-nearest-codesetting is used.">;
+ /* Don't add this option till it actually does something useful...
+ def breakpoint_set_exception_typename : Option<"exception-typename", "O">,
+ Arg<"TypeName">, Desc<"The breakpoint will only stop if an "
+ "exception Object of this type is thrown. Can be repeated multiple times "
+ "to stop for multiple object types">;
+ */
+}
+
+let Command = "breakpoint clear" in {
+ def breakpoint_clear_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Completion<"SourceFile">,
+ Desc<"Specify the breakpoint by source location in this particular file.">;
+ def breakpoint_clear_line : Option<"line", "l">, Group<1>, Arg<"LineNum">,
+ Required,
+ Desc<"Specify the breakpoint by source location at this particular line.">;
+}
+
+let Command = "breakpoint delete" in {
+ def breakpoint_delete_force : Option<"force", "f">, Group<1>,
+ Desc<"Delete all breakpoints without querying for confirmation.">;
+ def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
+ Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
+ "file is provided, which prime new targets.">;
+}
+
+let Command = "breakpoint name" in {
+ def breakpoint_name_name : Option<"name", "N">, Group<1>,
+ Arg<"BreakpointName">, Desc<"Specifies a breakpoint name to use.">;
+ def breakpoint_name_breakpoint_id : Option<"breakpoint-id", "B">, Group<2>,
+ Arg<"BreakpointID">, Desc<"Specify a breakpoint ID to use.">;
+ def breakpoint_name_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
+ Group<3>, Desc<"Operate on Dummy breakpoints - i.e. breakpoints set before "
+ "a file is provided, which prime new targets.">;
+ def breakpoint_name_help_string : Option<"help-string", "H">, Group<4>,
+ Arg<"None">, Desc<"A help string describing the purpose of this name.">;
+}
+
+let Command = "breakpoint access" in {
+ def breakpoint_access_allow_list : Option<"allow-list", "L">, Group<1>,
+ Arg<"Boolean">, Desc<"Determines whether the breakpoint will show up in "
+ "break list if not referred to explicitly.">;
+ def breakpoint_access_allow_disable : Option<"allow-disable", "A">, Group<2>,
+ Arg<"Boolean">, Desc<"Determines whether the breakpoint can be disabled by "
+ "name or when all breakpoints are disabled.">;
+ def breakpoint_access_allow_delete : Option<"allow-delete", "D">, Group<3>,
+ Arg<"Boolean">, Desc<"Determines whether the breakpoint can be deleted by "
+ "name or when all breakpoints are deleted.">;
+}
+
+let Command = "breakpoint read" in {
+ def breakpoint_read_file : Option<"file", "f">, Arg<"Filename">, Required,
+ Completion<"DiskFile">,
+ Desc<"The file from which to read the breakpoints.">;
+ def breakpoint_read_breakpoint_name : Option<"breakpoint-name", "N">,
+ Arg<"BreakpointName">, Desc<"Only read in breakpoints with this name.">;
+}
+
+let Command = "breakpoint write" in {
+ def breakpoint_write_file : Option<"file", "f">, Arg<"Filename">, Required,
+ Completion<"DiskFile">,
+ Desc<"The file into which to write the breakpoints.">;
+ def breakpoint_write_append : Option<"append", "a">,
+ Desc<"Append to saved breakpoints file if it exists.">;
+}
+
+let Command = "breakpoint command add" in {
+ def breakpoint_add_one_liner : Option<"one-liner", "o">, Group<1>,
+ Arg<"OneLiner">, Desc<"Specify a one-line breakpoint command inline. Be "
+ "sure to surround it with quotes.">;
+ def breakpoint_add_stop_on_error : Option<"stop-on-error", "e">,
+ Arg<"Boolean">, Desc<"Specify whether breakpoint command execution should "
+ "terminate on error.">;
+ def breakpoint_add_script_type : Option<"script-type", "s">,
+ EnumArg<"None", "ScriptOptionEnum()">,
+ Desc<"Specify the language for the commands - if none is specified, the "
+ "lldb command interpreter will be used.">;
+ def breakpoint_add_python_function : Option<"python-function", "F">,
+ Group<2>, Arg<"PythonFunction">,
+ Desc<"Give the name of a Python function to run as command for this "
+ "breakpoint. Be sure to give a module name if appropriate.">;
+ def breakpoint_add_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
+ Desc<"Sets Dummy breakpoints - i.e. breakpoints set before a file is "
+ "provided, which prime new targets.">;
+}
+
+let Command = "breakpoint command delete" in {
+ def breakpoint_command_delete_dummy_breakpoints :
+ Option<"dummy-breakpoints", "D">, Group<1>,
+ Desc<"Delete commands from Dummy breakpoints - i.e. breakpoints set before "
+ "a file is provided, which prime new targets.">;
+}
+
+let Command = "disassemble" in {
+ def disassemble_options_bytes : Option<"bytes", "b">,
+ Desc<"Show opcode bytes when disassembling.">;
+ def disassemble_options_context : Option<"context", "C">, Arg<"NumLines">,
+ Desc<"Number of context lines of source to show.">;
+ def disassemble_options_mixed : Option<"mixed", "m">,
+ Desc<"Enable mixed source and assembly display.">;
+ def disassemble_options_raw : Option<"raw", "r">,
+ Desc<"Print raw disassembly with no symbol information.">;
+ def disassemble_options_plugin : Option<"plugin", "P">, Arg<"Plugin">,
+ Desc<"Name of the disassembler plugin you want to use.">;
+ def disassemble_options_flavor : Option<"flavor", "F">,
+ Arg<"DisassemblyFlavor">, Desc<"Name of the disassembly flavor you want to "
+ "use. Currently the only valid options are default, and for Intel "
+ "architectures, att and intel.">;
+ def disassemble_options_arch : Option<"arch", "A">, Arg<"Architecture">,
+ Desc<"Specify the architecture to use from cross disassembly.">;
+ def disassemble_options_start_address : Option<"start-address", "s">,
+ Groups<[1,2]>, Arg<"AddressOrExpression">, Required,
+ Desc<"Address at which to start disassembling.">;
+ def disassemble_options_end_address : Option<"end-address", "e">, Group<1>,
+ Arg<"AddressOrExpression">, Desc<"Address at which to end disassembling.">;
+ def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5]>,
+ Arg<"NumLines">, Desc<"Number of instructions to display.">;
+ def disassemble_options_name : Option<"name", "n">, Group<3>,
+ Arg<"FunctionName">, Completion<"Symbol">,
+ Desc<"Disassemble entire contents of the given function name.">;
+ def disassemble_options_frame : Option<"frame", "f">, Group<4>,
+ Desc<"Disassemble from the start of the current frame's function.">;
+ def disassemble_options_pc : Option<"pc", "p">, Group<5>,
+ Desc<"Disassemble around the current pc.">;
+ def disassemble_options_line : Option<"line", "l">, Group<6>,
+ Desc<"Disassemble the current frame's current source line instructions if"
+ "there is debug line table information, else disassemble around the pc.">;
+ def disassemble_options_address : Option<"address", "a">, Group<7>,
+ Arg<"AddressOrExpression">,
+ Desc<"Disassemble function containing this address.">;
+}
+
+let Command = "expression" in {
+ def expression_options_all_threads : Option<"all-threads", "a">,
+ Groups<[1,2]>, Arg<"Boolean">, Desc<"Should we run all threads if the "
+ "execution doesn't complete on one thread.">;
+ def expression_options_ignore_breakpoints : Option<"ignore-breakpoints", "i">,
+ Groups<[1,2]>, Arg<"Boolean">,
+ Desc<"Ignore breakpoint hits while running expressions">;
+ def expression_options_timeout : Option<"timeout", "t">, Groups<[1,2]>,
+ Arg<"UnsignedInteger">,
+ Desc<"Timeout value (in microseconds) for running the expression.">;
+ def expression_options_unwind_on_error : Option<"unwind-on-error", "u">,
+ Groups<[1,2]>, Arg<"Boolean">,
+ Desc<"Clean up program state if the expression causes a crash, or raises a "
+ "signal. Note, unlike gdb hitting a breakpoint is controlled by another "
+ "option (-i).">;
+ def expression_options_debug : Option<"debug", "g">, Groups<[1,2]>,
+ Desc<"When specified, debug the JIT code by setting a breakpoint on the "
+ "first instruction and forcing breakpoints to not be ignored (-i0) and no "
+ "unwinding to happen on error (-u0).">;
+ def expression_options_language : Option<"language", "l">, Groups<[1,2]>,
+ Arg<"Language">, Desc<"Specifies the Language to use when parsing the "
+ "expression. If not set the target.language setting is used.">;
+ def expression_options_apply_fixits : Option<"apply-fixits", "X">,
+ Groups<[1,2]>, Arg<"Language">, Desc<"If true, simple fix-it hints will be "
+ "automatically applied to the expression.">;
+ def expression_options_description_verbosity :
+ Option<"description-verbosity", "v">, Group<1>,
+ OptionalEnumArg<"DescriptionVerbosity", "DescriptionVerbosityTypes()">,
+ Desc<"How verbose should the output of this expression be, if the object "
+ "description is asked for.">;
+ def expression_options_top_level : Option<"top-level", "p">, Groups<[1,2]>,
+ Desc<"Interpret the expression as a complete translation unit, without "
+ "injecting it into the local context. Allows declaration of persistent, "
+ "top-level entities without a $ prefix.">;
+ def expression_options_allow_jit : Option<"allow-jit", "j">, Groups<[1,2]>,
+ Arg<"Boolean">,
+ Desc<"Controls whether the expression can fall back to being JITted if it's"
+ "not supported by the interpreter (defaults to true).">;
+}
+
+let Command = "frame diag" in {
+ def frame_diag_register : Option<"register", "r">, Group<1>,
+ Arg<"RegisterName">, Desc<"A register to diagnose.">;
+ def frame_diag_address : Option<"address", "a">, Group<1>, Arg<"Address">,
+ Desc<"An address to diagnose.">;
+ def frame_diag_offset : Option<"offset", "o">, Group<1>, Arg<"Offset">,
+ Desc<"An optional offset. Requires --register.">;
+}
+
+let Command = "frame select" in {
+ def frame_select_relative : Option<"relative", "r">, Group<1>, Arg<"Offset">,
+ Desc<"A relative frame index offset from the current frame index.">;
+}
+
+let Command = "frame recognizer add" in {
+ def frame_recognizer_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
+ Completion<"Module">,
+ Desc<"Name of the module or shared library that this recognizer applies "
+ "to.">;
+ def frame_recognizer_function : Option<"function", "n">, Arg<"Name">,
+ Completion<"Symbol">,
+ Desc<"Name of the function that this recognizer applies to.">;
+ def frame_recognizer_python_class : Option<"python-class", "l">, Group<2>,
+ Arg<"PythonClass">,
+ Desc<"Give the name of a Python class to use for this frame recognizer.">;
+ def frame_recognizer_regex : Option<"regex", "x">,
+ Desc<"Function name and module name are actually regular expressions.">;
+}
+
+let Command = "history" in {
+ def history_count : Option<"count", "c">, Group<1>, Arg<"UnsignedInteger">,
+ Desc<"How many history commands to print.">;
+ def history_start_index : Option<"start-index", "s">, Group<1>,
+ Arg<"UnsignedInteger">, Desc<"Index at which to start printing history "
+ "commands (or end to mean tail mode).">;
+ def history_end_index : Option<"end-index", "e">, Group<1>,
+ Arg<"UnsignedInteger">,
+ Desc<"Index at which to stop printing history commands.">;
+ def history_clear : Option<"clear", "C">, Group<2>,
+ Desc<"Clears the current command history.">;
+}
+
+let Command = "log" in {
+ def log_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Desc<"Set the destination file to log to.">;
+ def log_threadsafe : Option<"threadsafe", "t">, Group<1>,
+ Desc<"Enable thread safe logging to avoid interweaved log lines.">;
+ def log_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Enable verbose logging.">;
+ def log_sequence : Option<"sequence", "s">, Group<1>,
+ Desc<"Prepend all log lines with an increasing integer sequence id.">;
+ def log_timestamp : Option<"timestamp", "T">, Group<1>,
+ Desc<"Prepend all log lines with a timestamp.">;
+ def log_pid_tid : Option<"pid-tid", "p">, Group<1>,
+ Desc<"Prepend all log lines with the process and thread ID that generates "
+ "the log line.">;
+ def log_thread_name : Option<"thread-name", "n">, Group<1>,
+ Desc<"Prepend all log lines with the thread name for the thread that "
+ "generates the log line.">;
+
+ def log_stack : Option<"stack", "S">, Group<1>,
+ Desc<"Append a stack backtrace to each log line.">;
+ def log_append : Option<"append", "a">, Group<1>,
+ Desc<"Append to the log file instead of overwriting.">;
+ def log_file_function : Option<"file-function", "F">, Group<1>,
+ Desc<"Prepend the names of files and function that generate the logs.">;
+}
+
+let Command = "reproducer" in {
+ def reproducer_provider : Option<"provider", "p">, Group<1>,
+ EnumArg<"None", "ReproducerProviderType()">,
+ Required, Desc<"The reproducer provider to dump.">;
+ def reproducer_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Desc<"The reproducer path. If a reproducer is replayed and no path is "
+ "provided, that reproducer is dumped.">;
+}
+
+let Command = "memory read" in {
+ def memory_read_num_per_line : Option<"num-per-line", "l">, Group<1>,
+ Arg<"NumberPerLine">, Desc<"The number of items per line to display.">;
+ def memory_read_binary : Option<"binary", "b">, Group<2>,
+ Desc<"If true, memory will be saved as binary. If false, the memory is "
+ "saved save as an ASCII dump that uses the format, size, count and number "
+ "per line settings.">;
+ def memory_read_type : Option<"type", "t">, Groups<[3,4]>, Arg<"Name">,
+ Required, Desc<"The name of a type to view memory as.">;
+ def memory_read_language : Option<"language", "x">, Group<4>, Arg<"Language">,
+ Desc<"The language of the type to view memory as.">;
+ def memory_read_offset : Option<"offset", "E">, Group<3>, Arg<"Count">,
+ Desc<"How many elements of the specified type to skip before starting to "
+ "display data.">;
+ def memory_read_force : Option<"force", "r">, Groups<[1,2,3]>,
+ Desc<"Necessary if reading over target.max-memory-read-size bytes.">;
+}
+
+let Command = "memory find" in {
+ def memory_find_expression : Option<"expression", "e">, Group<1>,
+ Arg<"Expression">, Required,
+ Desc<"Evaluate an expression to obtain a byte pattern.">;
+ def memory_find_string : Option<"string", "s">, Group<2>, Arg<"Name">,
+ Required, Desc<"Use text to find a byte pattern.">;
+ def memory_find_count : Option<"count", "c">, Arg<"Count">,
+ Desc<"How many times to perform the search.">;
+ def memory_find_dump_offset : Option<"dump-offset", "o">, Arg<"Offset">,
+ Desc<"When dumping memory for a match, an offset from the match location to"
+ " start dumping from.">;
+}
+
+let Command = "memory write" in {
+ def memory_write_infile : Option<"infile", "i">, Group<1>, Arg<"Filename">,
+ Required, Desc<"Write memory using the contents of a file.">;
+ def memory_write_offset : Option<"offset", "o">, Group<1>, Arg<"Offset">,
+ Desc<"Start writing bytes from an offset within the input file.">;
+}
+
+let Command = "register read" in {
+ def register_read_alternate : Option<"alternate", "A">,
+ Desc<"Display register names using the alternate register name if there "
+ "is one.">;
+ def register_read_set : Option<"set", "s">, Group<1>, Arg<"Index">,
+ Desc<"Specify which register sets to dump by index.">;
+ def register_read_all : Option<"all", "a">, Group<2>,
+ Desc<"Show all register sets.">;
+}
+
+let Command = "source" in {
+ def source_stop_on_error : Option<"stop-on-error", "e">, Arg<"Boolean">,
+ Desc<"If true, stop executing commands on error.">;
+ def source_stop_on_continue : Option<"stop-on-continue", "c">, Arg<"Boolean">,
+ Desc<"If true, stop executing commands on continue.">;
+ def source_silent_run : Option<"silent-run", "s">, Arg<"Boolean">,
+ Desc<"If true don't echo commands while executing.">;
+}
+
+let Command = "alias" in {
+ def alias_help : Option<"help", "h">, Arg<"HelpText">,
+ Desc<"Help text for this command">;
+ def alias_long_help : Option<"long-help", "H">, Arg<"HelpText">,
+ Desc<"Long help text for this command">;
+}
+
+let Command = "regex" in {
+ def regex_help : Option<"help", "h">, Group<1>, Arg<"None">,
+ Desc<"The help text to display for this command.">;
+ def regex_syntax : Option<"syntax", "s">, Group<1>, Arg<"None">,
+ Desc<"A syntax string showing the typical usage syntax.">;
+}
+
+let Command = "permissions" in {
+ def permissions_permissions_value : Option<"permissions-value", "v">,
+ Arg<"PermissionsNumber">,
+ Desc<"Give out the numeric value for permissions (e.g. 757)">;
+ def permissions_permissions_string : Option<"permissions-string", "s">,
+ Arg<"PermissionsString">,
+ Desc<"Give out the string value for permissions (e.g. rwxr-xr--).">;
+ def permissions_user_read : Option<"user-read", "r">,
+ Desc<"Allow user to read.">;
+ def permissions_user_write : Option<"user-write", "w">,
+ Desc<"Allow user to write.">;
+ def permissions_user_exec : Option<"user-exec", "x">,
+ Desc<"Allow user to execute.">;
+ def permissions_group_read : Option<"group-read", "R">,
+ Desc<"Allow group to read.">;
+ def permissions_group_write : Option<"group-write", "W">,
+ Desc<"Allow group to write.">;
+ def permissions_group_exec : Option<"group-exec", "X">,
+ Desc<"Allow group to execute.">;
+ def permissions_world_read : Option<"world-read", "d">,
+ Desc<"Allow world to read.">;
+ def permissions_world_write : Option<"world-write", "t">,
+ Desc<"Allow world to write.">;
+ def permissions_world_exec : Option<"world-exec", "e">,
+ Desc<"Allow world to execute.">;
+}
+
+let Command = "platform fread" in {
+ def platform_fread_offset : Option<"offset", "o">, Group<1>, Arg<"Index">,
+ Desc<"Offset into the file at which to start reading.">;
+ def platform_fread_count : Option<"count", "c">, Group<1>, Arg<"Count">,
+ Desc<"Number of bytes to read from the file.">;
+}
+
+let Command = "platform fwrite" in {
+ def platform_fwrite_offset : Option<"offset", "o">, Group<1>, Arg<"Index">,
+ Desc<"Offset into the file at which to start reading.">;
+ def platform_fwrite_data : Option<"data", "d">, Group<1>, Arg<"Value">,
+ Desc<"Text to write to the file.">;
+}
+
+let Command = "platform process list" in {
+ def platform_process_list_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">,
+ Desc<"List the process info for a specific process ID.">;
+ def platform_process_list_name : Option<"name", "n">, Group<2>,
+ Arg<"ProcessName">, Required,
+ Desc<"Find processes with executable basenames that match a string.">;
+ def platform_process_list_ends_with : Option<"ends-with", "e">, Group<3>,
+ Arg<"ProcessName">, Required,
+ Desc<"Find processes with executable basenames that end with a string.">;
+ def platform_process_list_starts_with : Option<"starts-with", "s">, Group<4>,
+ Arg<"ProcessName">, Required,
+ Desc<"Find processes with executable basenames that start with a string.">;
+ def platform_process_list_contains : Option<"contains", "c">, Group<5>,
+ Arg<"ProcessName">, Required,
+ Desc<"Find processes with executable basenames that contain a string.">;
+ def platform_process_list_regex : Option<"regex", "r">, Group<6>,
+ Arg<"RegularExpression">, Required,
+ Desc<"Find processes with executable basenames that match a regular "
+ "expression.">;
+ def platform_process_list_parent : Option<"parent", "P">, GroupRange<2, 6>,
+ Arg<"Pid">, Desc<"Find processes that have a matching parent process ID.">;
+ def platform_process_list_uid : Option<"uid", "u">, GroupRange<2, 6>,
+ Arg<"UnsignedInteger">, Validator<"&posix_validator">,
+ Desc<"Find processes that have a matching user ID.">;
+ def platform_process_list_euid : Option<"euid", "U">, GroupRange<2, 6>,
+ Arg<"UnsignedInteger">, Validator<"&posix_validator">,
+ Desc<"Find processes that have a matching effective user ID.">;
+ def platform_process_list_gid : Option<"gid", "g">, GroupRange<2, 6>,
+ Arg<"UnsignedInteger">, Validator<"&posix_validator">,
+ Desc<"Find processes that have a matching group ID.">;
+ def platform_process_list_egid : Option<"egid", "G">, GroupRange<2, 6>,
+ Arg<"UnsignedInteger">, Validator<"&posix_validator">,
+ Desc<"Find processes that have a matching effective group ID.">;
+ def platform_process_list_arch : Option<"arch", "a">, GroupRange<2, 6>,
+ Arg<"Architecture">,
+ Desc<"Find processes that have a matching architecture.">;
+ def platform_process_list_show_args : Option<"show-args", "A">,
+ GroupRange<1, 6>,
+ Desc<"Show process arguments instead of the process executable basename.">;
+ def platform_process_list_all_users: Option<"all-users", "x">,
+ GroupRange<1,6>,
+ Desc<"Show processes matching all user IDs.">;
+ def platform_process_list_verbose : Option<"verbose", "v">, GroupRange<1, 6>,
+ Desc<"Enable verbose output.">;
+}
+
+let Command = "platform process attach" in {
+ def platform_process_attach_plugin : Option<"plugin", "P">, Arg<"Plugin">,
+ Desc<"Name of the process plugin you want to use.">;
+ def platform_process_attach_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">,
+ Desc<"The process ID of an existing process to attach to.">;
+ def platform_process_attach_name : Option<"name", "n">, Group<2>,
+ Arg<"ProcessName">, Desc<"The name of the process to attach to.">;
+ def platform_process_attach_waitfor : Option<"waitfor", "w">, Group<2>,
+ Desc<"Wait for the process with <process-name> to launch.">;
+}
+
+let Command = "platform shell" in {
+ def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">,
+ Desc<"Seconds to wait for the remote host to finish running the command.">;
+}
+
+let Command = "process attach" in {
+ def process_attach_continue : Option<"continue", "c">,
+ Desc<"Immediately continue the process once attached.">;
+ def process_attach_plugin : Option<"plugin", "P">, Arg<"Plugin">,
+ Desc<"Name of the process plugin you want to use.">;
+ def process_attach_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">,
+ Desc<"The process ID of an existing process to attach to.">;
+ def process_attach_name : Option<"name", "n">, Group<2>, Arg<"ProcessName">,
+ Desc<"The name of the process to attach to.">;
+ def process_attach_include_existing : Option<"include-existing", "i">,
+ Group<2>, Desc<"Include existing processes when doing attach -w.">;
+ def process_attach_waitfor : Option<"waitfor", "w">, Group<2>,
+ Desc<"Wait for the process with <process-name> to launch.">;
+}
+
+let Command = "process continue" in {
+ def process_continue_ignore_count : Option<"ignore-count", "i">,
+ Arg<"UnsignedInteger">, Desc<"Ignore <N> crossings of the breakpoint (if it"
+ " exists) for the currently selected thread.">;
+}
+
+let Command = "process detach" in {
+ def process_detach_keep_stopped : Option<"keep-stopped", "s">, Group<1>,
+ Arg<"Boolean">, Desc<"Whether or not the process should be kept stopped on"
+ " detach (if possible).">;
+}
+
+let Command = "process connect" in {
+ def process_connect_plugin : Option<"plugin", "p">, Arg<"Plugin">,
+ Desc<"Name of the process plugin you want to use.">;
+}
+
+let Command = "process load" in {
+ def process_load_install : Option<"install", "i">, OptionalArg<"Path">,
+ Desc<"Install the shared library to the target. If specified without an "
+ "argument then the library will installed in the current working "
+ "directory.">;
+}
+
+let Command = "process handle" in {
+ def process_handle_stop : Option<"stop", "s">, Group<1>, Arg<"Boolean">,
+ Desc<"Whether or not the process should be stopped if the signal is "
+ "received.">;
+ def process_handle_notify : Option<"notify", "n">, Group<1>, Arg<"Boolean">,
+ Desc<"Whether or not the debugger should notify the user if the signal is "
+ "received.">;
+ def process_handle_pass : Option<"pass", "p">, Group<1>, Arg<"Boolean">,
+ Desc<"Whether or not the signal should be passed to the process.">;
+}
+
+let Command = "script import" in {
+ def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>,
+ Desc<"Allow the script to be loaded even if it was already loaded before. "
+ "This argument exists for backwards compatibility, but reloading is always "
+ "allowed, whether you specify it or not.">;
+}
+
+let Command = "script add" in {
+ def script_add_function : Option<"function", "f">, Group<1>,
+ Arg<"PythonFunction">,
+ Desc<"Name of the Python function to bind to this command name.">;
+ def script_add_class : Option<"class", "c">, Group<2>, Arg<"PythonClass">,
+ Desc<"Name of the Python class to bind to this command name.">;
+ def script_add_help : Option<"help", "h">, Group<1>, Arg<"HelpText">,
+ Desc<"The help text to display for this command.">;
+ def script_add_synchronicity : Option<"synchronicity", "s">,
+ EnumArg<"ScriptedCommandSynchronicity", "ScriptSynchroType()">,
+ Desc<"Set the synchronicity of this command's executions with regard to "
+ "LLDB event system.">;
+}
+let Command = "source info" in {
+ def source_info_count : Option<"count", "c">, Arg<"Count">,
+ Desc<"The number of line entries to display.">;
+ def source_info_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">,
+ Completion<"Module">, Desc<"Look up the source in the given module or "
+ "shared library (can be specified more than once).">;
+ def source_info_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Completion<"SourceFile">, Desc<"The file from which to display source.">;
+ def source_info_line : Option<"line", "l">, Group<1>, Arg<"LineNum">,
+ Desc<"The line number at which to start the displaying lines.">;
+ def source_info_end_line : Option<"end-line", "e">, Group<1>, Arg<"LineNum">,
+ Desc<"The line number at which to stop displaying lines.">;
+ def source_info_name : Option<"name", "n">, Group<2>, Arg<"Symbol">,
+ Completion<"Symbol">,
+ Desc<"The name of a function whose source to display.">;
+ def source_info_address : Option<"address", "a">, Group<3>,
+ Arg<"AddressOrExpression">, Desc<"Lookup the address and display the source"
+ " information for the corresponding file and line.">;
+}
+
+let Command = "source list" in {
+ def source_list_count : Option<"count", "c">, Arg<"Count">,
+ Desc<"The number of source lines to display.">;
+ def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">,
+ Completion<"Module">,
+ Desc<"Look up the source file in the given shared library.">;
+ def source_list_show_breakpoints : Option<"show-breakpoints", "b">,
+ Desc<"Show the line table locations from the debug information that "
+ "indicate valid places to set source level breakpoints.">;
+ def source_list_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Completion<"SourceFile">, Desc<"The file from which to display source.">;
+ def source_list_line : Option<"line", "l">, Group<1>, Arg<"LineNum">,
+ Desc<"The line number at which to start the display source.">;
+ def source_list_name : Option<"name", "n">, Group<2>, Arg<"Symbol">,
+ Completion<"Symbol">,
+ Desc<"The name of a function whose source to display.">;
+ def source_list_address : Option<"address", "a">, Group<3>,
+ Arg<"AddressOrExpression">, Desc<"Lookup the address and display the source"
+ " information for the corresponding file and line.">;
+ def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the"
+ " listing to look backwards from the last displayed block of source.">;
+}
+
+let Command = "target dependents" in {
+ def dependents_no_dependents : Option<"no-dependents", "d">, Group<1>,
+ OptionalEnumArg<"Value", "OptionEnumValues(g_dependents_enumaration)">,
+ Desc<"Whether or not to load dependents when creating a target. If the "
+ "option is not specified, the value is implicitly 'default'. If the "
+ "option is specified but without a value, the value is implicitly "
+ "'true'.">;
+}
+
+let Command = "target modules dump" in {
+ def target_modules_dump_verbose : Option<"verbose", "v">,
+ Desc<"Enable verbose dump.">;
+}
+
+let Command = "target modules list" in {
+ def target_modules_list_address : Option<"address", "a">, Group<1>,
+ Arg<"AddressOrExpression">, Desc<"Display the image at this address.">;
+ def target_modules_list_arch : Option<"arch", "A">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the architecture when listing images.">;
+ def target_modules_list_triple : Option<"triple", "t">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the triple when listing images.">;
+ def target_modules_list_header : Option<"header", "h">, Group<1>,
+ Desc<"Display the image base address as a load address if debugging, a file"
+ " address otherwise.">;
+ def target_modules_list_offset : Option<"offset", "o">, Group<1>,
+ Desc<"Display the image load address offset from the base file address "
+ "(the slide amount).">;
+ def target_modules_list_uuid : Option<"uuid", "u">, Group<1>,
+ Desc<"Display the UUID when listing images.">;
+ def target_modules_list_fullpath : Option<"fullpath", "f">, Group<1>,
+ OptionalArg<"Width">,
+ Desc<"Display the fullpath to the image object file.">;
+ def target_modules_list_directory : Option<"directory", "d">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the directory with optional width for "
+ "the image object file.">;
+ def target_modules_list_basename : Option<"basename", "b">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the basename with optional width for "
+ "the image object file.">;
+ def target_modules_list_symfile : Option<"symfile", "s">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the fullpath to the image symbol file "
+ "with optional width.">;
+ def target_modules_list_symfile_unique : Option<"symfile-unique", "S">,
+ Group<1>, OptionalArg<"Width">, Desc<"Display the symbol file with optional"
+ " width only if it is different from the executable object file.">;
+ def target_modules_list_mod_time : Option<"mod-time", "m">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the modification time with optional "
+ "width of the module.">;
+ def target_modules_list_ref_count : Option<"ref-count", "r">, Group<1>,
+ OptionalArg<"Width">, Desc<"Display the reference count if the module is "
+ "still in the shared module cache.">;
+ def target_modules_list_pointer : Option<"pointer", "p">, Group<1>,
+ OptionalArg<"None">, Desc<"Display the module pointer.">;
+ def target_modules_list_global : Option<"global", "g">, Group<1>,
+ Desc<"Display the modules from the global module list, not just the "
+ "current target.">;
+}
+
+let Command = "target modules show unwind" in {
+ def target_modules_show_unwind_name : Option<"name", "n">, Group<1>,
+ Arg<"FunctionName">,
+ Desc<"Show unwind instructions for a function or symbol name.">;
+ def target_modules_show_unwind_address : Option<"address", "a">, Group<2>,
+ Arg<"AddressOrExpression">, Desc<"Show unwind instructions for a function "
+ "or symbol containing an address">;
+}
+
+let Command = "target modules lookup" in {
+ def target_modules_lookup_address : Option<"address", "a">, Group<1>,
+ Arg<"AddressOrExpression">, Required, Desc<"Lookup an address in one or "
+ "more target modules.">;
+ def target_modules_lookup_offset : Option<"offset", "o">, Group<1>,
+ Arg<"Offset">, Desc<"When looking up an address subtract <offset> from any "
+ "addresses before doing the lookup.">;
+ // FIXME: re-enable regex for types when the LookupTypeInModule actually uses
+ // the regex option by adding to group 6.
+ def target_modules_lookup_regex : Option<"regex", "r">, Groups<[2,4,5]>,
+ Desc<"The <name> argument for name lookups are regular expressions.">;
+ def target_modules_lookup_symbol : Option<"symbol", "s">, Group<2>,
+ Arg<"Symbol">, Required, Desc<"Lookup a symbol by name in the symbol tables"
+ " in one or more target modules.">;
+ def target_modules_lookup_file : Option<"file", "f">, Group<3>,
+ Arg<"Filename">, Required, Desc<"Lookup a file by fullpath or basename in "
+ "one or more target modules.">;
+ def target_modules_lookup_line : Option<"line", "l">, Group<3>,
+ Arg<"LineNum">, Desc<"Lookup a line number in a file (must be used in "
+ "conjunction with --file).">;
+ def target_modules_lookup_no_inlines : Option<"no-inlines", "i">,
+ GroupRange<3,5>,
+ Desc<"Ignore inline entries (must be used in conjunction with --file or "
+ "--function).">;
+ def target_modules_lookup_function : Option<"function", "F">, Group<4>,
+ Arg<"FunctionName">, Required, Desc<"Lookup a function by name in the debug"
+ " symbols in one or more target modules.">;
+ def target_modules_lookup_name : Option<"name", "n">, Group<5>,
+ Arg<"FunctionOrSymbol">, Required, Desc<"Lookup a function or symbol by "
+ "name in one or more target modules.">;
+ def target_modules_lookup_type : Option<"type", "t">, Group<6>, Arg<"Name">,
+ Required, Desc<"Lookup a type by name in the debug symbols in one or more "
+ "target modules.">;
+ def target_modules_lookup_verbose : Option<"verbose", "v">,
+ Desc<"Enable verbose lookup information.">;
+ def target_modules_lookup_all : Option<"all", "A">, Desc<"Print all matches, "
+ "not just the best match, if a best match is available.">;
+}
+
+let Command = "target stop hook add" in {
+ def target_stop_hook_add_one_liner : Option<"one-liner", "o">,
+ Arg<"OneLiner">, Desc<"Add a command for the stop hook. Can be specified "
+ "more than once, and commands will be run in the order they appear.">;
+ def target_stop_hook_add_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
+ Completion<"Module">,
+ Desc<"Set the module within which the stop-hook is to be run.">;
+ def target_stop_hook_add_thread_index : Option<"thread-index", "x">,
+ Arg<"ThreadIndex">, Desc<"The stop hook is run only for the thread whose "
+ "index matches this argument.">;
+ def target_stop_hook_add_thread_id : Option<"thread-id", "t">,
+ Arg<"ThreadID">, Desc<"The stop hook is run only for the thread whose TID "
+ "matches this argument.">;
+ def target_stop_hook_add_thread_name : Option<"thread-name", "T">,
+ Arg<"ThreadName">, Desc<"The stop hook is run only for the thread whose "
+ "thread name matches this argument.">;
+ def target_stop_hook_add_queue_name : Option<"queue-name", "q">,
+ Arg<"QueueName">, Desc<"The stop hook is run only for threads in the queue "
+ "whose name is given by this argument.">;
+ def target_stop_hook_add_file : Option<"file", "f">, Group<1>,
+ Arg<"Filename">, Desc<"Specify the source file within which the stop-hook "
+ "is to be run.">, Completion<"SourceFile">;
+ def target_stop_hook_add_start_line : Option<"start-line", "l">, Group<1>,
+ Arg<"LineNum">, Desc<"Set the start of the line range for which the "
+ "stop-hook is to be run.">;
+ def target_stop_hook_add_end_line : Option<"end-line", "e">, Group<1>,
+ Arg<"LineNum">, Desc<"Set the end of the line range for which the stop-hook"
+ " is to be run.">;
+ def target_stop_hook_add_classname : Option<"classname", "c">, Group<2>,
+ Arg<"ClassName">,
+ Desc<"Specify the class within which the stop-hook is to be run.">;
+ def target_stop_hook_add_name : Option<"name", "n">, Group<3>,
+ Arg<"FunctionName">, Desc<"Set the function name within which the stop hook"
+ " will be run.">, Completion<"Symbol">;
+ def target_stop_hook_add_auto_continue : Option<"auto-continue", "G">,
+ Arg<"Boolean">, Desc<"The breakpoint will auto-continue after running its"
+ " commands.">;
+}
+
let Command = "thread backtrace" in {
def thread_backtrace_count : Option<"count", "c">, Group<1>, Arg<"Count">,
Desc<"How many frames to display (-1 for all)">;
diff --git a/source/Commands/OptionsBase.td b/source/Commands/OptionsBase.td
index a81563ed28c2..f6967f067bf4 100644
--- a/source/Commands/OptionsBase.td
+++ b/source/Commands/OptionsBase.td
@@ -41,15 +41,19 @@
// - `OptionalArg`: Sets the argument type and marks it as optional.
// - `Arg`: Sets the argument type and marks it as required.
// - `EnumArg`: Sets the argument type to an enum and marks it as required.
+// - `OptionalEnumArg`: Same as EnumArg but marks it as optional.
// See argument_type field for more info.
////////////////////////////////////////////////////////////////////////////////
// Field: validator
// Default value: 0 (No validator for option)
-// Set by: Nothing. This is currently only set after initialization in LLDB.
+// Set by:
+// - `Validator`: Sets the value to a given validator (which has to exist in
+// the surrounding code.
////////////////////////////////////////////////////////////////////////////////
// Field: enum_values
// Default value: {} (No enum associated with this option)
// Set by:
+// - `OptionalEnumArg`:
// - `EnumArg`: Sets the argument type and assigns it a enum holding the valid
// values. The enum needs to be a variable in the including code.
// Marks the option as required (see option_has_arg).
@@ -82,12 +86,14 @@
// Example: def foo : Option<"foo", "f">, Arg<"Pid">;
// Sets the argument type to eArgTypePid and marks option as
// required (see option_has_arg).
+// - `OptionalEnumArg`:
// - `EnumArg`: Sets the argument type and assigns it a enum holding the valid
// values. The enum needs to be a variable in the including code.
// Marks the option as required (see option_has_arg).
// Example: def foo : Option<"foo", "f">,
// EnumArg<"SortOrder",
// "OptionEnumValues(g_sort_option_enumeration)">;
+// Use `OptionalEnumArg` for having an option enum argument.
////////////////////////////////////////////////////////////////////////////////
// Field: usage_text
// Default value: ""
@@ -150,6 +156,13 @@ class EnumArg<string type, string enum> {
string ArgEnum = enum;
}
+// Gives the option an required argument.
+class OptionalEnumArg<string type, string enum> {
+ string ArgType = type;
+ string ArgEnum = enum;
+ bit OptionalArg = 1;
+}
+
// Sets the available completions for the given option.
class Completions<list<string> completions> {
list<string> Completions = completions;
@@ -158,3 +171,8 @@ class Completions<list<string> completions> {
class Completion<string completion> {
list<string> Completions = [completion];
}
+
+// Sets the validator for a given option.
+class Validator<string validator> {
+ string Validator = validator;
+}
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index 0da83eb98edb..a3912bef5a6e 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -261,6 +261,24 @@ bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
return false; // Failed to resolve this address to a section offset value
}
+/// if "addr_range_ptr" is not NULL, then fill in with the address range of the function.
+bool Address::ResolveFunctionScope(SymbolContext &sym_ctx,
+ AddressRange *addr_range_ptr) {
+ constexpr SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ if (!(CalculateSymbolContext(&sym_ctx, resolve_scope) & resolve_scope)) {
+ if (addr_range_ptr)
+ addr_range_ptr->Clear();
+ return false;
+ }
+
+ if (!addr_range_ptr)
+ return true;
+
+ return sym_ctx.GetAddressRange(resolve_scope, 0, false, *addr_range_ptr);
+}
+
ModuleSP Address::GetModule() const {
lldb::ModuleSP module_sp;
SectionSP section_sp(GetSection());
@@ -475,23 +493,19 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
switch (sect_type) {
case eSectionTypeData:
if (module_sp) {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab) {
- const addr_t file_Addr = GetFileAddress();
- Symbol *symbol =
- symtab->FindSymbolContainingFileAddress(file_Addr);
- if (symbol) {
- const char *symbol_name = symbol->GetName().AsCString();
- if (symbol_name) {
- s->PutCString(symbol_name);
- addr_t delta =
- file_Addr - symbol->GetAddressRef().GetFileAddress();
- if (delta)
- s->Printf(" + %" PRIu64, delta);
- showed_info = true;
- }
+ if (Symtab *symtab = module_sp->GetSymtab()) {
+ const addr_t file_Addr = GetFileAddress();
+ Symbol *symbol =
+ symtab->FindSymbolContainingFileAddress(file_Addr);
+ if (symbol) {
+ const char *symbol_name = symbol->GetName().AsCString();
+ if (symbol_name) {
+ s->PutCString(symbol_name);
+ addr_t delta =
+ file_Addr - symbol->GetAddressRef().GetFileAddress();
+ if (delta)
+ s->Printf(" + %" PRIu64, delta);
+ showed_info = true;
}
}
}
@@ -985,10 +999,9 @@ AddressClass Address::GetAddressClass() const {
if (module_sp) {
ObjectFile *obj_file = module_sp->GetObjectFile();
if (obj_file) {
- // Give the symbol vendor a chance to add to the unified section list
- // and to symtab from symbol file
- if (SymbolVendor *vendor = module_sp->GetSymbolVendor())
- vendor->GetSymtab();
+ // Give the symbol file a chance to add to the unified section list
+ // and to the symtab.
+ module_sp->GetSymtab();
return obj_file->GetAddressClass(GetFileAddress());
}
}
diff --git a/source/Core/AddressResolverFileLine.cpp b/source/Core/AddressResolverFileLine.cpp
index 24c0222d6ec2..4a14260c6c72 100644
--- a/source/Core/AddressResolverFileLine.cpp
+++ b/source/Core/AddressResolverFileLine.cpp
@@ -38,8 +38,7 @@ AddressResolverFileLine::~AddressResolverFileLine() {}
Searcher::CallbackReturn
AddressResolverFileLine::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) {
+ SymbolContext &context, Address *addr) {
SymbolContextList sc_list;
uint32_t sc_list_size;
CompileUnit *cu = context.comp_unit;
@@ -60,15 +59,15 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter,
if (log) {
StreamString s;
// new_bp_loc->GetDescription (&s, lldb::eDescriptionLevelVerbose);
- // log->Printf ("Added address: %s\n", s.GetData());
+ // LLDB_LOGF(log, "Added address: %s\n", s.GetData());
}
} else {
- if (log)
- log->Printf(
- "error: Unable to resolve address at file address 0x%" PRIx64
- " for %s:%d\n",
- line_start.GetFileAddress(),
- m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number);
+ LLDB_LOGF(log,
+ "error: Unable to resolve address at file address 0x%" PRIx64
+ " for %s:%d\n",
+ line_start.GetFileAddress(),
+ m_file_spec.GetFilename().AsCString("<Unknown>"),
+ m_line_number);
}
}
}
diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp
index e861368c0a25..6b9b7b2de723 100644
--- a/source/Core/AddressResolverName.cpp
+++ b/source/Core/AddressResolverName.cpp
@@ -36,7 +36,8 @@ AddressResolverName::AddressResolverName(const char *func_name,
: AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
m_regex(), m_match_type(type) {
if (m_match_type == AddressResolver::Regexp) {
- if (!m_regex.Compile(m_func_name.GetStringRef())) {
+ m_regex = RegularExpression(m_func_name.GetStringRef());
+ if (!m_regex.IsValid()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
if (log)
@@ -46,9 +47,9 @@ AddressResolverName::AddressResolverName(const char *func_name,
}
}
-AddressResolverName::AddressResolverName(RegularExpression &func_regex)
+AddressResolverName::AddressResolverName(RegularExpression func_regex)
: AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
- m_regex(func_regex), m_match_type(AddressResolver::Regexp) {}
+ m_regex(std::move(func_regex)), m_match_type(AddressResolver::Regexp) {}
AddressResolverName::AddressResolverName(const char *class_name,
const char *method,
@@ -66,8 +67,7 @@ AddressResolverName::~AddressResolverName() = default;
Searcher::CallbackReturn
AddressResolverName::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) {
+ SymbolContext &context, Address *addr) {
SymbolContextList func_list;
SymbolContextList sym_list;
@@ -86,7 +86,6 @@ AddressResolverName::SearchCallback(SearchFilter &filter,
const bool include_symbols = false;
const bool include_inlines = true;
- const bool append = false;
switch (m_match_type) {
case AddressResolver::Exact:
if (context.module_sp) {
@@ -94,7 +93,7 @@ AddressResolverName::SearchCallback(SearchFilter &filter,
eSymbolTypeCode, sym_list);
context.module_sp->FindFunctions(m_func_name, nullptr,
eFunctionNameTypeAuto, include_symbols,
- include_inlines, append, func_list);
+ include_inlines, func_list);
}
break;
@@ -103,7 +102,7 @@ AddressResolverName::SearchCallback(SearchFilter &filter,
context.module_sp->FindSymbolsMatchingRegExAndType(
m_regex, eSymbolTypeCode, sym_list);
context.module_sp->FindFunctions(m_regex, include_symbols,
- include_inlines, append, func_list);
+ include_inlines, func_list);
}
break;
diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp
index a67cb925d648..0afd897a2093 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -46,9 +46,10 @@ Communication::Communication(const char *name)
m_callback(nullptr), m_callback_baton(nullptr), m_close_on_eof(true)
{
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Communication (name = %s)", this, name);
+
+ LLDB_LOG(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
+ LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::Communication (name = {1})", this, name);
SetEventName(eBroadcastBitDisconnected, "disconnected");
SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
@@ -61,10 +62,10 @@ Communication::Communication(const char *name)
}
Communication::~Communication() {
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::~Communication (name = %s)", this,
- GetBroadcasterName().AsCString());
+ LLDB_LOG(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
+ LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::~Communication (name = {1})", this,
+ GetBroadcasterName().AsCString());
Clear();
}
@@ -77,9 +78,8 @@ void Communication::Clear() {
ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) {
Clear();
- lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Connect (url = %s)",
- this, url);
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::Connect (url = {1})", this, url);
lldb::ConnectionSP connection_sp(m_connection_sp);
if (connection_sp)
@@ -90,8 +90,8 @@ ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) {
}
ConnectionStatus Communication::Disconnect(Status *error_ptr) {
- lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Disconnect ()", this);
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::Disconnect ()", this);
lldb::ConnectionSP connection_sp(m_connection_sp);
if (connection_sp) {
@@ -173,11 +173,10 @@ size_t Communication::Write(const void *src, size_t src_len,
lldb::ConnectionSP connection_sp(m_connection_sp);
std::lock_guard<std::mutex> guard(m_write_mutex);
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Write (src = %p, src_len = %" PRIu64
- ") connection = %p",
- this, src, (uint64_t)src_len, connection_sp.get());
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::Write (src = {1}, src_len = %" PRIu64
+ ") connection = {2}",
+ this, src, (uint64_t)src_len, connection_sp.get());
if (connection_sp)
return connection_sp->Write(src, src_len, status, error_ptr);
@@ -195,8 +194,8 @@ bool Communication::StartReadThread(Status *error_ptr) {
if (m_read_thread.IsJoinable())
return true;
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_COMMUNICATION, "%p Communication::StartReadThread ()", this);
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::StartReadThread ()", this);
char thread_name[1024];
snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>",
@@ -228,8 +227,8 @@ bool Communication::StopReadThread(Status *error_ptr) {
if (!m_read_thread.IsJoinable())
return true;
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_COMMUNICATION, "%p Communication::StopReadThread ()", this);
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::StopReadThread ()", this);
m_read_thread_enabled = false;
@@ -270,11 +269,10 @@ size_t Communication::GetCachedBytes(void *dst, size_t dst_len) {
void Communication::AppendBytesToCache(const uint8_t *bytes, size_t len,
bool broadcast,
ConnectionStatus status) {
- lldb_private::LogIfAnyCategoriesSet(
- LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64
- ", broadcast = %i)",
- this, bytes, (uint64_t)len, broadcast);
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
+ "{0} Communication::AppendBytesToCache (src = {1}, src_len = {2}, "
+ "broadcast = {3})",
+ this, bytes, (uint64_t)len, broadcast);
if ((bytes == nullptr || len == 0) &&
(status != lldb::eConnectionStatusEndOfFile))
return;
@@ -310,8 +308,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
- if (log)
- log->Printf("%p Communication::ReadThread () thread starting...", p);
+ LLDB_LOGF(log, "%p Communication::ReadThread () thread starting...", p);
uint8_t buf[1024];
@@ -366,7 +363,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
}
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION);
if (log)
- log->Printf("%p Communication::ReadThread () thread exiting...", p);
+ LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p);
comm->m_read_thread_did_exit = true;
// Let clients know that this thread is exiting
diff --git a/source/Core/CoreProperties.td b/source/Core/CoreProperties.td
new file mode 100644
index 000000000000..014927c65c6f
--- /dev/null
+++ b/source/Core/CoreProperties.td
@@ -0,0 +1,118 @@
+include "../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "modulelist" in {
+ def EnableExternalLookup: Property<"enable-external-lookup", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"Control the use of external tools and repositories to locate symbol files. Directories listed in target.debug-file-search-paths and directory of the executable are always checked first for separate debug info files. Then depending on this setting: On macOS, Spotlight would be also used to locate a matching .dSYM bundle based on the UUID of the executable. On NetBSD, directory /usr/libdata/debug would be also searched. On platforms other than NetBSD directory /usr/lib/debug would be also searched.">;
+ def ClangModulesCachePath: Property<"clang-modules-cache-path", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"The path to the clang modules cache directory (-fmodules-cache-path).">;
+}
+
+let Definition = "debugger" in {
+ def AutoConfirm: Property<"auto-confirm", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true all confirmation prompts will receive their default reply.">;
+ def DisassemblyFormat: Property<"disassembly-format", "FormatEntity">,
+ Global,
+ DefaultStringValue<"{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${function.changed}\\\\n{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: ">,
+ Desc<"The default disassembly format string to use when disassembling instruction sequences.">;
+ def FrameFormat: Property<"frame-format", "FormatEntity">,
+ Global,
+ DefaultStringValue<"frame #${frame.index}: ${ansi.fg.yellow}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\\\\n">,
+ Desc<"The default frame format string to use when displaying stack frame information for threads.">;
+ def NotiftVoid: Property<"notify-void", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Notify the user explicitly if an expression returns void (default: false).">;
+ def Prompt: Property<"prompt", "String">,
+ Global,
+ DefaultEnumValue<"OptionValueString::eOptionEncodeCharacterEscapeSequences">,
+ DefaultStringValue<"(lldb) ">,
+ Desc<"The debugger command line prompt displayed for the user.">;
+ def ScriptLanguage: Property<"script-lang", "Enum">,
+ Global,
+ DefaultEnumValue<"eScriptLanguagePython">,
+ EnumValues<"OptionEnumValues(g_language_enumerators)">,
+ Desc<"The script language to be used for evaluating user-written scripts.">;
+ def StopDisassemblyCount: Property<"stop-disassembly-count", "SInt64">,
+ Global,
+ DefaultUnsignedValue<4>,
+ Desc<"The number of disassembly lines to show when displaying a stopped context.">;
+ def StopDisassemblyDisplay: Property<"stop-disassembly-display", "Enum">,
+ Global,
+ DefaultEnumValue<"Debugger::eStopDisassemblyTypeNoDebugInfo">,
+ EnumValues<"OptionEnumValues(g_show_disassembly_enum_values)">,
+ Desc<"Control when to display disassembly when displaying a stopped context.">;
+ def StopLineCountAfter: Property<"stop-line-count-after", "SInt64">,
+ Global,
+ DefaultUnsignedValue<3>,
+ Desc<"The number of sources lines to display that come after the current source line when displaying a stopped context.">;
+ def StopLineCountBefore: Property<"stop-line-count-before", "SInt64">,
+ Global,
+ DefaultUnsignedValue<3>,
+ Desc<"The number of sources lines to display that come before the current source line when displaying a stopped context.">;
+ def HighlightSource: Property<"highlight-source", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will highlight the displayed source code.">;
+ def StopShowColumn: Property<"stop-show-column", "Enum">,
+ DefaultEnumValue<"eStopShowColumnAnsiOrCaret">,
+ EnumValues<"OptionEnumValues(s_stop_show_column_values)">,
+ Desc<"If true, LLDB will use the column information from the debug info to mark the current position when displaying a stopped context.">;
+ def StopShowColumnAnsiPrefix: Property<"stop-show-column-ansi-prefix", "String">,
+ Global,
+ DefaultStringValue<"${ansi.underline}">,
+ Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the column to be marked.">;
+ def StopShowColumnAnsiSuffix: Property<"stop-show-column-ansi-suffix", "String">,
+ Global,
+ DefaultStringValue<"${ansi.normal}">,
+ Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">;
+ def TerminalWidth: Property<"term-width", "SInt64">,
+ Global,
+ DefaultUnsignedValue<80>,
+ Desc<"The maximum number of columns to use for displaying text.">;
+ def ThreadFormat: Property<"thread-format", "FormatEntity">,
+ Global,
+ DefaultStringValue<"thread #${thread.index}: tid = ${thread.id%tid}{, ${frame.pc}}{ ${module.file.basename}{`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{, name = ${ansi.fg.green}'${thread.name}'${ansi.normal}}{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}{, activity = ${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}{, ${thread.info.trace_messages} messages}{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}{\\\\nReturn value: ${thread.return-value}}{\\\\nCompleted expression: ${thread.completed-expression}}\\\\n">,
+ Desc<"The default thread format string to use when displaying thread information.">;
+ def ThreadStopFormat: Property<"thread-stop-format", "FormatEntity">,
+ Global,
+ DefaultStringValue<"thread #${thread.index}{, name = '${thread.name}'}{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}{, activity = ${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}{, ${thread.info.trace_messages} messages}{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}{\\\\nReturn value: ${thread.return-value}}{\\\\nCompleted expression: ${thread.completed-expression}}\\\\n">,
+ Desc<"The default thread format string to use when displaying thread information as part of the stop display.">;
+ def UseExternalEditor: Property<"use-external-editor", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Whether to use an external editor or not.">;
+ def UseColor: Property<"use-color", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"Whether to use Ansi color codes or not.">;
+ def AutoOneLineSummaries: Property<"auto-one-line-summaries", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will automatically display small structs in one-liner format (default: true).">;
+ def AutoIndent: Property<"auto-indent", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true).">;
+ def PrintDecls: Property<"print-decls", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true).">;
+ def TabSize: Property<"tab-size", "UInt64">,
+ Global,
+ DefaultUnsignedValue<4>,
+ Desc<"The tab size to use when indenting code in multi-line input mode (default: 4).">;
+ def EscapeNonPrintables: Property<"escape-non-printables", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will automatically escape non-printable and escape characters when formatting strings.">;
+ def FrameFormatUnique: Property<"frame-format-unique", "FormatEntity">,
+ Global,
+ DefaultStringValue<"frame #${frame.index}: ${ansi.fg.yellow}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-without-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\\\\n">,
+ Desc<"The default frame format string to use when displaying stack frameinformation for threads from thread backtrace unique.">;
+}
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 1a69fc582d0c..18397d00dcaa 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -93,22 +93,47 @@ static DebuggerList *g_debugger_list_ptr =
nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = {
- {Debugger::eStopDisassemblyTypeNever, "never",
- "Never show disassembly when displaying a stop context."},
- {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo",
- "Show disassembly when there is no debug information."},
- {Debugger::eStopDisassemblyTypeNoSource, "no-source",
- "Show disassembly when there is no source information, or the source file "
- "is missing when displaying a stop context."},
- {Debugger::eStopDisassemblyTypeAlways, "always",
- "Always show disassembly when displaying a stop context."} };
+ {
+ Debugger::eStopDisassemblyTypeNever,
+ "never",
+ "Never show disassembly when displaying a stop context.",
+ },
+ {
+ Debugger::eStopDisassemblyTypeNoDebugInfo,
+ "no-debuginfo",
+ "Show disassembly when there is no debug information.",
+ },
+ {
+ Debugger::eStopDisassemblyTypeNoSource,
+ "no-source",
+ "Show disassembly when there is no source information, or the source "
+ "file "
+ "is missing when displaying a stop context.",
+ },
+ {
+ Debugger::eStopDisassemblyTypeAlways,
+ "always",
+ "Always show disassembly when displaying a stop context.",
+ },
+};
static constexpr OptionEnumValueElement g_language_enumerators[] = {
- {eScriptLanguageNone, "none", "Disable scripting languages."},
- {eScriptLanguagePython, "python",
- "Select python as the default scripting language."},
- {eScriptLanguageDefault, "default",
- "Select the lldb default as the default scripting language."} };
+ {
+ eScriptLanguageNone,
+ "none",
+ "Disable scripting languages.",
+ },
+ {
+ eScriptLanguagePython,
+ "python",
+ "Select python as the default scripting language.",
+ },
+ {
+ eScriptLanguageDefault,
+ "default",
+ "Select the lldb default as the default scripting language.",
+ },
+};
#define MODULE_WITH_FUNC \
"{ " \
@@ -189,133 +214,39 @@ static constexpr OptionEnumValueElement g_language_enumerators[] = {
// without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
static constexpr OptionEnumValueElement s_stop_show_column_values[] = {
- {eStopShowColumnAnsiOrCaret, "ansi-or-caret",
- "Highlight the stop column with ANSI terminal codes when color/ANSI mode "
- "is enabled; otherwise, fall back to using a text-only caret (^) as if "
- "\"caret-only\" mode was selected."},
- {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI "
- "terminal codes when running LLDB with "
- "color/ANSI enabled."},
- {eStopShowColumnCaret, "caret",
- "Highlight the stop column with a caret character (^) underneath the stop "
- "column. This method introduces a new line in source listings that "
- "display thread stop locations."},
- {eStopShowColumnNone, "none", "Do not highlight the stop column."}};
-
-static constexpr PropertyDefinition g_properties[] = {
- {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, {},
- "If true all confirmation prompts will receive their default reply."},
- {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0,
- DEFAULT_DISASSEMBLY_FORMAT, {},
- "The default disassembly format "
- "string to use when disassembling "
- "instruction sequences."},
- {"frame-format", OptionValue::eTypeFormatEntity, true, 0,
- DEFAULT_FRAME_FORMAT, {},
- "The default frame format string to use "
- "when displaying stack frame information "
- "for threads."},
- {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, {},
- "Notify the user explicitly if an expression returns void (default: "
- "false)."},
- {"prompt", OptionValue::eTypeString, true,
- OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", {},
- "The debugger command line prompt displayed for the user."},
- {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython,
- nullptr, OptionEnumValues(g_language_enumerators),
- "The script language to be used for evaluating user-written scripts."},
- {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, {},
- "The number of disassembly lines to show when displaying a "
- "stopped context."},
- {"stop-disassembly-display", OptionValue::eTypeEnum, true,
- Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr,
- OptionEnumValues(g_show_disassembly_enum_values),
- "Control when to display disassembly when displaying a stopped context."},
- {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, {},
- "The number of sources lines to display that come after the "
- "current source line when displaying a stopped context."},
- {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, {},
- "The number of sources lines to display that come before the "
- "current source line when displaying a stopped context."},
- {"highlight-source", OptionValue::eTypeBoolean, true, true, nullptr, {},
- "If true, LLDB will highlight the displayed source code."},
- {"stop-show-column", OptionValue::eTypeEnum, false,
- eStopShowColumnAnsiOrCaret, nullptr, OptionEnumValues(s_stop_show_column_values),
- "If true, LLDB will use the column information from the debug info to "
- "mark the current position when displaying a stopped context."},
- {"stop-show-column-ansi-prefix", OptionValue::eTypeString, true, 0,
- "${ansi.underline}", {},
- "When displaying the column marker in a color-enabled (i.e. ANSI) "
- "terminal, use the ANSI terminal code specified in this format at the "
- "immediately before the column to be marked."},
- {"stop-show-column-ansi-suffix", OptionValue::eTypeString, true, 0,
- "${ansi.normal}", {},
- "When displaying the column marker in a color-enabled (i.e. ANSI) "
- "terminal, use the ANSI terminal code specified in this format "
- "immediately after the column to be marked."},
- {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, {},
- "The maximum number of columns to use for displaying text."},
- {"thread-format", OptionValue::eTypeFormatEntity, true, 0,
- DEFAULT_THREAD_FORMAT, {},
- "The default thread format string to use "
- "when displaying thread information."},
- {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0,
- DEFAULT_THREAD_STOP_FORMAT, {},
- "The default thread format "
- "string to use when displaying thread "
- "information as part of the stop display."},
- {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, {},
- "Whether to use an external editor or not."},
- {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, {},
- "Whether to use Ansi color codes or not."},
- {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr,
- {},
- "If true, LLDB will automatically display small structs in "
- "one-liner format (default: true)."},
- {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, {},
- "If true, LLDB will auto indent/outdent code. Currently only supported in "
- "the REPL (default: true)."},
- {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, {},
- "If true, LLDB will print the values of variables declared in an "
- "expression. Currently only supported in the REPL (default: true)."},
- {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, {},
- "The tab size to use when indenting code in multi-line input mode "
- "(default: 4)."},
- {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr,
- {},
- "If true, LLDB will automatically escape non-printable and "
- "escape characters when formatting strings."},
- {"frame-format-unique", OptionValue::eTypeFormatEntity, true, 0,
- DEFAULT_FRAME_FORMAT_NO_ARGS, {},
- "The default frame format string to use when displaying stack frame"
- "information for threads from thread backtrace unique."}};
+ {
+ eStopShowColumnAnsiOrCaret,
+ "ansi-or-caret",
+ "Highlight the stop column with ANSI terminal codes when color/ANSI "
+ "mode is enabled; otherwise, fall back to using a text-only caret (^) "
+ "as if \"caret-only\" mode was selected.",
+ },
+ {
+ eStopShowColumnAnsi,
+ "ansi",
+ "Highlight the stop column with ANSI terminal codes when running LLDB "
+ "with color/ANSI enabled.",
+ },
+ {
+ eStopShowColumnCaret,
+ "caret",
+ "Highlight the stop column with a caret character (^) underneath the "
+ "stop column. This method introduces a new line in source listings "
+ "that display thread stop locations.",
+ },
+ {
+ eStopShowColumnNone,
+ "none",
+ "Do not highlight the stop column.",
+ },
+};
+
+#define LLDB_PROPERTIES_debugger
+#include "CoreProperties.inc"
enum {
- ePropertyAutoConfirm = 0,
- ePropertyDisassemblyFormat,
- ePropertyFrameFormat,
- ePropertyNotiftVoid,
- ePropertyPrompt,
- ePropertyScriptLanguage,
- ePropertyStopDisassemblyCount,
- ePropertyStopDisassemblyDisplay,
- ePropertyStopLineCountAfter,
- ePropertyStopLineCountBefore,
- ePropertyHighlightSource,
- ePropertyStopShowColumn,
- ePropertyStopShowColumnAnsiPrefix,
- ePropertyStopShowColumnAnsiSuffix,
- ePropertyTerminalWidth,
- ePropertyThreadFormat,
- ePropertyThreadStopFormat,
- ePropertyUseExternalEditor,
- ePropertyUseColor,
- ePropertyAutoOneLineSummaries,
- ePropertyAutoIndent,
- ePropertyPrintDecls,
- ePropertyTabSize,
- ePropertyEscapeNonPrintables,
- ePropertyFrameFormatUnique,
+#define LLDB_PROPERTIES_debugger
+#include "CorePropertiesEnum.inc"
};
LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
@@ -324,8 +255,16 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
VarSetOperationType op,
llvm::StringRef property_path,
llvm::StringRef value) {
- bool is_load_script = (property_path == "target.load-script-from-symbol-file");
- bool is_escape_non_printables = (property_path == "escape-non-printables");
+ bool is_load_script =
+ (property_path == "target.load-script-from-symbol-file");
+ // These properties might change how we visualize data.
+ bool invalidate_data_vis = (property_path == "escape-non-printables");
+ invalidate_data_vis |=
+ (property_path == "target.max-zero-padding-in-float-format");
+ if (invalidate_data_vis) {
+ DataVisualization::ForceUpdate();
+ }
+
TargetSP target_sp;
LoadScriptFromSymFile load_script_old_value;
if (is_load_script && exe_ctx->GetTargetSP()) {
@@ -336,18 +275,18 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
if (error.Success()) {
// FIXME it would be nice to have "on-change" callbacks for properties
- if (property_path == g_properties[ePropertyPrompt].name) {
+ if (property_path == g_debugger_properties[ePropertyPrompt].name) {
llvm::StringRef new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes(
+ std::string str = lldb_private::ansi::FormatAnsiTerminalCodes(
new_prompt, GetUseColor());
if (str.length())
new_prompt = str;
GetCommandInterpreter().UpdatePrompt(new_prompt);
- auto bytes = llvm::make_unique<EventDataBytes>(new_prompt);
+ auto bytes = std::make_unique<EventDataBytes>(new_prompt);
auto prompt_change_event_sp = std::make_shared<Event>(
CommandInterpreter::eBroadcastBitResetPrompt, bytes.release());
GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
- } else if (property_path == g_properties[ePropertyUseColor].name) {
+ } else if (property_path == g_debugger_properties[ePropertyUseColor].name) {
// use-color changed. Ping the prompt so it can reset the ansi terminal
// codes.
SetPrompt(GetPrompt());
@@ -358,18 +297,14 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
std::list<Status> errors;
StreamString feedback_stream;
if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
- StreamFileSP stream_sp(GetErrorFile());
- if (stream_sp) {
- for (auto error : errors) {
- stream_sp->Printf("%s\n", error.AsCString());
- }
- if (feedback_stream.GetSize())
- stream_sp->PutCString(feedback_stream.GetString());
+ Stream &s = GetErrorStream();
+ for (auto error : errors) {
+ s.Printf("%s\n", error.AsCString());
}
+ if (feedback_stream.GetSize())
+ s.PutCString(feedback_stream.GetString());
}
}
- } else if (is_escape_non_printables) {
- DataVisualization::ForceUpdate();
}
}
return error;
@@ -378,7 +313,7 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
bool Debugger::GetAutoConfirm() const {
const uint32_t idx = ePropertyAutoConfirm;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
}
const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
@@ -399,13 +334,13 @@ const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const {
bool Debugger::GetNotifyVoid() const {
const uint32_t idx = ePropertyNotiftVoid;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
}
llvm::StringRef Debugger::GetPrompt() const {
const uint32_t idx = ePropertyPrompt;
return m_collection_sp->GetPropertyAtIndexAsString(
- nullptr, idx, g_properties[idx].default_cstr_value);
+ nullptr, idx, g_debugger_properties[idx].default_cstr_value);
}
void Debugger::SetPrompt(llvm::StringRef p) {
@@ -413,7 +348,7 @@ void Debugger::SetPrompt(llvm::StringRef p) {
m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
llvm::StringRef new_prompt = GetPrompt();
std::string str =
- lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
+ lldb_private::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
if (str.length())
new_prompt = str;
GetCommandInterpreter().UpdatePrompt(new_prompt);
@@ -437,7 +372,7 @@ const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
const uint32_t idx = ePropertyScriptLanguage;
return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
@@ -449,7 +384,7 @@ bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
uint32_t Debugger::GetTerminalWidth() const {
const uint32_t idx = ePropertyTerminalWidth;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
bool Debugger::SetTerminalWidth(uint32_t term_width) {
@@ -460,7 +395,7 @@ bool Debugger::SetTerminalWidth(uint32_t term_width) {
bool Debugger::GetUseExternalEditor() const {
const uint32_t idx = ePropertyUseExternalEditor;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
}
bool Debugger::SetUseExternalEditor(bool b) {
@@ -471,7 +406,7 @@ bool Debugger::SetUseExternalEditor(bool b) {
bool Debugger::GetUseColor() const {
const uint32_t idx = ePropertyUseColor;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
}
bool Debugger::SetUseColor(bool b) {
@@ -484,13 +419,13 @@ bool Debugger::SetUseColor(bool b) {
bool Debugger::GetHighlightSource() const {
const uint32_t idx = ePropertyHighlightSource;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
StopShowColumn Debugger::GetStopShowColumn() const {
const uint32_t idx = ePropertyStopShowColumn;
return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const {
@@ -507,20 +442,20 @@ uint32_t Debugger::GetStopSourceLineCount(bool before) const {
const uint32_t idx =
before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
const uint32_t idx = ePropertyStopDisassemblyDisplay;
return (Debugger::StopDisassemblyType)
m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
uint32_t Debugger::GetDisassemblyLineCount() const {
const uint32_t idx = ePropertyStopDisassemblyCount;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
bool Debugger::GetAutoOneLineSummaries() const {
@@ -556,7 +491,7 @@ bool Debugger::SetPrintDecls(bool b) {
uint32_t Debugger::GetTabSize() const {
const uint32_t idx = ePropertyTabSize;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_debugger_properties[idx].default_uint_value);
}
bool Debugger::SetTabSize(uint32_t tab_size) {
@@ -717,8 +652,7 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) {
}
}
-DebuggerSP
-Debugger::FindDebuggerWithInstanceName(ConstString instance_name) {
+DebuggerSP Debugger::FindDebuggerWithInstanceName(ConstString instance_name) {
DebuggerSP debugger_sp;
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
@@ -764,16 +698,16 @@ TargetSP Debugger::FindTargetWithProcess(Process *process) {
Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
: UserID(g_unique_id++),
Properties(std::make_shared<OptionValueProperties>()),
- m_input_file_sp(std::make_shared<StreamFile>(stdin, false)),
- m_output_file_sp(std::make_shared<StreamFile>(stdout, false)),
- m_error_file_sp(std::make_shared<StreamFile>(stderr, false)),
+ m_input_file_sp(std::make_shared<NativeFile>(stdin, false)),
+ m_output_stream_sp(std::make_shared<StreamFile>(stdout, false)),
+ m_error_stream_sp(std::make_shared<StreamFile>(stderr, false)),
m_input_recorder(nullptr),
m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
m_terminal_state(), m_target_list(*this), m_platform_list(),
m_listener_sp(Listener::MakeListener("lldb.Debugger")),
m_source_manager_up(), m_source_file_cache(),
m_command_interpreter_up(
- llvm::make_unique<CommandInterpreter>(*this, false)),
+ std::make_unique<CommandInterpreter>(*this, false)),
m_script_interpreter_sp(), m_input_reader_stack(), m_instance_name(),
m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(),
m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
@@ -790,7 +724,10 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
assert(default_platform_sp);
m_platform_list.Append(default_platform_sp, true);
- m_collection_sp->Initialize(g_properties);
+ m_dummy_target_sp = m_target_list.GetDummyTarget(*this);
+ assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?");
+
+ m_collection_sp->Initialize(g_debugger_properties);
m_collection_sp->AppendProperty(
ConstString("target"),
ConstString("Settings specify to debugging targets."), true,
@@ -818,7 +755,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
if (term && !strcmp(term, "dumb"))
SetUseColor(false);
// Turn off use-color if we don't write to a terminal with color support.
- if (!m_output_file_sp->GetFile().GetIsTerminalWithColors())
+ if (!GetOutputFile().GetIsTerminalWithColors())
SetUseColor(false);
#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
@@ -859,8 +796,7 @@ void Debugger::Clear() {
// Close the input file _before_ we close the input read communications
// class as it does NOT own the input file, our m_input_file does.
m_terminal_state.Clear();
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close();
+ GetInputFile().Close();
m_command_interpreter_up->Clear();
});
@@ -885,57 +821,29 @@ void Debugger::SetAsyncExecution(bool async_execution) {
repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; }
-void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership,
- repro::DataRecorder *recorder) {
+void Debugger::SetInputFile(FileSP file_sp, repro::DataRecorder *recorder) {
+ assert(file_sp && file_sp->IsValid());
m_input_recorder = recorder;
- if (m_input_file_sp)
- m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership);
- else
- m_input_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
-
- File &in_file = m_input_file_sp->GetFile();
- if (!in_file.IsValid())
- in_file.SetStream(stdin, true);
-
+ m_input_file_sp = file_sp;
// Save away the terminal state if that is relevant, so that we can restore
// it in RestoreInputState.
SaveInputTerminalState();
}
-void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
- if (m_output_file_sp)
- m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership);
- else
- m_output_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
-
- File &out_file = m_output_file_sp->GetFile();
- if (!out_file.IsValid())
- out_file.SetStream(stdout, false);
-
- // Do not create the ScriptInterpreter just for setting the output file
- // handle as the constructor will know how to do the right thing on its own.
- if (ScriptInterpreter *script_interpreter =
- GetScriptInterpreter(/*can_create=*/false))
- script_interpreter->ResetOutputFileHandle(fh);
+void Debugger::SetOutputFile(FileSP file_sp) {
+ assert(file_sp && file_sp->IsValid());
+ m_output_stream_sp = std::make_shared<StreamFile>(file_sp);
}
-void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) {
- if (m_error_file_sp)
- m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership);
- else
- m_error_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);
-
- File &err_file = m_error_file_sp->GetFile();
- if (!err_file.IsValid())
- err_file.SetStream(stderr, false);
+void Debugger::SetErrorFile(FileSP file_sp) {
+ assert(file_sp && file_sp->IsValid());
+ m_error_stream_sp = std::make_shared<StreamFile>(file_sp);
}
void Debugger::SaveInputTerminalState() {
- if (m_input_file_sp) {
- File &in_file = m_input_file_sp->GetFile();
- if (in_file.GetDescriptor() != File::kInvalidDescriptor)
- m_terminal_state.Save(in_file.GetDescriptor(), true);
- }
+ int fd = GetInputFile().GetDescriptor();
+ if (fd != File::kInvalidDescriptor)
+ m_terminal_state.Save(fd, true);
}
void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
@@ -1016,8 +924,9 @@ bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
}
void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
- lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
- m_input_reader_stack.PrintAsync(stream.get(), s, len);
+ lldb_private::StreamFile &stream =
+ is_stdout ? GetOutputStream() : GetErrorStream();
+ m_input_reader_stack.PrintAsync(&stream, s, len);
}
ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
@@ -1054,8 +963,7 @@ void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
}
}
-void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
- StreamFileSP &out,
+void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out,
StreamFileSP &err) {
// Before an IOHandler runs, it must have in/out/err streams. This function
// is called when one ore more of the streams are nullptr. We use the top
@@ -1065,37 +973,34 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
// If no STDIN has been set, then set it appropriately
- if (!in) {
+ if (!in || !in->IsValid()) {
if (top_reader_sp)
- in = top_reader_sp->GetInputStreamFile();
+ in = top_reader_sp->GetInputFileSP();
else
- in = GetInputFile();
-
+ in = GetInputFileSP();
// If there is nothing, use stdin
if (!in)
- in = std::make_shared<StreamFile>(stdin, false);
+ in = std::make_shared<NativeFile>(stdin, false);
}
// If no STDOUT has been set, then set it appropriately
- if (!out) {
+ if (!out || !out->GetFile().IsValid()) {
if (top_reader_sp)
- out = top_reader_sp->GetOutputStreamFile();
+ out = top_reader_sp->GetOutputStreamFileSP();
else
- out = GetOutputFile();
-
+ out = GetOutputStreamSP();
// If there is nothing, use stdout
if (!out)
out = std::make_shared<StreamFile>(stdout, false);
}
// If no STDERR has been set, then set it appropriately
- if (!err) {
+ if (!err || !err->GetFile().IsValid()) {
if (top_reader_sp)
- err = top_reader_sp->GetErrorStreamFile();
+ err = top_reader_sp->GetErrorStreamFileSP();
else
- err = GetErrorFile();
-
+ err = GetErrorStreamSP();
// If there is nothing, use stderr
if (!err)
- err = std::make_shared<StreamFile>(stdout, false);
+ err = std::make_shared<StreamFile>(stderr, false);
}
}
@@ -1263,15 +1168,15 @@ bool Debugger::EnableLog(llvm::StringRef channel,
LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
} else if (log_file.empty()) {
log_stream_sp = std::make_shared<llvm::raw_fd_ostream>(
- GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered);
+ GetOutputFile().GetDescriptor(), !should_close, unbuffered);
} else {
auto pos = m_log_streams.find(log_file);
if (pos != m_log_streams.end())
log_stream_sp = pos->second.lock();
if (!log_stream_sp) {
- llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text;
+ llvm::sys::fs::OpenFlags flags = llvm::sys::fs::OF_Text;
if (log_options & LLDB_LOG_OPTION_APPEND)
- flags |= llvm::sys::fs::F_Append;
+ flags |= llvm::sys::fs::OF_Append;
int FD;
if (std::error_code ec = llvm::sys::fs::openFileForWrite(
log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) {
@@ -1308,7 +1213,7 @@ ScriptInterpreter *Debugger::GetScriptInterpreter(bool can_create) {
SourceManager &Debugger::GetSourceManager() {
if (!m_source_manager_up)
- m_source_manager_up = llvm::make_unique<SourceManager>(shared_from_this());
+ m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());
return *m_source_manager_up;
}
@@ -1360,60 +1265,23 @@ void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
// }
}
-size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
+void Debugger::FlushProcessOutput(Process &process, bool flush_stdout,
+ bool flush_stderr) {
+ const auto &flush = [&](Stream &stream,
+ size_t (Process::*get)(char *, size_t, Status &)) {
+ Status error;
+ size_t len;
+ char buffer[1024];
+ while ((len = (process.*get)(buffer, sizeof(buffer), error)) > 0)
+ stream.Write(buffer, len);
+ stream.Flush();
+ };
- if (stream) {
- // The process has stuff waiting for stdout; get it and write it out to the
- // appropriate place.
- if (process == nullptr) {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process) {
- Status error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
- }
- return total_bytes;
-}
-
-size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) {
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
-
- if (stream) {
- // The process has stuff waiting for stderr; get it and write it out to the
- // appropriate place.
- if (process == nullptr) {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process) {
- Status error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
- }
- return total_bytes;
+ std::lock_guard<std::mutex> guard(m_output_flush_mutex);
+ if (flush_stdout)
+ flush(*GetAsyncOutputStream(), &Process::GetSTDOUT);
+ if (flush_stderr)
+ flush(*GetAsyncErrorStream(), &Process::GetSTDERR);
}
// This function handles events that were broadcast by the process.
@@ -1453,15 +1321,9 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) {
pop_process_io_handler);
}
- // Now display and STDOUT
- if (got_stdout || got_state_changed) {
- GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
- }
-
- // Now display and STDERR
- if (got_stderr || got_state_changed) {
- GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
- }
+ // Now display STDOUT and STDERR
+ FlushProcessOutput(*process_sp, got_stdout || got_state_changed,
+ got_stderr || got_state_changed);
// Give structured data events an opportunity to display.
if (got_structured_data) {
@@ -1638,8 +1500,9 @@ bool Debugger::StartEventHandlerThread() {
eBroadcastBitEventThreadIsListening);
auto thread_name =
- full_name.GetLength() < llvm::get_max_thread_name_length() ?
- full_name.AsCString() : "dbg.evt-handler";
+ full_name.GetLength() < llvm::get_max_thread_name_length()
+ ? full_name.AsCString()
+ : "dbg.evt-handler";
// Use larger 8MB stack for this thread
llvm::Expected<HostThread> event_handler_thread =
@@ -1700,8 +1563,7 @@ bool Debugger::StartIOHandlerThread() {
void Debugger::StopIOHandlerThread() {
if (m_io_handler_thread.IsJoinable()) {
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close();
+ GetInputFile().Close();
m_io_handler_thread.Join(nullptr);
}
}
@@ -1714,10 +1576,6 @@ void Debugger::JoinIOHandlerThread() {
}
}
-Target *Debugger::GetDummyTarget() {
- return m_target_list.GetDummyTarget(*this).get();
-}
-
Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
Target *target = nullptr;
if (!prefer_dummy) {
@@ -1734,13 +1592,11 @@ Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
FileSpec repl_executable;
if (language == eLanguageTypeUnknown) {
- std::set<LanguageType> repl_languages;
-
- Language::GetLanguagesSupportingREPLs(repl_languages);
+ LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
- if (repl_languages.size() == 1) {
- language = *repl_languages.begin();
- } else if (repl_languages.empty()) {
+ if (auto single_lang = repl_languages.GetSingularLanguage()) {
+ language = *single_lang;
+ } else if (repl_languages.Empty()) {
err.SetErrorStringWithFormat(
"LLDB isn't configured with REPL support for any languages.");
return err;
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index af7cf82d470a..89ae25cbad64 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -158,52 +158,58 @@ size_t Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
return success_count;
}
-bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
- const char *plugin_name, const char *flavor,
- const ExecutionContext &exe_ctx,
- ConstString name, Module *module,
- uint32_t num_instructions,
- bool mixed_source_and_assembly,
- uint32_t num_mixed_context_lines,
- uint32_t options, Stream &strm) {
+bool Disassembler::Disassemble(
+ Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const ExecutionContext &exe_ctx, ConstString name,
+ Module *module, uint32_t num_instructions, bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) {
+ // If no name is given there's nothing to disassemble.
+ if (!name)
+ return false;
+
+ const bool include_symbols = true;
+ const bool include_inlines = true;
+
+ // Find functions matching the given name.
SymbolContextList sc_list;
- if (name) {
- const bool include_symbols = true;
- const bool include_inlines = true;
- if (module) {
- module->FindFunctions(name, nullptr, eFunctionNameTypeAuto,
- include_symbols, include_inlines, true, sc_list);
- } else if (exe_ctx.GetTargetPtr()) {
- exe_ctx.GetTargetPtr()->GetImages().FindFunctions(
- name, eFunctionNameTypeAuto, include_symbols, include_inlines, false,
- sc_list);
- }
+ if (module) {
+ module->FindFunctions(name, nullptr, eFunctionNameTypeAuto, include_symbols,
+ include_inlines, sc_list);
+ } else if (exe_ctx.GetTargetPtr()) {
+ exe_ctx.GetTargetPtr()->GetImages().FindFunctions(
+ name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list);
}
- if (sc_list.GetSize()) {
- return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list,
- num_instructions, mixed_source_and_assembly,
- num_mixed_context_lines, options, strm);
- }
- return false;
+ // If no functions were found there's nothing to disassemble.
+ if (sc_list.IsEmpty())
+ return false;
+
+ return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
lldb::DisassemblerSP Disassembler::DisassembleRange(
const ArchSpec &arch, const char *plugin_name, const char *flavor,
const ExecutionContext &exe_ctx, const AddressRange &range,
bool prefer_file_cache) {
- lldb::DisassemblerSP disasm_sp;
- if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) {
- disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch,
- flavor, plugin_name);
-
- if (disasm_sp) {
- size_t bytes_disassembled = disasm_sp->ParseInstructions(
- &exe_ctx, range, nullptr, prefer_file_cache);
- if (bytes_disassembled == 0)
- disasm_sp.reset();
- }
- }
+ if (range.GetByteSize() <= 0)
+ return {};
+
+ if (!range.GetBaseAddress().IsValid())
+ return {};
+
+ lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget(
+ exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
+
+ if (!disasm_sp)
+ return {};
+
+ const size_t bytes_disassembled =
+ disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ return {};
+
return disasm_sp;
}
@@ -212,20 +218,20 @@ Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
const char *flavor, const Address &start,
const void *src, size_t src_len,
uint32_t num_instructions, bool data_from_file) {
- lldb::DisassemblerSP disasm_sp;
+ if (!src)
+ return {};
- if (src) {
- disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
+ lldb::DisassemblerSP disasm_sp =
+ Disassembler::FindPlugin(arch, flavor, plugin_name);
- if (disasm_sp) {
- DataExtractor data(src, src_len, arch.GetByteOrder(),
- arch.GetAddressByteSize());
+ if (!disasm_sp)
+ return {};
- (void)disasm_sp->DecodeInstructions(start, data, 0, num_instructions,
- false, data_from_file);
- }
- }
+ DataExtractor data(src, src_len, arch.GetByteOrder(),
+ arch.GetAddressByteSize());
+ (void)disasm_sp->DecodeInstructions(start, data, 0, num_instructions, false,
+ data_from_file);
return disasm_sp;
}
@@ -237,27 +243,28 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
bool mixed_source_and_assembly,
uint32_t num_mixed_context_lines,
uint32_t options, Stream &strm) {
- if (disasm_range.GetByteSize()) {
- lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
- exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
-
- if (disasm_sp) {
- AddressRange range;
- ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(),
- range.GetBaseAddress());
- range.SetByteSize(disasm_range.GetByteSize());
- const bool prefer_file_cache = false;
- size_t bytes_disassembled = disasm_sp->ParseInstructions(
- &exe_ctx, range, &strm, prefer_file_cache);
- if (bytes_disassembled == 0)
- return false;
-
- return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
- num_instructions, mixed_source_and_assembly,
- num_mixed_context_lines, options, strm);
- }
- }
- return false;
+ if (!disasm_range.GetByteSize())
+ return false;
+
+ lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
+ exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
+
+ if (!disasm_sp)
+ return false;
+
+ AddressRange range;
+ ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(),
+ range.GetBaseAddress());
+ range.SetByteSize(disasm_range.GetByteSize());
+ const bool prefer_file_cache = false;
+ size_t bytes_disassembled =
+ disasm_sp->ParseInstructions(&exe_ctx, range, &strm, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ return false;
+
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
@@ -268,42 +275,51 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
bool mixed_source_and_assembly,
uint32_t num_mixed_context_lines,
uint32_t options, Stream &strm) {
- if (num_instructions > 0) {
- lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
- exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
- if (disasm_sp) {
- Address addr;
- ResolveAddress(exe_ctx, start_address, addr);
- const bool prefer_file_cache = false;
- size_t bytes_disassembled = disasm_sp->ParseInstructions(
- &exe_ctx, addr, num_instructions, prefer_file_cache);
- if (bytes_disassembled == 0)
- return false;
- return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
- num_instructions, mixed_source_and_assembly,
- num_mixed_context_lines, options, strm);
- }
- }
- return false;
+ if (num_instructions == 0)
+ return false;
+
+ lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
+ exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
+ if (!disasm_sp)
+ return false;
+
+ Address addr;
+ ResolveAddress(exe_ctx, start_address, addr);
+
+ const bool prefer_file_cache = false;
+ size_t bytes_disassembled = disasm_sp->ParseInstructions(
+ &exe_ctx, addr, num_instructions, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ return false;
+
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
Disassembler::SourceLine
Disassembler::GetFunctionDeclLineEntry(const SymbolContext &sc) {
+ if (!sc.function)
+ return {};
+
+ if (!sc.line_entry.IsValid())
+ return {};
+
+ LineEntry prologue_end_line = sc.line_entry;
+ FileSpec func_decl_file;
+ uint32_t func_decl_line;
+ sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line);
+
+ if (func_decl_file != prologue_end_line.file &&
+ func_decl_file != prologue_end_line.original_file)
+ return {};
+
SourceLine decl_line;
- if (sc.function && sc.line_entry.IsValid()) {
- LineEntry prologue_end_line = sc.line_entry;
- FileSpec func_decl_file;
- uint32_t func_decl_line;
- sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line);
- if (func_decl_file == prologue_end_line.file ||
- func_decl_file == prologue_end_line.original_file) {
- decl_line.file = func_decl_file;
- decl_line.line = func_decl_line;
- // TODO do we care about column on these entries? If so, we need to
- // plumb that through GetStartLineSourceInfo.
- decl_line.column = 0;
- }
- }
+ decl_line.file = func_decl_file;
+ decl_line.line = func_decl_line;
+ // TODO: Do we care about column on these entries? If so, we need to plumb
+ // that through GetStartLineSourceInfo.
+ decl_line.column = 0;
return decl_line;
}
@@ -355,12 +371,9 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine(
const char *function_name =
sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments)
.GetCString();
- if (function_name) {
- RegularExpression::Match regex_match(1);
- if (avoid_regex->Execute(function_name, &regex_match)) {
- // skip this source line
- return true;
- }
+ if (function_name && avoid_regex->Execute(function_name)) {
+ // skip this source line
+ return true;
}
}
// don't skip this source line
@@ -793,10 +806,9 @@ OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream,
std::string value;
static RegularExpression g_reg_exp(
llvm::StringRef("^[ \t]*([^ \t]+)[ \t]*$"));
- RegularExpression::Match regex_match(1);
- bool reg_exp_success = g_reg_exp.Execute(line, &regex_match);
- if (reg_exp_success)
- regex_match.GetMatchAtIndex(line.c_str(), 1, value);
+ llvm::SmallVector<llvm::StringRef, 2> matches;
+ if (g_reg_exp.Execute(line, &matches))
+ value = matches[1].str();
else
value = line;
@@ -856,14 +868,15 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) {
if (!line.empty()) {
static RegularExpression g_reg_exp(llvm::StringRef(
"^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"));
- RegularExpression::Match regex_match(2);
- bool reg_exp_success = g_reg_exp.Execute(line, &regex_match);
+ llvm::SmallVector<llvm::StringRef, 3> matches;
+
+ bool reg_exp_success = g_reg_exp.Execute(line, &matches);
std::string key;
std::string value;
if (reg_exp_success) {
- regex_match.GetMatchAtIndex(line.c_str(), 1, key);
- regex_match.GetMatchAtIndex(line.c_str(), 2, value);
+ key = matches[1].str();
+ value = matches[2].str();
} else {
out_stream->Printf("Instruction::ReadDictionary: Failure executing "
"regular expression.\n");
diff --git a/source/Core/DumpDataExtractor.cpp b/source/Core/DumpDataExtractor.cpp
index aa84370e223a..12e98de2675c 100644
--- a/source/Core/DumpDataExtractor.cpp
+++ b/source/Core/DumpDataExtractor.cpp
@@ -14,20 +14,18 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/ModuleList.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/CanonicalType.h"
-
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include <limits>
@@ -64,8 +62,12 @@ static float half2float(uint16_t half) {
return u.f * ldexpf(1, -112);
}
-static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
- lldb::offset_t byte_size, llvm::APInt &result) {
+static llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ lldb::offset_t byte_size) {
+ if (byte_size == 0)
+ return llvm::None;
+
llvm::SmallVector<uint64_t, 2> uint64_array;
lldb::offset_t bytes_left = byte_size;
uint64_t u64;
@@ -81,8 +83,7 @@ static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
}
uint64_array.push_back(u64);
}
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
+ return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
} else if (byte_order == lldb::eByteOrderBig) {
lldb::offset_t be_offset = *offset_ptr + byte_size;
lldb::offset_t temp_offset;
@@ -101,18 +102,17 @@ static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
uint64_array.push_back(u64);
}
*offset_ptr += byte_size;
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
+ return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
}
- return false;
+ return llvm::None;
}
static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
lldb::offset_t offset, lldb::offset_t byte_size,
bool is_signed, unsigned radix) {
- llvm::APInt apint;
- if (GetAPInt(data, &offset, byte_size, apint)) {
- std::string apint_str(apint.toString(radix, is_signed));
+ llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size);
+ if (apint.hasValue()) {
+ std::string apint_str(apint.getValue().toString(radix, is_signed));
switch (radix) {
case 2:
s->Write("0b", 2);
@@ -555,49 +555,31 @@ lldb::offset_t lldb_private::DumpDataExtractor(
if (exe_scope)
target_sp = exe_scope->CalculateTarget();
if (target_sp) {
- ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
- if (clang_ast) {
- clang::ASTContext *ast = clang_ast->getASTContext();
- if (ast) {
- llvm::SmallVector<char, 256> sv;
- // Show full precision when printing float values
- const unsigned format_precision = 0;
- const unsigned format_max_padding = 100;
- size_t item_bit_size = item_byte_size * 8;
-
- if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
- llvm::APInt apint(item_bit_size,
- DE.GetMaxU64(&offset, item_byte_size));
- llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
- apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
- llvm::APInt apint;
- if (GetAPInt(DE, &offset, item_byte_size, apint)) {
- llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
- apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
- } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
- const auto &semantics =
- ast->getFloatTypeSemantics(ast->LongDoubleTy);
-
- offset_t byte_size = item_byte_size;
- if (&semantics == &llvm::APFloatBase::x87DoubleExtended())
- byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
-
- llvm::APInt apint;
- if (GetAPInt(DE, &offset, byte_size, apint)) {
- llvm::APFloat apfloat(semantics, apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
- } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
- llvm::APInt apint(item_bit_size, DE.GetU16(&offset));
- llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
- apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
-
+ auto type_system_or_err =
+ target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (!type_system_or_err) {
+ llvm::consumeError(type_system_or_err.takeError());
+ } else {
+ auto &type_system = *type_system_or_err;
+ llvm::SmallVector<char, 256> sv;
+ // Show full precision when printing float values
+ const unsigned format_precision = 0;
+ const unsigned format_max_padding =
+ target_sp->GetMaxZeroPaddingInFloatFormat();
+
+ const auto &semantics =
+ type_system.GetFloatTypeSemantics(item_byte_size);
+
+ // Recalculate the byte size in case of a difference. This is possible
+ // when item_byte_size is 16 (128-bit), because you could get back the
+ // x87DoubleExtended semantics which has a byte size of 10 (80-bit).
+ const size_t semantics_byte_size =
+ (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
+ llvm::Optional<llvm::APInt> apint =
+ GetAPInt(DE, &offset, semantics_byte_size);
+ if (apint.hasValue()) {
+ llvm::APFloat apfloat(semantics, apint.getValue());
+ apfloat.toString(sv, format_precision, format_max_padding);
if (!sv.empty()) {
s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
used_upfloat = true;
diff --git a/source/Core/FileLineResolver.cpp b/source/Core/FileLineResolver.cpp
index 3cba1c7e8143..01df295398a8 100644
--- a/source/Core/FileLineResolver.cpp
+++ b/source/Core/FileLineResolver.cpp
@@ -33,7 +33,7 @@ FileLineResolver::~FileLineResolver() {}
Searcher::CallbackReturn
FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context,
- Address *addr, bool containing) {
+ Address *addr) {
CompileUnit *cu = context.comp_unit;
if (m_inlines ||
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
index 1ffbed2cd64e..c90828f40989 100644
--- a/source/Core/FormatEntity.cpp
+++ b/source/Core/FormatEntity.cpp
@@ -514,24 +514,24 @@ static bool ScanBracketedRange(llvm::StringRef subpath,
close_bracket_index = llvm::StringRef::npos;
const size_t open_bracket_index = subpath.find('[');
if (open_bracket_index == llvm::StringRef::npos) {
- if (log)
- log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ LLDB_LOGF(log,
+ "[ScanBracketedRange] no bracketed range, skipping entirely");
return false;
}
close_bracket_index = subpath.find(']', open_bracket_index + 1);
if (close_bracket_index == llvm::StringRef::npos) {
- if (log)
- log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ LLDB_LOGF(log,
+ "[ScanBracketedRange] no bracketed range, skipping entirely");
return false;
} else {
var_name_final_if_array_range = subpath.data() + open_bracket_index;
if (close_bracket_index - open_bracket_index == 1) {
- if (log)
- log->Printf(
- "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
+ LLDB_LOGF(
+ log,
+ "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
index_lower = 0;
} else {
const size_t separator_index = subpath.find('-', open_bracket_index + 1);
@@ -540,22 +540,21 @@ static bool ScanBracketedRange(llvm::StringRef subpath,
const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
index_higher = index_lower;
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64
- "] detected, high index is same",
- index_lower);
+ LLDB_LOGF(log,
+ "[ScanBracketedRange] [%" PRId64
+ "] detected, high index is same",
+ index_lower);
} else {
const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
const char *index_higher_cstr = subpath.data() + separator_index + 1;
index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
index_higher = ::strtoul(index_higher_cstr, nullptr, 0);
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected",
- index_lower, index_higher);
+ LLDB_LOGF(log,
+ "[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected",
+ index_lower, index_higher);
}
if (index_lower > index_higher && index_higher > 0) {
- if (log)
- log->Printf("[ScanBracketedRange] swapping indices");
+ LLDB_LOGF(log, "[ScanBracketedRange] swapping indices");
const int64_t temp = index_lower;
index_lower = index_higher;
index_higher = temp;
@@ -627,9 +626,8 @@ static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index,
const char *ptr_deref_format = "[%d]";
std::string ptr_deref_buffer(10, 0);
::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
- if (log)
- log->Printf("[ExpandIndexedExpression] name to deref: %s",
- ptr_deref_buffer.c_str());
+ LLDB_LOGF(log, "[ExpandIndexedExpression] name to deref: %s",
+ ptr_deref_buffer.c_str());
ValueObject::GetValueForExpressionPathOptions options;
ValueObject::ExpressionPathEndResultType final_value_type;
ValueObject::ExpressionPathScanEndReason reason_to_stop;
@@ -640,15 +638,15 @@ static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index,
ptr_deref_buffer.c_str(), &reason_to_stop, &final_value_type, options,
&what_next);
if (!item) {
- if (log)
- log->Printf("[ExpandIndexedExpression] ERROR: why stopping = %d,"
- " final_value_type %d",
- reason_to_stop, final_value_type);
+ LLDB_LOGF(log,
+ "[ExpandIndexedExpression] ERROR: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
} else {
- if (log)
- log->Printf("[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
- " final_value_type %d",
- reason_to_stop, final_value_type);
+ LLDB_LOGF(log,
+ "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
}
return item;
}
@@ -770,9 +768,8 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
const std::string &expr_path = entry.string;
- if (log)
- log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",
- expr_path.c_str());
+ LLDB_LOGF(log, "[Debugger::FormatPrompt] symbol to expand: %s",
+ expr_path.c_str());
target =
valobj
@@ -781,16 +778,16 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
.get();
if (!target) {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: why stopping = %d,"
- " final_value_type %d",
- reason_to_stop, final_value_type);
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
return false;
} else {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
- " final_value_type %d",
- reason_to_stop, final_value_type);
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
target = target
->GetQualifiedRepresentationIfAvailable(
target->GetDynamicValueType(), true)
@@ -814,18 +811,16 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
Status error;
target = target->Dereference(error).get();
if (error.Fail()) {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: %s\n",
- error.AsCString("unknown"));
+ LLDB_LOGF(log, "[Debugger::FormatPrompt] ERROR: %s\n",
+ error.AsCString("unknown"));
return false;
}
do_deref_pointer = false;
}
if (!target) {
- if (log)
- log->Printf("[Debugger::FormatPrompt] could not calculate target for "
- "prompt expression");
+ LLDB_LOGF(log, "[Debugger::FormatPrompt] could not calculate target for "
+ "prompt expression");
return false;
}
@@ -860,18 +855,16 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
// exceptions
{
StreamString str_temp;
- if (log)
- log->Printf(
- "[Debugger::FormatPrompt] I am into array || pointer && !range");
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] I am into array || pointer && !range");
if (target->HasSpecialPrintableRepresentation(val_obj_display,
custom_format)) {
// try to use the special cases
bool success = target->DumpPrintableRepresentation(
str_temp, val_obj_display, custom_format);
- if (log)
- log->Printf("[Debugger::FormatPrompt] special cases did%s match",
- success ? "" : "n't");
+ LLDB_LOGF(log, "[Debugger::FormatPrompt] special cases did%s match",
+ success ? "" : "n't");
// should not happen
if (success)
@@ -909,17 +902,16 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
}
if (!is_array_range) {
- if (log)
- log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] dumping ordinary printable output");
return target->DumpPrintableRepresentation(s, val_obj_display,
custom_format);
} else {
- if (log)
- log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] checking if I can handle as array");
if (!is_array && !is_pointer)
return false;
- if (log)
- log->Printf("[Debugger::FormatPrompt] handle as array");
+ LLDB_LOGF(log, "[Debugger::FormatPrompt] handle as array");
StreamString special_directions_stream;
llvm::StringRef special_directions;
if (close_bracket_index != llvm::StringRef::npos &&
@@ -965,15 +957,15 @@ static bool DumpValue(Stream &s, const SymbolContext *sc,
.get();
if (!item) {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at "
- "index %" PRId64,
- index);
+ LLDB_LOGF(log,
+ "[Debugger::FormatPrompt] ERROR in getting child item at "
+ "index %" PRId64,
+ index);
} else {
- if (log)
- log->Printf(
- "[Debugger::FormatPrompt] special_directions for child item: %s",
- special_directions.data() ? special_directions.data() : "");
+ LLDB_LOGF(
+ log,
+ "[Debugger::FormatPrompt] special_directions for child item: %s",
+ special_directions.data() ? special_directions.data() : "");
}
if (special_directions.empty()) {
@@ -2354,34 +2346,31 @@ static void AddMatches(const FormatEntity::Entry::Definition *def,
}
}
-size_t FormatEntity::AutoComplete(CompletionRequest &request) {
- llvm::StringRef str = request.GetCursorArgumentPrefix().str();
-
- request.SetWordComplete(false);
- str = str.drop_front(request.GetMatchStartPoint());
+void FormatEntity::AutoComplete(CompletionRequest &request) {
+ llvm::StringRef str = request.GetCursorArgumentPrefix();
const size_t dollar_pos = str.rfind('$');
if (dollar_pos == llvm::StringRef::npos)
- return 0;
+ return;
// Hitting TAB after $ at the end of the string add a "{"
if (dollar_pos == str.size() - 1) {
std::string match = str.str();
match.append("{");
request.AddCompletion(match);
- return 1;
+ return;
}
if (str[dollar_pos + 1] != '{')
- return 0;
+ return;
const size_t close_pos = str.find('}', dollar_pos + 2);
if (close_pos != llvm::StringRef::npos)
- return 0;
+ return;
const size_t format_pos = str.find('%', dollar_pos + 2);
if (format_pos != llvm::StringRef::npos)
- return 0;
+ return;
llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
if (partial_variable.empty()) {
@@ -2389,7 +2378,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
StringList new_matches;
AddMatches(&g_root, str, llvm::StringRef(), new_matches);
request.AddCompletions(new_matches);
- return request.GetNumberOfMatches();
+ return;
}
// We have a partially specified variable, find it
@@ -2397,7 +2386,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
const FormatEntity::Entry::Definition *entry_def =
FindEntry(partial_variable, &g_root, remainder);
if (!entry_def)
- return 0;
+ return;
const size_t n = entry_def->num_children;
@@ -2409,7 +2398,6 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
} else {
// "${thread.id" <TAB>
request.AddCompletion(MakeMatch(str, "}"));
- request.SetWordComplete(true);
}
} else if (remainder.equals(".")) {
// "${thread." <TAB>
@@ -2423,5 +2411,4 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) {
AddMatches(entry_def, str, remainder, new_matches);
request.AddCompletions(new_matches);
}
- return request.GetNumberOfMatches();
}
diff --git a/source/Core/Highlighter.cpp b/source/Core/Highlighter.cpp
index 0b0aa969bf65..c3c614aac210 100644
--- a/source/Core/Highlighter.cpp
+++ b/source/Core/Highlighter.cpp
@@ -13,6 +13,7 @@
#include "lldb/Utility/StreamString.h"
using namespace lldb_private;
+using namespace lldb_private::ansi;
void HighlightStyle::ColorStyle::Apply(Stream &s, llvm::StringRef value) const {
s << m_prefix << value << m_suffix;
@@ -20,8 +21,8 @@ void HighlightStyle::ColorStyle::Apply(Stream &s, llvm::StringRef value) const {
void HighlightStyle::ColorStyle::Set(llvm::StringRef prefix,
llvm::StringRef suffix) {
- m_prefix = lldb_utility::ansi::FormatAnsiTerminalCodes(prefix);
- m_suffix = lldb_utility::ansi::FormatAnsiTerminalCodes(suffix);
+ m_prefix = FormatAnsiTerminalCodes(prefix);
+ m_suffix = FormatAnsiTerminalCodes(suffix);
}
void DefaultHighlighter::Highlight(const HighlightStyle &options,
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index b30308490cca..46be29f6fbf9 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -52,7 +52,7 @@
#include "llvm/ADT/StringRef.h"
-#ifdef _MSC_VER
+#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#endif
@@ -70,10 +70,14 @@
using namespace lldb;
using namespace lldb_private;
+using llvm::None;
+using llvm::Optional;
+using llvm::StringRef;
+
IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type)
: IOHandler(debugger, type,
- StreamFileSP(), // Adopt STDIN from top input reader
+ FileSP(), // Adopt STDIN from top input reader
StreamFileSP(), // Adopt STDOUT from top input reader
StreamFileSP(), // Adopt STDERR from top input reader
0, // Flags
@@ -81,7 +85,7 @@ IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type)
) {}
IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type,
- const lldb::StreamFileSP &input_sp,
+ const lldb::FileSP &input_sp,
const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp, uint32_t flags,
repro::DataRecorder *data_recorder)
@@ -98,7 +102,7 @@ IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type,
IOHandler::~IOHandler() = default;
int IOHandler::GetInputFD() {
- return (m_input_sp ? m_input_sp->GetFile().GetDescriptor() : -1);
+ return (m_input_sp ? m_input_sp->GetDescriptor() : -1);
}
int IOHandler::GetOutputFD() {
@@ -110,7 +114,7 @@ int IOHandler::GetErrorFD() {
}
FILE *IOHandler::GetInputFILE() {
- return (m_input_sp ? m_input_sp->GetFile().GetStream() : nullptr);
+ return (m_input_sp ? m_input_sp->GetStream() : nullptr);
}
FILE *IOHandler::GetOutputFILE() {
@@ -121,18 +125,18 @@ FILE *IOHandler::GetErrorFILE() {
return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr);
}
-StreamFileSP &IOHandler::GetInputStreamFile() { return m_input_sp; }
+FileSP &IOHandler::GetInputFileSP() { return m_input_sp; }
-StreamFileSP &IOHandler::GetOutputStreamFile() { return m_output_sp; }
+StreamFileSP &IOHandler::GetOutputStreamFileSP() { return m_output_sp; }
-StreamFileSP &IOHandler::GetErrorStreamFile() { return m_error_sp; }
+StreamFileSP &IOHandler::GetErrorStreamFileSP() { return m_error_sp; }
bool IOHandler::GetIsInteractive() {
- return GetInputStreamFile()->GetFile().GetIsInteractive();
+ return GetInputFileSP() ? GetInputFileSP()->GetIsInteractive() : false;
}
bool IOHandler::GetIsRealTerminal() {
- return GetInputStreamFile()->GetFile().GetIsRealTerminal();
+ return GetInputFileSP() ? GetInputFileSP()->GetIsRealTerminal() : false;
}
void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); }
@@ -170,18 +174,11 @@ IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
IOHandlerConfirm::~IOHandlerConfirm() = default;
-int IOHandlerConfirm::IOHandlerComplete(
- IOHandler &io_handler, const char *current_line, const char *cursor,
- const char *last_char, int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions) {
- if (current_line == cursor) {
- if (m_default_response) {
- matches.AppendString("y");
- } else {
- matches.AppendString("n");
- }
- }
- return matches.GetSize();
+void IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) {
+ if (request.GetRawCursorPos() != 0)
+ return;
+ request.AddCompletion(m_default_response ? "y" : "n");
}
void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
@@ -219,47 +216,20 @@ void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
}
}
-int IOHandlerDelegate::IOHandlerComplete(
- IOHandler &io_handler, const char *current_line, const char *cursor,
- const char *last_char, int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions) {
+void IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) {
switch (m_completion) {
case Completion::None:
break;
-
case Completion::LLDBCommand:
- return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(
- current_line, cursor, last_char, skip_first_n_matches, max_matches,
- matches, descriptions);
- case Completion::Expression: {
- CompletionResult result;
- CompletionRequest request(current_line, current_line - cursor,
- skip_first_n_matches, max_matches, result);
+ io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(request);
+ break;
+ case Completion::Expression:
CommandCompletions::InvokeCommonCompletionCallbacks(
io_handler.GetDebugger().GetCommandInterpreter(),
CommandCompletions::eVariablePathCompletion, request, nullptr);
- result.GetMatches(matches);
- result.GetDescriptions(descriptions);
-
- size_t num_matches = request.GetNumberOfMatches();
- if (num_matches > 0) {
- std::string common_prefix;
- matches.LongestCommonPrefix(common_prefix);
- const size_t partial_name_len = request.GetCursorArgumentPrefix().size();
-
- // If we matched a unique single command, add a space... Only do this if
- // the completer told us this was a complete word, however...
- if (num_matches == 1 && request.GetWordComplete()) {
- common_prefix.push_back(' ');
- }
- common_prefix.erase(0, partial_name_len);
- matches.InsertStringAtIndex(0, std::move(common_prefix));
- }
- return num_matches;
- } break;
+ break;
}
-
- return 0;
}
IOHandlerEditline::IOHandlerEditline(
@@ -269,7 +239,7 @@ IOHandlerEditline::IOHandlerEditline(
bool multi_line, bool color_prompts, uint32_t line_number_start,
IOHandlerDelegate &delegate, repro::DataRecorder *data_recorder)
: IOHandlerEditline(debugger, type,
- StreamFileSP(), // Inherit input from top input reader
+ FileSP(), // Inherit input from top input reader
StreamFileSP(), // Inherit output from top input reader
StreamFileSP(), // Inherit error from top input reader
0, // Flags
@@ -278,9 +248,9 @@ IOHandlerEditline::IOHandlerEditline(
line_number_start, delegate, data_recorder) {}
IOHandlerEditline::IOHandlerEditline(
- Debugger &debugger, IOHandler::Type type,
- const lldb::StreamFileSP &input_sp, const lldb::StreamFileSP &output_sp,
- const lldb::StreamFileSP &error_sp, uint32_t flags,
+ Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp,
+ const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp,
+ uint32_t flags,
const char *editline_name, // Used for saving history files
llvm::StringRef prompt, llvm::StringRef continuation_prompt,
bool multi_line, bool color_prompts, uint32_t line_number_start,
@@ -300,7 +270,8 @@ IOHandlerEditline::IOHandlerEditline(
#ifndef LLDB_DISABLE_LIBEDIT
bool use_editline = false;
- use_editline = m_input_sp->GetFile().GetIsRealTerminal();
+ use_editline = GetInputFILE() && GetOutputFILE() && GetErrorFILE() &&
+ m_input_sp && m_input_sp->GetIsRealTerminal();
if (use_editline) {
m_editline_up.reset(new Editline(editline_name, GetInputFILE(),
@@ -339,92 +310,119 @@ void IOHandlerEditline::Deactivate() {
m_delegate.IOHandlerDeactivated(*this);
}
+// Split out a line from the buffer, if there is a full one to get.
+static Optional<std::string> SplitLine(std::string &line_buffer) {
+ size_t pos = line_buffer.find('\n');
+ if (pos == std::string::npos)
+ return None;
+ std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r");
+ line_buffer = line_buffer.substr(pos + 1);
+ return line;
+}
+
+// If the final line of the file ends without a end-of-line, return
+// it as a line anyway.
+static Optional<std::string> SplitLineEOF(std::string &line_buffer) {
+ if (llvm::all_of(line_buffer, isspace))
+ return None;
+ std::string line = std::move(line_buffer);
+ line_buffer.clear();
+ return line;
+}
+
bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_up) {
bool b = m_editline_up->GetLine(line, interrupted);
- if (m_data_recorder)
+ if (b && m_data_recorder)
m_data_recorder->Record(line, true);
return b;
- } else {
+ }
#endif
- line.clear();
- FILE *in = GetInputFILE();
- if (in) {
- if (GetIsInteractive()) {
- const char *prompt = nullptr;
+ line.clear();
- if (m_multi_line && m_curr_line_idx > 0)
- prompt = GetContinuationPrompt();
+ if (GetIsInteractive()) {
+ const char *prompt = nullptr;
- if (prompt == nullptr)
- prompt = GetPrompt();
+ if (m_multi_line && m_curr_line_idx > 0)
+ prompt = GetContinuationPrompt();
- if (prompt && prompt[0]) {
- FILE *out = GetOutputFILE();
- if (out) {
- ::fprintf(out, "%s", prompt);
- ::fflush(out);
- }
- }
+ if (prompt == nullptr)
+ prompt = GetPrompt();
+
+ if (prompt && prompt[0]) {
+ if (m_output_sp) {
+ m_output_sp->Printf("%s", prompt);
+ m_output_sp->Flush();
}
- char buffer[256];
- bool done = false;
- bool got_line = false;
- m_editing = true;
- while (!done) {
+ }
+ }
+
+ Optional<std::string> got_line = SplitLine(m_line_buffer);
+
+ if (!got_line && !m_input_sp) {
+ // No more input file, we are done...
+ SetIsDone(true);
+ return false;
+ }
+
+ FILE *in = GetInputFILE();
+ char buffer[256];
+
+ if (!got_line && !in && m_input_sp) {
+ // there is no FILE*, fall back on just reading bytes from the stream.
+ while (!got_line) {
+ size_t bytes_read = sizeof(buffer);
+ Status error = m_input_sp->Read((void *)buffer, bytes_read);
+ if (error.Success() && !bytes_read) {
+ got_line = SplitLineEOF(m_line_buffer);
+ break;
+ }
+ if (error.Fail())
+ break;
+ m_line_buffer += StringRef(buffer, bytes_read);
+ got_line = SplitLine(m_line_buffer);
+ }
+ }
+
+ if (!got_line && in) {
+ m_editing = true;
+ while (!got_line) {
+ char *r = fgets(buffer, sizeof(buffer), in);
#ifdef _WIN32
- // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED
- // according to the docs on MSDN. However, this has evidently been a
- // known bug since Windows 8. Therefore, we can't detect if a signal
- // interrupted in the fgets. So pressing ctrl-c causes the repl to end
- // and the process to exit. A temporary workaround is just to attempt to
- // fgets twice until this bug is fixed.
- if (fgets(buffer, sizeof(buffer), in) == nullptr &&
- fgets(buffer, sizeof(buffer), in) == nullptr) {
-#else
- if (fgets(buffer, sizeof(buffer), in) == nullptr) {
+ // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED
+ // according to the docs on MSDN. However, this has evidently been a
+ // known bug since Windows 8. Therefore, we can't detect if a signal
+ // interrupted in the fgets. So pressing ctrl-c causes the repl to end
+ // and the process to exit. A temporary workaround is just to attempt to
+ // fgets twice until this bug is fixed.
+ if (r == nullptr)
+ r = fgets(buffer, sizeof(buffer), in);
+ // this is the equivalent of EINTR for Windows
+ if (r == nullptr && GetLastError() == ERROR_OPERATION_ABORTED)
+ continue;
#endif
- const int saved_errno = errno;
- if (feof(in))
- done = true;
- else if (ferror(in)) {
- if (saved_errno != EINTR)
- done = true;
- }
- } else {
- got_line = true;
- size_t buffer_len = strlen(buffer);
- assert(buffer[buffer_len] == '\0');
- char last_char = buffer[buffer_len - 1];
- if (last_char == '\r' || last_char == '\n') {
- done = true;
- // Strip trailing newlines
- while (last_char == '\r' || last_char == '\n') {
- --buffer_len;
- if (buffer_len == 0)
- break;
- last_char = buffer[buffer_len - 1];
- }
- }
- line.append(buffer, buffer_len);
- }
+ if (r == nullptr) {
+ if (ferror(in) && errno == EINTR)
+ continue;
+ if (feof(in))
+ got_line = SplitLineEOF(m_line_buffer);
+ break;
}
- m_editing = false;
- if (m_data_recorder && got_line)
- m_data_recorder->Record(line, true);
- // We might have gotten a newline on a line by itself make sure to return
- // true in this case.
- return got_line;
- } else {
- // No more input file, we are done...
- SetIsDone(true);
+ m_line_buffer += buffer;
+ got_line = SplitLine(m_line_buffer);
}
- return false;
-#ifndef LLDB_DISABLE_LIBEDIT
+ m_editing = false;
}
-#endif
+
+ if (got_line) {
+ line = got_line.getValue();
+ if (m_data_recorder)
+ m_data_recorder->Record(line, true);
+ }
+
+ return (bool)got_line;
}
#ifndef LLDB_DISABLE_LIBEDIT
@@ -445,16 +443,11 @@ int IOHandlerEditline::FixIndentationCallback(Editline *editline,
*editline_reader, lines, cursor_position);
}
-int IOHandlerEditline::AutoCompleteCallback(
- const char *current_line, const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches, StringList &matches,
- StringList &descriptions, void *baton) {
+void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request,
+ void *baton) {
IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
if (editline_reader)
- return editline_reader->m_delegate.IOHandlerComplete(
- *editline_reader, current_line, cursor, last_char, skip_first_n_matches,
- max_matches, matches, descriptions);
- return 0;
+ editline_reader->m_delegate.IOHandlerComplete(*editline_reader, request);
}
#endif
@@ -526,10 +519,11 @@ bool IOHandlerEditline::GetLines(StringList &lines, bool &interrupted) {
// Show line numbers if we are asked to
std::string line;
if (m_base_line_number > 0 && GetIsInteractive()) {
- FILE *out = GetOutputFILE();
- if (out)
- ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(),
- GetPrompt() == nullptr ? " " : "");
+ if (m_output_sp) {
+ m_output_sp->Printf("%u%s",
+ m_base_line_number + (uint32_t)lines.GetSize(),
+ GetPrompt() == nullptr ? " " : "");
+ }
}
m_curr_line_idx = lines.GetSize();
@@ -615,7 +609,7 @@ void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) {
else
#endif
{
-#ifdef _MSC_VER
+#ifdef _WIN32
const char *prompt = GetPrompt();
if (prompt) {
// Back up over previous prompt using Windows API
@@ -630,9 +624,9 @@ void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) {
}
#endif
IOHandler::PrintAsync(stream, s, len);
-#ifdef _MSC_VER
+#ifdef _WIN32
if (prompt)
- IOHandler::PrintAsync(GetOutputStreamFile().get(), prompt,
+ IOHandler::PrintAsync(GetOutputStreamFileSP().get(), prompt,
strlen(prompt));
#endif
}
@@ -952,16 +946,9 @@ public:
}
void PutChar(int ch) { ::waddch(m_window, ch); }
void PutCString(const char *s, int len = -1) { ::waddnstr(m_window, s, len); }
- void Refresh() { ::wrefresh(m_window); }
- void DeferredRefresh() {
- // We are using panels, so we don't need to call this...
- //::wnoutrefresh(m_window);
- }
void SetBackground(int color_pair_idx) {
::wbkgd(m_window, COLOR_PAIR(color_pair_idx));
}
- void UnderlineOn() { AttributeOn(A_UNDERLINE); }
- void UnderlineOff() { AttributeOff(A_UNDERLINE); }
void PutCStringTruncated(const char *s, int right_pad) {
int bytes_left = GetWidth() - GetCursorX();
@@ -1213,19 +1200,6 @@ public:
return eKeyNotHandled;
}
- bool SetActiveWindow(Window *window) {
- const size_t num_subwindows = m_subwindows.size();
- for (size_t i = 0; i < num_subwindows; ++i) {
- if (m_subwindows[i].get() == window) {
- m_prev_active_window_idx = m_curr_active_window_idx;
- ::top_panel(window->m_panel);
- m_curr_active_window_idx = i;
- return true;
- }
- }
- return false;
- }
-
WindowSP GetActiveWindow() {
if (!m_subwindows.empty()) {
if (m_curr_active_window_idx >= m_subwindows.size()) {
@@ -1257,8 +1231,6 @@ public:
void SetCanBeActive(bool b) { m_can_activate = b; }
- const WindowDelegateSP &GetDelegate() const { return m_delegate_sp; }
-
void SetDelegate(const WindowDelegateSP &delegate_sp) {
m_delegate_sp = delegate_sp;
}
@@ -1410,12 +1382,8 @@ public:
int GetKeyValue() const { return m_key_value; }
- void SetKeyValue(int key_value) { m_key_value = key_value; }
-
std::string &GetName() { return m_name; }
- std::string &GetKeyName() { return m_key_name; }
-
int GetDrawWidth() const {
return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
}
@@ -1569,7 +1537,6 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
menu->DrawMenuTitle(window, false);
}
window.PutCString(" |");
- window.DeferredRefresh();
} break;
case Menu::Type::Item: {
@@ -1592,7 +1559,6 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
submenus[i]->DrawMenuTitle(window, is_selected);
}
window.MoveCursor(cursor_x, cursor_y);
- window.DeferredRefresh();
} break;
default:
@@ -1898,8 +1864,6 @@ public:
return m_window_sp;
}
- WindowDelegates &GetWindowDelegates() { return m_window_delegates; }
-
protected:
WindowSP m_window_sp;
WindowDelegates m_window_delegates;
@@ -1936,9 +1900,7 @@ struct Row {
return 0;
}
- void Expand() {
- expanded = true;
- }
+ void Expand() { expanded = true; }
std::vector<Row> &GetChildren() {
ProcessSP process_sp = value.GetProcessSP();
@@ -2293,8 +2255,6 @@ public:
m_selected_item = nullptr;
}
- window.DeferredRefresh();
-
return true; // Drawing handled
}
@@ -2644,14 +2604,12 @@ protected:
class ValueObjectListDelegate : public WindowDelegate {
public:
ValueObjectListDelegate()
- : m_rows(), m_selected_row(nullptr),
- m_selected_row_idx(0), m_first_visible_row(0), m_num_rows(0),
- m_max_x(0), m_max_y(0) {}
+ : m_rows(), m_selected_row(nullptr), m_selected_row_idx(0),
+ m_first_visible_row(0), m_num_rows(0), m_max_x(0), m_max_y(0) {}
ValueObjectListDelegate(ValueObjectList &valobj_list)
- : m_rows(), m_selected_row(nullptr),
- m_selected_row_idx(0), m_first_visible_row(0), m_num_rows(0),
- m_max_x(0), m_max_y(0) {
+ : m_rows(), m_selected_row(nullptr), m_selected_row_idx(0),
+ m_first_visible_row(0), m_num_rows(0), m_max_x(0), m_max_y(0) {
SetValues(valobj_list);
}
@@ -2694,8 +2652,6 @@ public:
DisplayRows(window, m_rows, g_options);
- window.DeferredRefresh();
-
// Get the selected row
m_selected_row = GetRowForRowIndex(m_selected_row_idx);
// Keep the cursor on the selected row so the highlight and the cursor are
@@ -3800,7 +3756,6 @@ public:
window.Printf(" with status = %i", exit_status);
}
}
- window.DeferredRefresh();
return true;
}
@@ -4258,7 +4213,6 @@ public:
}
}
}
- window.DeferredRefresh();
return true; // Drawing handled
}
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index c6759cc944ca..b06656aa3fb7 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -8,13 +8,6 @@
#include "lldb/Core/Mangled.h"
-#if defined(_WIN32)
-#include "lldb/Host/windows/windows.h"
-
-#include <dbghelp.h>
-#pragma comment(lib, "dbghelp.lib")
-#endif
-
#include "lldb/Core/RichManglingContext.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
@@ -39,25 +32,6 @@
#include <string.h>
using namespace lldb_private;
-#if defined(_MSC_VER)
-static DWORD safeUndecorateName(const char *Mangled, char *Demangled,
- DWORD DemangledLength) {
- static std::mutex M;
- std::lock_guard<std::mutex> Lock(M);
- return ::UnDecorateSymbolName(
- Mangled, Demangled, DemangledLength,
- UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
- // keywords
- UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
- // etc keywords
- UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
- UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc
- // specifiers
- UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
- );
-}
-#endif
-
static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
if (s) {
if (s[0] == '?')
@@ -124,21 +98,6 @@ get_demangled_name_without_arguments(ConstString mangled,
}
#pragma mark Mangled
-// Default constructor
-Mangled::Mangled() : m_mangled(), m_demangled() {}
-
-// Constructor with an optional string and a boolean indicating if it is the
-// mangled version.
-Mangled::Mangled(ConstString s, bool mangled)
- : m_mangled(), m_demangled() {
- if (s)
- SetValue(s, mangled);
-}
-
-Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
- if (!name.empty())
- SetValue(ConstString(name), is_mangled);
-}
Mangled::Mangled(ConstString s) : m_mangled(), m_demangled() {
if (s)
@@ -150,9 +109,6 @@ Mangled::Mangled(llvm::StringRef name) {
SetValue(ConstString(name));
}
-// Destructor
-Mangled::~Mangled() {}
-
// Convert to pointer operator. This allows code to check any Mangled objects
// to see if they contain anything valid using code such as:
//
@@ -218,28 +174,20 @@ void Mangled::SetValue(ConstString name) {
// Local helpers for different demangling implementations.
static char *GetMSVCDemangledStr(const char *M) {
-#if defined(_MSC_VER)
- const size_t demangled_length = 2048;
- char *demangled_cstr = static_cast<char *>(::malloc(demangled_length));
- ::ZeroMemory(demangled_cstr, demangled_length);
- DWORD result = safeUndecorateName(M, demangled_cstr, demangled_length);
+ char *demangled_cstr = llvm::microsoftDemangle(
+ M, nullptr, nullptr, nullptr,
+ llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier |
+ llvm::MSDF_NoCallingConvention |
+ llvm::MSDF_NoMemberType));
if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
if (demangled_cstr && demangled_cstr[0])
- log->Printf("demangled msvc: %s -> \"%s\"", M, demangled_cstr);
+ LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M, demangled_cstr);
else
- log->Printf("demangled msvc: %s -> error: 0x%lu", M, result);
+ LLDB_LOGF(log, "demangled msvc: %s -> error", M);
}
- if (result != 0) {
- return demangled_cstr;
- } else {
- ::free(demangled_cstr);
- return nullptr;
- }
-#else
- return nullptr;
-#endif
+ return demangled_cstr;
}
static char *GetItaniumDemangledStr(const char *M) {
@@ -261,9 +209,9 @@ static char *GetItaniumDemangledStr(const char *M) {
if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
if (demangled_cstr)
- log->Printf("demangled itanium: %s -> \"%s\"", M, demangled_cstr);
+ LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
else
- log->Printf("demangled itanium: %s -> error: failed to demangle", M);
+ LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);
}
return demangled_cstr;
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 153d5a740936..aef3f3e3b4b0 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -137,14 +137,15 @@ Module::Module(const ModuleSpec &module_spec)
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
LIBLLDB_LOG_MODULES));
if (log != nullptr)
- log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
- module_spec.GetArchitecture().GetArchitectureName(),
- module_spec.GetFileSpec().GetPath().c_str(),
- module_spec.GetObjectName().IsEmpty() ? "" : "(",
- module_spec.GetObjectName().IsEmpty()
- ? ""
- : module_spec.GetObjectName().AsCString(""),
- module_spec.GetObjectName().IsEmpty() ? "" : ")");
+ LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
+ static_cast<void *>(this),
+ module_spec.GetArchitecture().GetArchitectureName(),
+ module_spec.GetFileSpec().GetPath().c_str(),
+ module_spec.GetObjectName().IsEmpty() ? "" : "(",
+ module_spec.GetObjectName().IsEmpty()
+ ? ""
+ : module_spec.GetObjectName().AsCString(""),
+ module_spec.GetObjectName().IsEmpty() ? "" : ")");
// First extract all module specifications from the file using the local file
// path. If there are no specifications, then don't fill anything in
@@ -164,7 +165,7 @@ Module::Module(const ModuleSpec &module_spec)
if (!modules_specs.FindMatchingModuleSpec(module_spec,
matching_module_spec)) {
if (log) {
- log->Printf("Found local object file but the specs didn't match");
+ LLDB_LOGF(log, "Found local object file but the specs didn't match");
}
return;
}
@@ -235,11 +236,11 @@ Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
LIBLLDB_LOG_MODULES));
if (log != nullptr)
- log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
- m_arch.GetArchitectureName(), m_file.GetPath().c_str(),
- m_object_name.IsEmpty() ? "" : "(",
- m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
- m_object_name.IsEmpty() ? "" : ")");
+ LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
+ static_cast<void *>(this), m_arch.GetArchitectureName(),
+ m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
+ m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
+ m_object_name.IsEmpty() ? "" : ")");
}
Module::Module()
@@ -267,11 +268,11 @@ Module::~Module() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
LIBLLDB_LOG_MODULES));
if (log != nullptr)
- log->Printf("%p Module::~Module((%s) '%s%s%s%s')",
- static_cast<void *>(this), m_arch.GetArchitectureName(),
- m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
- m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
- m_object_name.IsEmpty() ? "" : ")");
+ LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",
+ static_cast<void *>(this), m_arch.GetArchitectureName(),
+ m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
+ m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
+ m_object_name.IsEmpty() ? "" : ")");
// Release any auto pointers before we start tearing down our member
// variables since the object file and symbol files might need to make
// function calls back into this module object. The ordering is important
@@ -291,7 +292,7 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (process_sp) {
m_did_load_objfile = true;
- auto data_up = llvm::make_unique<DataBufferHeap>(size_to_read, 0);
+ auto data_up = std::make_unique<DataBufferHeap>(size_to_read, 0);
Status readmem_error;
const size_t bytes_read =
process_sp->ReadMemory(header_addr, data_up->GetBytes(),
@@ -352,7 +353,8 @@ void Module::SetUUID(const lldb_private::UUID &uuid) {
}
}
-TypeSystem *Module::GetTypeSystemForLanguage(LanguageType language) {
+llvm::Expected<TypeSystem &>
+Module::GetTypeSystemForLanguage(LanguageType language) {
return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
}
@@ -364,7 +366,7 @@ void Module::ParseAllDebugSymbols() {
SymbolContext sc;
sc.module_sp = shared_from_this();
- SymbolVendor *symbols = GetSymbolVendor();
+ SymbolFile *symbols = GetSymbolFile();
for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
@@ -404,8 +406,7 @@ size_t Module::GetNumCompileUnits() {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Module::GetNumCompileUnits (module = %p)",
static_cast<void *>(this));
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
+ if (SymbolFile *symbols = GetSymbolFile())
return symbols->GetNumCompileUnits();
return 0;
}
@@ -416,8 +417,7 @@ CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
CompUnitSP cu_sp;
if (index < num_comp_units) {
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
+ if (SymbolFile *symbols = GetSymbolFile())
cu_sp = symbols->GetCompileUnitAtIndex(index);
}
return cu_sp;
@@ -455,8 +455,8 @@ uint32_t Module::ResolveSymbolContextForAddress(
sc.module_sp = shared_from_this();
resolved_flags |= eSymbolContextModule;
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (!sym_vendor)
+ SymbolFile *symfile = GetSymbolFile();
+ if (!symfile)
return resolved_flags;
// Resolve the compile unit, function, block, line table or line entry if
@@ -467,14 +467,14 @@ uint32_t Module::ResolveSymbolContextForAddress(
resolve_scope & eSymbolContextLineEntry ||
resolve_scope & eSymbolContextVariable) {
resolved_flags |=
- sym_vendor->ResolveSymbolContext(so_addr, resolve_scope, sc);
+ symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
}
// Resolve the symbol if requested, but don't re-look it up if we've
// already found it.
if (resolve_scope & eSymbolContextSymbol &&
!(resolved_flags & eSymbolContextSymbol)) {
- Symtab *symtab = sym_vendor->GetSymtab();
+ Symtab *symtab = symfile->GetSymtab();
if (symtab && so_addr.IsSectionOffset()) {
Symbol *matching_symbol = nullptr;
@@ -507,18 +507,15 @@ uint32_t Module::ResolveSymbolContextForAddress(
// files on MacOSX have an unstripped symbol table inside of them.
ObjectFile *symtab_objfile = symtab->GetObjectFile();
if (symtab_objfile && symtab_objfile->IsStripped()) {
- SymbolFile *symfile = sym_vendor->GetSymbolFile();
- if (symfile) {
- ObjectFile *symfile_objfile = symfile->GetObjectFile();
- if (symfile_objfile != symtab_objfile) {
- Symtab *symfile_symtab = symfile_objfile->GetSymtab();
- if (symfile_symtab) {
- Symbol *symbol =
- symfile_symtab->FindSymbolContainingFileAddress(
- so_addr.GetFileAddress());
- if (symbol && !symbol->IsSynthetic()) {
- sc.symbol = symbol;
- }
+ ObjectFile *symfile_objfile = symfile->GetObjectFile();
+ if (symfile_objfile != symtab_objfile) {
+ Symtab *symfile_symtab = symfile_objfile->GetSymtab();
+ if (symfile_symtab) {
+ Symbol *symbol =
+ symfile_symtab->FindSymbolContainingFileAddress(
+ so_addr.GetFileAddress());
+ if (symbol && !symbol->IsSynthetic()) {
+ sc.symbol = symbol;
}
}
}
@@ -590,40 +587,29 @@ uint32_t Module::ResolveSymbolContextsForFileSpec(
const uint32_t initial_count = sc_list.GetSize();
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
+ if (SymbolFile *symbols = GetSymbolFile())
symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope,
sc_list);
return sc_list.GetSize() - initial_count;
}
-size_t Module::FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches,
- VariableList &variables) {
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
- return symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches,
- variables);
- return 0;
+void Module::FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, VariableList &variables) {
+ if (SymbolFile *symbols = GetSymbolFile())
+ symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);
}
-size_t Module::FindGlobalVariables(const RegularExpression &regex,
- size_t max_matches,
- VariableList &variables) {
- SymbolVendor *symbols = GetSymbolVendor();
+void Module::FindGlobalVariables(const RegularExpression &regex,
+ size_t max_matches, VariableList &variables) {
+ SymbolFile *symbols = GetSymbolFile();
if (symbols)
- return symbols->FindGlobalVariables(regex, max_matches, variables);
- return 0;
+ symbols->FindGlobalVariables(regex, max_matches, variables);
}
-size_t Module::FindCompileUnits(const FileSpec &path, bool append,
- SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
-
- const size_t start_size = sc_list.GetSize();
+void Module::FindCompileUnits(const FileSpec &path,
+ SymbolContextList &sc_list) {
const size_t num_compile_units = GetNumCompileUnits();
SymbolContext sc;
sc.module_sp = shared_from_this();
@@ -635,7 +621,6 @@ size_t Module::FindCompileUnits(const FileSpec &path, bool append,
sc_list.Append(sc);
}
}
- return sc_list.GetSize() - start_size;
}
Module::LookupInfo::LookupInfo(ConstString name,
@@ -798,18 +783,15 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
}
}
-size_t Module::FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask,
- bool include_symbols, bool include_inlines,
- bool append, SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
-
+void Module::FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask,
+ bool include_symbols, bool include_inlines,
+ SymbolContextList &sc_list) {
const size_t old_size = sc_list.GetSize();
// Find all the functions (not symbols, but debug information functions...
- SymbolVendor *symbols = GetSymbolVendor();
+ SymbolFile *symbols = GetSymbolFile();
if (name_type_mask & eFunctionNameTypeAuto) {
LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
@@ -817,7 +799,7 @@ size_t Module::FindFunctions(ConstString name,
if (symbols) {
symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx,
lookup_info.GetNameTypeMask(), include_inlines,
- append, sc_list);
+ sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
@@ -836,7 +818,7 @@ size_t Module::FindFunctions(ConstString name,
} else {
if (symbols) {
symbols->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
@@ -847,21 +829,15 @@ size_t Module::FindFunctions(ConstString name,
}
}
}
-
- return sc_list.GetSize() - old_size;
}
-size_t Module::FindFunctions(const RegularExpression &regex,
- bool include_symbols, bool include_inlines,
- bool append, SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
-
+void Module::FindFunctions(const RegularExpression &regex, bool include_symbols,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
const size_t start_size = sc_list.GetSize();
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols) {
- symbols->FindFunctions(regex, include_inlines, append, sc_list);
+ if (SymbolFile *symbols = GetSymbolFile()) {
+ symbols->FindFunctions(regex, include_inlines, sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
@@ -923,7 +899,6 @@ size_t Module::FindFunctions(const RegularExpression &regex,
}
}
}
- return sc_list.GetSize() - start_size;
}
void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
@@ -945,57 +920,49 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
}
}
-size_t Module::FindTypes_Impl(
+void Module::FindTypes_Impl(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches,
+ size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
- return symbols->FindTypes(name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types);
- return 0;
+ if (SymbolFile *symbols = GetSymbolFile())
+ symbols->FindTypes(name, parent_decl_ctx, max_matches,
+ searched_symbol_files, types);
}
-size_t Module::FindTypesInNamespace(ConstString type_name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches, TypeList &type_list) {
- const bool append = true;
+void Module::FindTypesInNamespace(ConstString type_name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, TypeList &type_list) {
TypeMap types_map;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- size_t num_types =
- FindTypes_Impl(type_name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types_map);
- if (num_types > 0) {
+ FindTypes_Impl(type_name, parent_decl_ctx, max_matches, searched_symbol_files,
+ types_map);
+ if (types_map.GetSize()) {
SymbolContext sc;
sc.module_sp = shared_from_this();
sc.SortTypeList(types_map, type_list);
}
- return num_types;
}
lldb::TypeSP Module::FindFirstType(const SymbolContext &sc,
ConstString name, bool exact_match) {
TypeList type_list;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- const size_t num_matches =
- FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
- if (num_matches)
+ FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
+ if (type_list.GetSize())
return type_list.GetTypeAtIndex(0);
return TypeSP();
}
-size_t Module::FindTypes(
+void Module::FindTypes(
ConstString name, bool exact_match, size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeList &types) {
- size_t num_matches = 0;
const char *type_name_cstr = name.GetCString();
llvm::StringRef type_scope;
llvm::StringRef type_basename;
- const bool append = true;
TypeClass type_class = eTypeClassAny;
TypeMap typesmap;
@@ -1008,58 +975,66 @@ size_t Module::FindTypes(
exact_match = type_scope.consume_front("::");
ConstString type_basename_const_str(type_basename);
- if (FindTypes_Impl(type_basename_const_str, nullptr, append, max_matches,
- searched_symbol_files, typesmap)) {
+ FindTypes_Impl(type_basename_const_str, nullptr, max_matches,
+ searched_symbol_files, typesmap);
+ if (typesmap.GetSize())
typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
exact_match);
- num_matches = typesmap.GetSize();
- }
} else {
// The type is not in a namespace/class scope, just search for it by
// basename
if (type_class != eTypeClassAny && !type_basename.empty()) {
// The "type_name_cstr" will have been modified if we have a valid type
// class prefix (like "struct", "class", "union", "typedef" etc).
- FindTypes_Impl(ConstString(type_basename), nullptr, append, UINT_MAX,
+ FindTypes_Impl(ConstString(type_basename), nullptr, UINT_MAX,
searched_symbol_files, typesmap);
typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
exact_match);
- num_matches = typesmap.GetSize();
} else {
- num_matches = FindTypes_Impl(name, nullptr, append, UINT_MAX,
- searched_symbol_files, typesmap);
+ FindTypes_Impl(name, nullptr, UINT_MAX, searched_symbol_files, typesmap);
if (exact_match) {
std::string name_str(name.AsCString(""));
typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class,
exact_match);
- num_matches = typesmap.GetSize();
}
}
}
- if (num_matches > 0) {
+ if (typesmap.GetSize()) {
SymbolContext sc;
sc.module_sp = shared_from_this();
sc.SortTypeList(typesmap, types);
}
- return num_matches;
}
-SymbolVendor *Module::GetSymbolVendor(bool can_create,
- lldb_private::Stream *feedback_strm) {
- if (!m_did_load_symbol_vendor.load()) {
+void Module::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ if (SymbolFile *symbols = GetSymbolFile())
+ symbols->FindTypes(pattern, languages, types);
+}
+
+SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
+ if (!m_did_load_symfile.load()) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_did_load_symbol_vendor.load() && can_create) {
+ if (!m_did_load_symfile.load() && can_create) {
ObjectFile *obj_file = GetObjectFile();
if (obj_file != nullptr) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
m_symfile_up.reset(
SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
- m_did_load_symbol_vendor = true;
+ m_did_load_symfile = true;
}
}
}
- return m_symfile_up.get();
+ return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
+}
+
+Symtab *Module::GetSymtab() {
+ if (SymbolFile *symbols = GetSymbolFile())
+ return symbols->GetSymtab();
+ return nullptr;
}
void Module::SetFileSpecAndObjectName(const FileSpec &file,
@@ -1232,20 +1207,12 @@ void Module::Dump(Stream *s) {
if (objfile)
objfile->Dump(s);
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
- symbols->Dump(s);
+ if (SymbolFile *symbols = GetSymbolFile())
+ symbols->Dump(*s);
s->IndentLess();
}
-TypeList *Module::GetTypeList() {
- SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
- return &symbols->GetTypeList();
- return nullptr;
-}
-
ConstString Module::GetObjectName() const { return m_object_name; }
ObjectFile *Module::GetObjectFile() {
@@ -1295,9 +1262,8 @@ void Module::SectionFileAddressesChanged() {
ObjectFile *obj_file = GetObjectFile();
if (obj_file)
obj_file->SectionFileAddressesChanged();
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (sym_vendor != nullptr)
- sym_vendor->SectionFileAddressesChanged();
+ if (SymbolFile *symbols = GetSymbolFile())
+ symbols->SectionFileAddressesChanged();
}
UnwindTable &Module::GetUnwindTable() {
@@ -1308,7 +1274,7 @@ UnwindTable &Module::GetUnwindTable() {
SectionList *Module::GetUnifiedSectionList() {
if (!m_sections_up)
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
return m_sections_up.get();
}
@@ -1318,13 +1284,9 @@ const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
Timer scoped_timer(
func_cat, "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
name.AsCString(), symbol_type);
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- return symtab->FindFirstSymbolWithNameAndType(
- name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
- }
+ if (Symtab *symtab = GetSymtab())
+ return symtab->FindFirstSymbolWithNameAndType(
+ name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
return nullptr;
}
void Module::SymbolIndicesToSymbolContextList(
@@ -1345,23 +1307,18 @@ void Module::SymbolIndicesToSymbolContextList(
}
}
-size_t Module::FindFunctionSymbols(ConstString name,
+void Module::FindFunctionSymbols(ConstString name,
uint32_t name_type_mask,
SymbolContextList &sc_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
name.AsCString(), name_type_mask);
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- return symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
- }
- return 0;
+ if (Symtab *symtab = GetSymtab())
+ symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
}
-size_t Module::FindSymbolsWithNameAndType(ConstString name,
+void Module::FindSymbolsWithNameAndType(ConstString name,
SymbolType symbol_type,
SymbolContextList &sc_list) {
// No need to protect this call using m_mutex all other method calls are
@@ -1371,22 +1328,16 @@ size_t Module::FindSymbolsWithNameAndType(ConstString name,
Timer scoped_timer(
func_cat, "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
name.AsCString(), symbol_type);
- const size_t initial_size = sc_list.GetSize();
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab) {
- std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
- SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
- }
+ if (Symtab *symtab = GetSymtab()) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
+ SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
}
- return sc_list.GetSize() - initial_size;
}
-size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
- SymbolType symbol_type,
- SymbolContextList &sc_list) {
+void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ SymbolType symbol_type,
+ SymbolContextList &sc_list) {
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
@@ -1395,35 +1346,27 @@ size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
func_cat,
"Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
regex.GetText().str().c_str(), symbol_type);
- const size_t initial_size = sc_list.GetSize();
- SymbolVendor *sym_vendor = GetSymbolVendor();
- if (sym_vendor) {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab) {
- std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsMatchingRexExAndType(
- regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
- symbol_indexes);
- SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
- }
+ if (Symtab *symtab = GetSymtab()) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->FindAllSymbolsMatchingRexExAndType(
+ regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
+ symbol_indexes);
+ SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
}
- return sc_list.GetSize() - initial_size;
}
void Module::PreloadSymbols() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor * sym_vendor = GetSymbolVendor();
- if (!sym_vendor) {
+ SymbolFile *sym_file = GetSymbolFile();
+ if (!sym_file)
return;
- }
+
// Prime the symbol file first, since it adds symbols to the symbol table.
- if (SymbolFile *symbol_file = sym_vendor->GetSymbolFile()) {
- symbol_file->PreloadSymbols();
- }
+ sym_file->PreloadSymbols();
+
// Now we can prime the symbol table.
- if (Symtab * symtab = sym_vendor->GetSymtab()) {
+ if (Symtab *symtab = sym_file->GetSymtab())
symtab->PreloadSymbols();
- }
}
void Module::SetSymbolFileFileSpec(const FileSpec &file) {
@@ -1433,7 +1376,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) {
// Remove any sections in the unified section list that come from the
// current symbol vendor.
SectionList *section_list = GetSectionList();
- SymbolFile *symbol_file = m_symfile_up->GetSymbolFile();
+ SymbolFile *symbol_file = GetSymbolFile();
if (section_list && symbol_file) {
ObjectFile *obj_file = symbol_file->GetObjectFile();
// Make sure we have an object file and that the symbol vendor's objfile
@@ -1489,7 +1432,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) {
}
m_symfile_spec = file;
m_symfile_up.reset();
- m_did_load_symbol_vendor = false;
+ m_did_load_symfile = false;
}
bool Module::IsExecutable() {
@@ -1654,6 +1597,26 @@ bool Module::RemapSourceFile(llvm::StringRef path,
return m_source_mappings.RemapPath(path, new_path);
}
+bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
+ if (!arch_spec.IsValid())
+ return false;
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
+ "module has arch %s, merging/replacing with arch %s",
+ m_arch.GetTriple().getTriple().c_str(),
+ arch_spec.GetTriple().getTriple().c_str());
+ if (!m_arch.IsCompatibleMatch(arch_spec)) {
+ // The new architecture is different, we just need to replace it.
+ return SetArchitecture(arch_spec);
+ }
+
+ // Merge bits from arch_spec into "merged_arch" and set our architecture.
+ ArchSpec merged_arch(m_arch);
+ merged_arch.MergeFrom(arch_spec);
+ // SetArchitecture() is a no-op if m_arch is already valid.
+ m_arch = ArchSpec();
+ return SetArchitecture(merged_arch);
+}
+
llvm::VersionTuple Module::GetVersion() {
if (ObjectFile *obj_file = GetObjectFile())
return obj_file->GetVersion();
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index 9d795f9e5586..b0567a902fd7 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -17,6 +17,7 @@
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
@@ -56,40 +57,26 @@ class SymbolFile;
namespace lldb_private {
class Target;
}
-namespace lldb_private {
-class TypeList;
-}
using namespace lldb;
using namespace lldb_private;
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"enable-external-lookup", OptionValue::eTypeBoolean, true, true, nullptr,
- {},
- "Control the use of external tools and repositories to locate symbol "
- "files. Directories listed in target.debug-file-search-paths and "
- "directory of the executable are always checked first for separate debug "
- "info files. Then depending on this setting: "
- "On macOS, Spotlight would be also used to locate a matching .dSYM "
- "bundle based on the UUID of the executable. "
- "On NetBSD, directory /usr/libdata/debug would be also searched. "
- "On platforms other than NetBSD directory /usr/lib/debug would be "
- "also searched."
- },
- {"clang-modules-cache-path", OptionValue::eTypeFileSpec, true, 0, nullptr,
- {},
- "The path to the clang modules cache directory (-fmodules-cache-path)."}};
-
-enum { ePropertyEnableExternalLookup, ePropertyClangModulesCachePath };
+#define LLDB_PROPERTIES_modulelist
+#include "CoreProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_modulelist
+#include "CorePropertiesEnum.inc"
+};
} // namespace
ModuleListProperties::ModuleListProperties() {
m_collection_sp =
std::make_shared<OptionValueProperties>(ConstString("symbols"));
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_modulelist_properties);
llvm::SmallString<128> path;
clang::driver::Driver::getDefaultModuleCachePath(path);
@@ -99,7 +86,7 @@ ModuleListProperties::ModuleListProperties() {
bool ModuleListProperties::GetEnableExternalLookup() const {
const uint32_t idx = ePropertyEnableExternalLookup;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
}
bool ModuleListProperties::SetEnableExternalLookup(bool new_value) {
@@ -135,9 +122,9 @@ ModuleList::ModuleList(ModuleList::Notifier *notifier)
const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
if (this != &rhs) {
std::lock(m_modules_mutex, rhs.m_modules_mutex);
- std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex,
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex,
std::adopt_lock);
- std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex,
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex,
std::adopt_lock);
m_modules = rhs.m_modules;
}
@@ -155,8 +142,8 @@ void ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) {
}
}
-void ModuleList::Append(const ModuleSP &module_sp, bool notify) {
- AppendImpl(module_sp, notify);
+void ModuleList::Append(const ModuleSP &module_sp, bool notify) {
+ AppendImpl(module_sp, notify);
}
void ModuleList::ReplaceEquivalent(const ModuleSP &module_sp) {
@@ -339,14 +326,10 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
return module_sp;
}
-size_t ModuleList::FindFunctions(ConstString name,
- FunctionNameType name_type_mask,
- bool include_symbols, bool include_inlines,
- bool append,
- SymbolContextList &sc_list) const {
- if (!append)
- sc_list.Clear();
-
+void ModuleList::FindFunctions(ConstString name,
+ FunctionNameType name_type_mask,
+ bool include_symbols, bool include_inlines,
+ SymbolContextList &sc_list) const {
const size_t old_size = sc_list.GetSize();
if (name_type_mask & eFunctionNameTypeAuto) {
@@ -357,7 +340,7 @@ size_t ModuleList::FindFunctions(ConstString name,
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindFunctions(lookup_info.GetLookupName(), nullptr,
lookup_info.GetNameTypeMask(), include_symbols,
- include_inlines, true, sc_list);
+ include_inlines, sc_list);
}
const size_t new_size = sc_list.GetSize();
@@ -369,15 +352,14 @@ size_t ModuleList::FindFunctions(ConstString name,
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols,
- include_inlines, true, sc_list);
+ include_inlines, sc_list);
}
}
- return sc_list.GetSize() - old_size;
}
-size_t ModuleList::FindFunctionSymbols(ConstString name,
- lldb::FunctionNameType name_type_mask,
- SymbolContextList &sc_list) {
+void ModuleList::FindFunctionSymbols(ConstString name,
+ lldb::FunctionNameType name_type_mask,
+ SymbolContextList &sc_list) {
const size_t old_size = sc_list.GetSize();
if (name_type_mask & eFunctionNameTypeAuto) {
@@ -401,96 +383,66 @@ size_t ModuleList::FindFunctionSymbols(ConstString name,
(*pos)->FindFunctionSymbols(name, name_type_mask, sc_list);
}
}
-
- return sc_list.GetSize() - old_size;
}
-size_t ModuleList::FindFunctions(const RegularExpression &name,
- bool include_symbols, bool include_inlines,
- bool append, SymbolContextList &sc_list) {
- const size_t old_size = sc_list.GetSize();
-
+void ModuleList::FindFunctions(const RegularExpression &name,
+ bool include_symbols, bool include_inlines,
+ SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctions(name, include_symbols, include_inlines, append,
- sc_list);
+ (*pos)->FindFunctions(name, include_symbols, include_inlines, sc_list);
}
-
- return sc_list.GetSize() - old_size;
}
-size_t ModuleList::FindCompileUnits(const FileSpec &path, bool append,
- SymbolContextList &sc_list) const {
- if (!append)
- sc_list.Clear();
-
+void ModuleList::FindCompileUnits(const FileSpec &path,
+ SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindCompileUnits(path, true, sc_list);
+ (*pos)->FindCompileUnits(path, sc_list);
}
-
- return sc_list.GetSize();
}
-size_t ModuleList::FindGlobalVariables(ConstString name,
- size_t max_matches,
- VariableList &variable_list) const {
- size_t initial_size = variable_list.GetSize();
+void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches,
+ VariableList &variable_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindGlobalVariables(name, nullptr, max_matches, variable_list);
}
- return variable_list.GetSize() - initial_size;
}
-size_t ModuleList::FindGlobalVariables(const RegularExpression &regex,
- size_t max_matches,
- VariableList &variable_list) const {
- size_t initial_size = variable_list.GetSize();
+void ModuleList::FindGlobalVariables(const RegularExpression &regex,
+ size_t max_matches,
+ VariableList &variable_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindGlobalVariables(regex, max_matches, variable_list);
}
- return variable_list.GetSize() - initial_size;
}
-size_t ModuleList::FindSymbolsWithNameAndType(ConstString name,
- SymbolType symbol_type,
- SymbolContextList &sc_list,
- bool append) const {
+void ModuleList::FindSymbolsWithNameAndType(ConstString name,
+ SymbolType symbol_type,
+ SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- if (!append)
- sc_list.Clear();
- size_t initial_size = sc_list.GetSize();
-
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
(*pos)->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
- return sc_list.GetSize() - initial_size;
}
-size_t ModuleList::FindSymbolsMatchingRegExAndType(
+void ModuleList::FindSymbolsMatchingRegExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
- SymbolContextList &sc_list, bool append) const {
+ SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- if (!append)
- sc_list.Clear();
- size_t initial_size = sc_list.GetSize();
-
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
(*pos)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
- return sc_list.GetSize() - initial_size;
}
-size_t ModuleList::FindModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) const {
- size_t existing_matches = matching_module_list.GetSize();
-
+void ModuleList::FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
@@ -498,7 +450,6 @@ size_t ModuleList::FindModules(const ModuleSpec &module_spec,
if (module_sp->MatchesModuleSpec(module_spec))
matching_module_list.Append(module_sp);
}
- return matching_module_list.GetSize() - existing_matches;
}
ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
@@ -536,44 +487,36 @@ ModuleSP ModuleList::FindModule(const UUID &uuid) const {
return module_sp;
}
-size_t
-ModuleList::FindTypes(Module *search_first, ConstString name,
- bool name_is_fully_qualified, size_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeList &types) const {
+void ModuleList::FindTypes(Module *search_first, ConstString name,
+ bool name_is_fully_qualified, size_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeList &types) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- size_t total_matches = 0;
collection::const_iterator pos, end = m_modules.end();
if (search_first) {
for (pos = m_modules.begin(); pos != end; ++pos) {
if (search_first == pos->get()) {
- total_matches +=
- search_first->FindTypes(name, name_is_fully_qualified, max_matches,
- searched_symbol_files, types);
+ search_first->FindTypes(name, name_is_fully_qualified, max_matches,
+ searched_symbol_files, types);
- if (total_matches >= max_matches)
- break;
+ if (types.GetSize() >= max_matches)
+ return;
}
}
}
- if (total_matches < max_matches) {
- for (pos = m_modules.begin(); pos != end; ++pos) {
- // Search the module if the module is not equal to the one in the symbol
- // context "sc". If "sc" contains a empty module shared pointer, then the
- // comparison will always be true (valid_module_ptr != nullptr).
- if (search_first != pos->get())
- total_matches +=
- (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
- searched_symbol_files, types);
-
- if (total_matches >= max_matches)
- break;
- }
- }
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ // Search the module if the module is not equal to the one in the symbol
+ // context "sc". If "sc" contains a empty module shared pointer, then the
+ // comparison will always be true (valid_module_ptr != nullptr).
+ if (search_first != pos->get())
+ (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
+ searched_symbol_files, types);
- return total_matches;
+ if (types.GetSize() >= max_matches)
+ return;
+ }
}
bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
@@ -641,11 +584,11 @@ void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
for (pos = begin; pos != end; ++pos) {
Module *module = pos->get();
const FileSpec &module_file_spec = module->GetFileSpec();
- log->Printf("%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
- (uint32_t)std::distance(begin, pos),
- module->GetUUID().GetAsString().c_str(),
- module->GetArchitecture().GetArchitectureName(),
- module_file_spec.GetPath().c_str());
+ LLDB_LOGF(log, "%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
+ (uint32_t)std::distance(begin, pos),
+ module->GetUUID().GetAsString().c_str(),
+ module->GetArchitecture().GetArchitectureName(),
+ module_file_spec.GetPath().c_str());
}
}
}
@@ -757,9 +700,9 @@ bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
return false;
}
-size_t ModuleList::FindSharedModules(const ModuleSpec &module_spec,
- ModuleList &matching_module_list) {
- return GetSharedModuleList().FindModules(module_spec, matching_module_list);
+void ModuleList::FindSharedModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) {
+ GetSharedModuleList().FindModules(module_spec, matching_module_list);
}
size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
@@ -794,8 +737,9 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
// mutex list.
if (!always_create) {
ModuleList matching_module_list;
- const size_t num_matching_modules =
- shared_module_list.FindModules(module_spec, matching_module_list);
+ shared_module_list.FindModules(module_spec, matching_module_list);
+ const size_t num_matching_modules = matching_module_list.GetSize();
+
if (num_matching_modules > 0) {
for (size_t module_idx = 0; module_idx < num_matching_modules;
++module_idx) {
@@ -808,8 +752,9 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
if (log != nullptr)
- log->Printf("module changed: %p, removing from global module list",
- static_cast<void *>(module_sp.get()));
+ LLDB_LOGF(log,
+ "module changed: %p, removing from global module list",
+ static_cast<void *>(module_sp.get()));
shared_module_list.Remove(module_sp);
module_sp.reset();
@@ -945,8 +890,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec,
platform_module_spec.GetSymbolFileSpec() =
located_binary_modulespec.GetSymbolFileSpec();
ModuleList matching_module_list;
- if (shared_module_list.FindModules(platform_module_spec,
- matching_module_list) > 0) {
+ shared_module_list.FindModules(platform_module_spec, matching_module_list);
+ if (!matching_module_list.IsEmpty()) {
module_sp = matching_module_list.GetModuleAtIndex(0);
// If we didn't have a UUID in mind when looking for the object file,
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index 24cadcd85bf5..80b64fb832fa 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -1341,10 +1341,10 @@ PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
return nullptr;
}
-size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
- StringList &matches) {
+void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
+ CompletionRequest &request) {
if (name.empty())
- return matches.GetSize();
+ return;
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
PlatformInstances &instances = GetPlatformInstances();
@@ -1354,9 +1354,8 @@ size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
for (pos = instances.begin(); pos != end; ++pos) {
llvm::StringRef plugin_name(pos->name.GetCString());
if (plugin_name.startswith(name_sref))
- matches.AppendString(plugin_name.data());
+ request.AddCompletion(plugin_name.data());
}
- return matches.GetSize();
}
#pragma mark Process
@@ -2084,12 +2083,11 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
#pragma mark TypeSystem
struct TypeSystemInstance {
- TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
-
ConstString name;
std::string description;
TypeSystemCreateInstance create_callback;
- TypeSystemEnumerateSupportedLanguages enumerate_callback;
+ LanguageSet supported_languages_for_types;
+ LanguageSet supported_languages_for_expressions;
};
typedef std::vector<TypeSystemInstance> TypeSystemInstances;
@@ -2104,11 +2102,11 @@ static TypeSystemInstances &GetTypeSystemInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name,
- const char *description,
- TypeSystemCreateInstance create_callback,
- TypeSystemEnumerateSupportedLanguages
- enumerate_supported_languages_callback) {
+bool PluginManager::RegisterPlugin(
+ ConstString name, const char *description,
+ TypeSystemCreateInstance create_callback,
+ LanguageSet supported_languages_for_types,
+ LanguageSet supported_languages_for_expressions) {
if (create_callback) {
TypeSystemInstance instance;
assert((bool)name);
@@ -2116,7 +2114,8 @@ bool PluginManager::RegisterPlugin(ConstString name,
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- instance.enumerate_callback = enumerate_supported_languages_callback;
+ instance.supported_languages_for_types = supported_languages_for_types;
+ instance.supported_languages_for_expressions = supported_languages_for_expressions;
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
GetTypeSystemInstances().push_back(instance);
}
@@ -2164,30 +2163,22 @@ PluginManager::GetTypeSystemCreateCallbackForPluginName(
return nullptr;
}
-TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
- uint32_t idx) {
+LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
+ LanguageSet all;
TypeSystemInstances &instances = GetTypeSystemInstances();
- if (idx < instances.size())
- return instances[idx].enumerate_callback;
- return nullptr;
+ for (unsigned i = 0; i < instances.size(); ++i)
+ all.bitvector |= instances[i].supported_languages_for_types.bitvector;
+ return all;
}
-TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
- ConstString name) {
- if (name) {
- std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
- TypeSystemInstances &instances = GetTypeSystemInstances();
-
- TypeSystemInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++pos) {
- if (name == pos->name)
- return pos->enumerate_callback;
- }
- }
- return nullptr;
+LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
+ LanguageSet all;
+ TypeSystemInstances &instances = GetTypeSystemInstances();
+ for (unsigned i = 0; i < instances.size(); ++i)
+ all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
+ return all;
}
#pragma mark REPL
@@ -2198,7 +2189,7 @@ struct REPLInstance {
ConstString name;
std::string description;
REPLCreateInstance create_callback;
- REPLEnumerateSupportedLanguages enumerate_languages_callback;
+ LanguageSet supported_languages;
};
typedef std::vector<REPLInstance> REPLInstances;
@@ -2213,10 +2204,9 @@ static REPLInstances &GetREPLInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
- REPLCreateInstance create_callback,
- REPLEnumerateSupportedLanguages enumerate_languages_callback) {
+bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+ REPLCreateInstance create_callback,
+ LanguageSet supported_languages) {
if (create_callback) {
REPLInstance instance;
assert((bool)name);
@@ -2224,7 +2214,7 @@ bool PluginManager::RegisterPlugin(
if (description && description[0])
instance.description = description;
instance.create_callback = create_callback;
- instance.enumerate_languages_callback = enumerate_languages_callback;
+ instance.supported_languages = supported_languages;
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
GetREPLInstances().push_back(instance);
}
@@ -2270,29 +2260,13 @@ PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) {
return nullptr;
}
-REPLEnumerateSupportedLanguages
-PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
+LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
+ LanguageSet all;
REPLInstances &instances = GetREPLInstances();
- if (idx < instances.size())
- return instances[idx].enumerate_languages_callback;
- return nullptr;
-}
-
-REPLEnumerateSupportedLanguages
-PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
- ConstString name) {
- if (name) {
- std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
- REPLInstances &instances = GetREPLInstances();
-
- REPLInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++pos) {
- if (name == pos->name)
- return pos->enumerate_languages_callback;
- }
- }
- return nullptr;
+ for (unsigned i = 0; i < instances.size(); ++i)
+ all.bitvector |= instances[i].supported_languages.bitvector;
+ return all;
}
#pragma mark PluginManager
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp
index 531fa078de29..e02b4f66b58c 100644
--- a/source/Core/SearchFilter.cpp
+++ b/source/Core/SearchFilter.cpp
@@ -13,7 +13,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -209,7 +209,7 @@ void SearchFilter::Search(Searcher &searcher) {
empty_sc.target_sp = m_target_sp;
if (searcher.GetDepth() == lldb::eSearchDepthTarget)
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr);
else
DoModuleIteration(empty_sc, searcher);
}
@@ -222,7 +222,7 @@ void SearchFilter::SearchInModuleList(Searcher &searcher, ModuleList &modules) {
empty_sc.target_sp = m_target_sp;
if (searcher.GetDepth() == lldb::eSearchDepthTarget)
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr);
else {
std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
const size_t numModules = modules.GetSize();
@@ -252,7 +252,7 @@ SearchFilter::DoModuleIteration(const SymbolContext &context,
if (context.module_sp) {
if (searcher.GetDepth() == lldb::eSearchDepthModule) {
SymbolContext matchingContext(context.module_sp.get());
- searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ searcher.SearchCallback(*this, matchingContext, nullptr);
} else {
return DoCUIteration(context.module_sp, context, searcher);
}
@@ -272,7 +272,7 @@ SearchFilter::DoModuleIteration(const SymbolContext &context,
SymbolContext matchingContext(m_target_sp, module_sp);
Searcher::CallbackReturn shouldContinue =
- searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ searcher.SearchCallback(*this, matchingContext, nullptr);
if (shouldContinue == Searcher::eCallbackReturnStop ||
shouldContinue == Searcher::eCallbackReturnPop)
return shouldContinue;
@@ -306,7 +306,7 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp,
SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
shouldContinue =
- searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ searcher.SearchCallback(*this, matchingContext, nullptr);
if (shouldContinue == Searcher::eCallbackReturnPop)
return Searcher::eCallbackReturnContinue;
@@ -316,10 +316,10 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp,
// First make sure this compile unit's functions are parsed
// since CompUnit::ForeachFunction only iterates over already
// parsed functions.
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (!sym_vendor)
+ SymbolFile *sym_file = module_sp->GetSymbolFile();
+ if (!sym_file)
continue;
- if (!sym_vendor->ParseFunctions(*cu_sp))
+ if (!sym_file->ParseFunctions(*cu_sp))
continue;
// If we got any functions, use ForeachFunction to do the iteration.
cu_sp->ForeachFunction([&](const FunctionSP &func_sp) {
@@ -328,9 +328,8 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp,
if (searcher.GetDepth() == lldb::eSearchDepthFunction) {
SymbolContext matchingContext(m_target_sp, module_sp,
cu_sp.get(), func_sp.get());
- shouldContinue = searcher.SearchCallback(*this,
- matchingContext,
- nullptr, false);
+ shouldContinue =
+ searcher.SearchCallback(*this, matchingContext, nullptr);
} else {
shouldContinue = DoFunctionIteration(func_sp.get(), context,
searcher);
@@ -343,7 +342,7 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp,
} else {
if (CompUnitPasses(*context.comp_unit)) {
SymbolContext matchingContext(m_target_sp, module_sp, context.comp_unit);
- return searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ return searcher.SearchCallback(*this, matchingContext, nullptr);
}
}
return Searcher::eCallbackReturnContinue;
@@ -431,7 +430,7 @@ void SearchFilterByModule::Search(Searcher &searcher) {
if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr);
}
// If the module file spec is a full path, then we can just find the one
@@ -568,7 +567,7 @@ void SearchFilterByModuleList::Search(Searcher &searcher) {
if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr);
}
// If the module file spec is a full path, then we can just find the one
@@ -640,7 +639,7 @@ SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData(
"SFBM::CFSD: filter module item %zu not a string.", i);
return nullptr;
}
- modules.Append(FileSpec(module));
+ modules.EmplaceBack(module);
}
}
@@ -703,7 +702,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData(
"SFBM::CFSD: filter module item %zu not a string.", i);
return result_sp;
}
- modules.Append(FileSpec(module));
+ modules.EmplaceBack(module);
}
}
@@ -725,7 +724,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData(
"SFBM::CFSD: filter cu item %zu not a string.", i);
return nullptr;
}
- cus.Append(FileSpec(cu));
+ cus.EmplaceBack(cu);
}
return std::make_shared<SearchFilterByModuleListAndCU>(
@@ -777,7 +776,7 @@ void SearchFilterByModuleListAndCU::Search(Searcher &searcher) {
if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
SymbolContext empty_sc;
empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ searcher.SearchCallback(*this, empty_sc, nullptr);
}
// If the module file spec is a full path, then we can just find the one
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index f30ddd2c18c3..7615dc1d65c7 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -269,7 +269,7 @@ bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr,
bool Section::ContainsFileAddress(addr_t vm_addr) const {
const addr_t file_addr = GetFileAddress();
- if (file_addr != LLDB_INVALID_ADDRESS) {
+ if (file_addr != LLDB_INVALID_ADDRESS && !IsThreadSpecific()) {
if (file_addr <= vm_addr) {
const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
return offset < GetByteSize();
@@ -417,10 +417,6 @@ lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
#pragma mark SectionList
-SectionList::SectionList() : m_sections() {}
-
-SectionList::~SectionList() {}
-
SectionList &SectionList::operator=(const SectionList &rhs) {
if (this != &rhs)
m_sections = rhs.m_sections;
diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp
index 87065ab62425..42741e4ba4fe 100644
--- a/source/Core/SourceManager.cpp
+++ b/source/Core/SourceManager.cpp
@@ -324,10 +324,10 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) {
ConstString main_name("main");
bool symbols_okay = false; // Force it to be a debug symbol.
bool inlines_okay = true;
- bool append = false;
- size_t num_matches = executable_ptr->FindFunctions(
- main_name, nullptr, lldb::eFunctionNameTypeBase, inlines_okay,
- symbols_okay, append, sc_list);
+ executable_ptr->FindFunctions(main_name, nullptr,
+ lldb::eFunctionNameTypeBase, inlines_okay,
+ symbols_okay, sc_list);
+ size_t num_matches = sc_list.GetSize();
for (size_t idx = 0; idx < num_matches; idx++) {
SymbolContext sc;
sc_list.GetContextAtIndex(idx, sc);
diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp
index ce6e1ea2c18f..2ddb39659d66 100644
--- a/source/Core/StreamFile.cpp
+++ b/source/Core/StreamFile.cpp
@@ -8,6 +8,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Utility/Log.h"
#include <stdio.h>
@@ -15,35 +16,55 @@ using namespace lldb;
using namespace lldb_private;
// StreamFile constructor
-StreamFile::StreamFile() : Stream(), m_file() {}
+StreamFile::StreamFile() : Stream() { m_file_sp = std::make_shared<File>(); }
StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
- : Stream(flags, addr_size, byte_order), m_file() {}
-
-StreamFile::StreamFile(int fd, bool transfer_ownership)
- : Stream(), m_file(fd, transfer_ownership) {}
+ : Stream(flags, addr_size, byte_order) {
+ m_file_sp = std::make_shared<File>();
+}
-StreamFile::StreamFile(FILE *fh, bool transfer_ownership)
- : Stream(), m_file(fh, transfer_ownership) {}
+StreamFile::StreamFile(int fd, bool transfer_ownership) : Stream() {
+ m_file_sp =
+ std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, transfer_ownership);
+}
-StreamFile::StreamFile(const char *path) : Stream(), m_file() {
- FileSystem::Instance().Open(m_file, FileSpec(path),
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate |
- File::eOpenOptionCloseOnExec);
+StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream() {
+ m_file_sp = std::make_shared<NativeFile>(fh, transfer_ownership);
}
-StreamFile::StreamFile(const char *path, uint32_t options, uint32_t permissions)
- : Stream(), m_file() {
+StreamFile::StreamFile(const char *path) : Stream() {
+ auto file = FileSystem::Instance().Open(
+ FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec);
+ if (file)
+ m_file_sp = std::move(file.get());
+ else {
+ // TODO refactor this so the error gets popagated up instead of logged here.
+ LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), file.takeError(),
+ "Cannot open {1}: {0}", path);
+ m_file_sp = std::make_shared<File>();
+ }
+}
- FileSystem::Instance().Open(m_file, FileSpec(path), options, permissions);
+StreamFile::StreamFile(const char *path, File::OpenOptions options,
+ uint32_t permissions)
+ : Stream() {
+ auto file = FileSystem::Instance().Open(FileSpec(path), options, permissions);
+ if (file)
+ m_file_sp = std::move(file.get());
+ else {
+ // TODO refactor this so the error gets popagated up instead of logged here.
+ LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), file.takeError(),
+ "Cannot open {1}: {0}", path);
+ m_file_sp = std::make_shared<File>();
+ }
}
StreamFile::~StreamFile() {}
-void StreamFile::Flush() { m_file.Flush(); }
+void StreamFile::Flush() { m_file_sp->Flush(); }
size_t StreamFile::WriteImpl(const void *s, size_t length) {
- m_file.Write(s, length);
+ m_file_sp->Write(s, length);
return length;
}
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index fdb4adb5f431..3124b9338b36 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -314,7 +314,7 @@ bool Value::GetData(DataExtractor &data) {
}
Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
- uint32_t data_offset, Module *module) {
+ Module *module) {
data.Clear();
Status error;
@@ -520,13 +520,12 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
// Make sure we have enough room within "data", and if we don't make
// something large enough that does
- if (!data.ValidOffsetForDataOfSize(data_offset, byte_size)) {
- auto data_sp =
- std::make_shared<DataBufferHeap>(data_offset + byte_size, '\0');
+ if (!data.ValidOffsetForDataOfSize(0, byte_size)) {
+ auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
data.SetData(data_sp);
}
- uint8_t *dst = const_cast<uint8_t *>(data.PeekData(data_offset, byte_size));
+ uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
if (dst != nullptr) {
if (address_type == eAddressTypeHost) {
// The address is an address in this process, so just copy it.
@@ -597,7 +596,7 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
{
DataExtractor data;
lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- Status error(GetValueAsData(exe_ctx, data, 0, nullptr));
+ Status error(GetValueAsData(exe_ctx, data, nullptr));
if (error.Success()) {
Scalar scalar;
if (compiler_type.GetValueAsScalar(data, 0, data.GetByteSize(),
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 297365b4ecbd..74176eeace3a 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -73,7 +73,6 @@ class SymbolContextScope;
using namespace lldb;
using namespace lldb_private;
-using namespace lldb_utility;
static user_id_t g_value_obj_uid = 0;
@@ -226,12 +225,12 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) {
bool ValueObject::UpdateFormatsIfNeeded() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
- if (log)
- log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
- "rev: %d - Global rev: %d",
- GetName().GetCString(), static_cast<void *>(this),
- m_last_format_mgr_revision,
- DataVisualization::GetCurrentRevision());
+ LLDB_LOGF(log,
+ "[%s %p] checking for FormatManager revisions. ValueObject "
+ "rev: %d - Global rev: %d",
+ GetName().GetCString(), static_cast<void *>(this),
+ m_last_format_mgr_revision,
+ DataVisualization::GetCurrentRevision());
bool any_change = false;
@@ -811,7 +810,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
UpdateValueIfNeeded(false);
ExecutionContext exe_ctx(GetExecutionContextRef());
- error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
+ error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
if (error.Fail()) {
if (m_data.GetByteSize()) {
data = m_data;
@@ -1672,16 +1671,7 @@ bool ValueObject::IsRuntimeSupportValue() {
if (!GetVariable() || !GetVariable()->IsArtificial())
return false;
- LanguageType lang = eLanguageTypeUnknown;
- if (auto *sym_ctx_scope = GetSymbolContextScope()) {
- if (auto *func = sym_ctx_scope->CalculateSymbolContextFunction())
- lang = func->GetLanguage();
- else if (auto *comp_unit =
- sym_ctx_scope->CalculateSymbolContextCompileUnit())
- lang = comp_unit->GetLanguage();
- }
-
- if (auto *runtime = process->GetLanguageRuntime(lang))
+ if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()))
if (runtime->IsWhitelistedRuntimeValue(GetName()))
return false;
@@ -2726,9 +2716,9 @@ ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
if (IsBitfield()) {
Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
- m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
+ m_error = v.GetValueAsData(&exe_ctx, data, GetModule().get());
} else
- m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
valobj_sp = ValueObjectConstResult::Create(
exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
@@ -3310,32 +3300,32 @@ lldb::ValueObjectSP ValueObjectManager::GetSP() {
lldb::ProcessSP process_sp = GetProcessSP();
if (!process_sp)
return lldb::ValueObjectSP();
-
+
const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
if (current_stop_id == m_stop_id)
return m_user_valobj_sp;
-
+
m_stop_id = current_stop_id;
-
+
if (!m_root_valobj_sp) {
m_user_valobj_sp.reset();
return m_root_valobj_sp;
}
-
+
m_user_valobj_sp = m_root_valobj_sp;
-
+
if (m_use_dynamic != lldb::eNoDynamicValues) {
lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
if (dynamic_sp)
m_user_valobj_sp = dynamic_sp;
}
-
+
if (m_use_synthetic) {
lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
if (synthetic_sp)
m_user_valobj_sp = synthetic_sp;
}
-
+
return m_user_valobj_sp;
}
diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp
index 6ccda8c32915..3a74b6a7fe18 100644
--- a/source/Core/ValueObjectCast.cpp
+++ b/source/Core/ValueObjectCast.cpp
@@ -79,7 +79,7 @@ bool ValueObjectCast::UpdateValue() {
m_value.GetScalar() != old_value.GetScalar());
}
ExecutionContext exe_ctx(GetExecutionContextRef());
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
SetValueDidChange(m_parent->GetValueDidChange());
return true;
}
diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index 01f2e20dd0bc..6b4ada154d68 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -175,6 +175,30 @@ bool ValueObjectChild::UpdateValue() {
// Set this object's scalar value to the address of its value by
// adding its byte offset to the parent address
m_value.GetScalar() += GetByteOffset();
+
+ // If a bitfield doesn't fit into the child_byte_size'd
+ // window at child_byte_offset, move the window forward
+ // until it fits. The problem here is that Value has no
+ // notion of bitfields and thus the Value's DataExtractor
+ // is sized like the bitfields CompilerType; a sequence of
+ // bitfields, however, can be larger than their underlying
+ // type.
+ if (m_bitfield_bit_offset) {
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx(GetExecutionContextRef().Lock(
+ thread_and_frame_only_if_stopped));
+ if (auto type_bit_size = GetCompilerType().GetBitSize(
+ exe_ctx.GetBestExecutionContextScope())) {
+ uint64_t bitfield_end =
+ m_bitfield_bit_size + m_bitfield_bit_offset;
+ if (bitfield_end > *type_bit_size) {
+ uint64_t overhang_bytes =
+ (bitfield_end - *type_bit_size + 7) / 8;
+ m_value.GetScalar() += overhang_bytes;
+ m_bitfield_bit_offset -= overhang_bytes * 8;
+ }
+ }
+ }
}
} break;
@@ -203,7 +227,7 @@ bool ValueObjectChild::UpdateValue() {
if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue) {
Value &value = is_instance_ptr_base ? m_parent->GetValue() : m_value;
m_error =
- value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
} else {
m_error.Clear(); // No value so nothing to read...
}
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index a1b2cac96874..71620698da2a 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -182,7 +182,7 @@ ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
m_name = name;
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module);
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);
}
ValueObjectConstResult::~ValueObjectConstResult() {}
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 90b46d1f170d..59037e2b6b25 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -199,7 +199,7 @@ bool ValueObjectDynamicValue::UpdateValue() {
ClearDynamicTypeInformation();
m_dynamic_type_info.Clear();
m_value = m_parent->GetValue();
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
return m_error.Success();
}
@@ -243,13 +243,13 @@ bool ValueObjectDynamicValue::UpdateValue() {
m_value.SetValueType(value_type);
if (has_changed_type && log)
- log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
- static_cast<void *>(this), GetTypeName().GetCString());
+ LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(),
+ static_cast<void *>(this), GetTypeName().GetCString());
if (m_address.IsValid() && m_dynamic_type_info) {
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
if (m_error.Success()) {
if (!CanProvideValue()) {
// this value object represents an aggregate type whose children have
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index 95d4330ee0c6..1a316bf3e7b0 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -168,7 +168,7 @@ bool ValueObjectMemory::UpdateValue() {
case Value::eValueTypeScalar:
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
break;
case Value::eValueTypeFileAddress:
@@ -209,7 +209,7 @@ bool ValueObjectMemory::UpdateValue() {
value.SetCompilerType(m_compiler_type);
}
- m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
}
break;
}
diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp
index 75a254fbbc21..7e97df6d2a34 100644
--- a/source/Core/ValueObjectRegister.cpp
+++ b/source/Core/ValueObjectRegister.cpp
@@ -18,6 +18,7 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
@@ -256,15 +257,19 @@ ValueObjectRegister::~ValueObjectRegister() {}
CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
if (!m_compiler_type.IsValid()) {
ExecutionContext exe_ctx(GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- Module *exe_module = target->GetExecutableModulePointer();
- if (exe_module) {
- TypeSystem *type_system =
+ if (auto *target = exe_ctx.GetTargetPtr()) {
+ if (auto *exe_module = target->GetExecutableModulePointer()) {
+ auto type_system_or_err =
exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system)
- m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
- m_reg_info.encoding, m_reg_info.byte_size * 8);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES),
+ std::move(err), "Unable to get CompilerType from TypeSystem");
+ } else {
+ m_compiler_type =
+ type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ m_reg_info.encoding, m_reg_info.byte_size * 8);
+ }
}
}
}
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index 400473235759..a6bf35eac70a 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -87,20 +87,18 @@ size_t ValueObjectSynthetic::CalculateNumChildren(uint32_t max) {
if (max < UINT32_MAX) {
size_t num_children = m_synth_filter_up->CalculateNumChildren(max);
- if (log)
- log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
- "%s and type %s, the filter returned %zu child values",
- GetName().AsCString(), GetTypeName().AsCString(),
- num_children);
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
+ "%s and type %s, the filter returned %zu child values",
+ GetName().AsCString(), GetTypeName().AsCString(), num_children);
return num_children;
} else {
size_t num_children = (m_synthetic_children_count =
m_synth_filter_up->CalculateNumChildren(max));
- if (log)
- log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
- "%s and type %s, the filter returned %zu child values",
- GetName().AsCString(), GetTypeName().AsCString(),
- num_children);
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
+ "%s and type %s, the filter returned %zu child values",
+ GetName().AsCString(), GetTypeName().AsCString(), num_children);
return num_children;
}
}
@@ -142,7 +140,7 @@ void ValueObjectSynthetic::CreateSynthFilter() {
}
m_synth_filter_up = (m_synth_sp->GetFrontEnd(*valobj_for_frontend));
if (!m_synth_filter_up)
- m_synth_filter_up = llvm::make_unique<DummySyntheticFrontEnd>(*m_parent);
+ m_synth_filter_up = std::make_unique<DummySyntheticFrontEnd>(*m_parent);
}
bool ValueObjectSynthetic::UpdateValue() {
@@ -163,21 +161,21 @@ bool ValueObjectSynthetic::UpdateValue() {
// <rdar://problem/12424824>
ConstString new_parent_type_name = m_parent->GetTypeName();
if (new_parent_type_name != m_parent_type_name) {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, type changed "
- "from %s to %s, recomputing synthetic filter",
- GetName().AsCString(), m_parent_type_name.AsCString(),
- new_parent_type_name.AsCString());
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::UpdateValue] name=%s, type changed "
+ "from %s to %s, recomputing synthetic filter",
+ GetName().AsCString(), m_parent_type_name.AsCString(),
+ new_parent_type_name.AsCString());
m_parent_type_name = new_parent_type_name;
CreateSynthFilter();
}
// let our backend do its update
if (!m_synth_filter_up->Update()) {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
- "filter said caches are stale - clearing",
- GetName().AsCString());
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said caches are stale - clearing",
+ GetName().AsCString());
// filter said that cached values are stale
m_children_byindex.Clear();
m_name_toindex.Clear();
@@ -190,10 +188,10 @@ bool ValueObjectSynthetic::UpdateValue() {
m_synthetic_children_count = UINT32_MAX;
m_might_have_children = eLazyBoolCalculate;
} else {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
- "filter said caches are still valid",
- GetName().AsCString());
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said caches are still valid",
+ GetName().AsCString());
}
m_provides_value = eLazyBoolCalculate;
@@ -201,18 +199,18 @@ bool ValueObjectSynthetic::UpdateValue() {
lldb::ValueObjectSP synth_val(m_synth_filter_up->GetSyntheticValue());
if (synth_val && synth_val->CanProvideValue()) {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
- "filter said it can provide a value",
- GetName().AsCString());
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said it can provide a value",
+ GetName().AsCString());
m_provides_value = eLazyBoolYes;
CopyValueData(synth_val.get());
} else {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
- "filter said it will not provide a value",
- GetName().AsCString());
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said it will not provide a value",
+ GetName().AsCString());
m_provides_value = eLazyBoolNo;
CopyValueData(m_parent);
@@ -226,32 +224,32 @@ lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx,
bool can_create) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving "
- "child at index %zu",
- GetName().AsCString(), idx);
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving "
+ "child at index %zu",
+ GetName().AsCString(), idx);
UpdateValueIfNeeded();
ValueObject *valobj;
if (!m_children_byindex.GetValueForKey(idx, valobj)) {
if (can_create && m_synth_filter_up != nullptr) {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
- "index %zu not cached and will be created",
- GetName().AsCString(), idx);
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu not cached and will be created",
+ GetName().AsCString(), idx);
lldb::ValueObjectSP synth_guy = m_synth_filter_up->GetChildAtIndex(idx);
- if (log)
- log->Printf(
- "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index "
- "%zu created as %p (is "
- "synthetic: %s)",
- GetName().AsCString(), idx, static_cast<void *>(synth_guy.get()),
- synth_guy.get()
- ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no")
- : "no");
+ LLDB_LOGF(
+ log,
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index "
+ "%zu created as %p (is "
+ "synthetic: %s)",
+ GetName().AsCString(), idx, static_cast<void *>(synth_guy.get()),
+ synth_guy.get()
+ ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no")
+ : "no");
if (!synth_guy)
return synth_guy;
@@ -263,20 +261,20 @@ lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx,
GetPreferredDisplayLanguage());
return synth_guy;
} else {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
- "index %zu not cached and cannot "
- "be created (can_create = %s, synth_filter = %p)",
- GetName().AsCString(), idx, can_create ? "yes" : "no",
- static_cast<void *>(m_synth_filter_up.get()));
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu not cached and cannot "
+ "be created (can_create = %s, synth_filter = %p)",
+ GetName().AsCString(), idx, can_create ? "yes" : "no",
+ static_cast<void *>(m_synth_filter_up.get()));
return lldb::ValueObjectSP();
}
} else {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
- "index %zu cached as %p",
- GetName().AsCString(), idx, static_cast<void *>(valobj));
+ LLDB_LOGF(log,
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu cached as %p",
+ GetName().AsCString(), idx, static_cast<void *>(valobj));
return valobj->GetSP();
}
@@ -322,7 +320,7 @@ lldb::ValueObjectSP ValueObjectSynthetic::GetNonSyntheticValue() {
void ValueObjectSynthetic::CopyValueData(ValueObject *source) {
m_value = (source->UpdateValueIfNeeded(), source->GetValue());
ExecutionContext exe_ctx(GetExecutionContextRef());
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
}
bool ValueObjectSynthetic::CanProvideValue() {
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index 5aee82493b28..33f9d5410843 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -221,7 +221,7 @@ bool ValueObjectVariable::UpdateValue() {
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
m_error =
- m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
break;
case Value::eValueTypeFileAddress:
@@ -250,7 +250,7 @@ bool ValueObjectVariable::UpdateValue() {
Value value(m_value);
value.SetContext(Value::eContextTypeVariable, variable);
m_error =
- value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
SetValueDidChange(value_type != old_value.GetValueType() ||
m_value.GetScalar() != old_value.GetScalar());
diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp
index dd2808a7cf7c..1eac372d79ec 100644
--- a/source/DataFormatters/FormatManager.cpp
+++ b/source/DataFormatters/FormatManager.cpp
@@ -30,7 +30,7 @@ struct FormatInfo {
// current format
};
-static FormatInfo g_format_infos[] = {
+static constexpr FormatInfo g_format_infos[] = {
{eFormatDefault, '\0', "default"},
{eFormatBoolean, 'B', "boolean"},
{eFormatBinary, 'b', "binary"},
@@ -69,7 +69,13 @@ static FormatInfo g_format_infos[] = {
{eFormatAddressInfo, 'A', "address"},
{eFormatHexFloat, '\0', "hex float"},
{eFormatInstruction, 'i', "instruction"},
- {eFormatVoid, 'v', "void"}};
+ {eFormatVoid, 'v', "void"},
+ {eFormatUnicode8, 'u', "unicode8"},
+};
+
+static_assert((sizeof(g_format_infos) / sizeof(g_format_infos[0])) ==
+ kNumFormats,
+ "All formats must have a corresponding info entry.");
static uint32_t g_num_format_infos = llvm::array_lengthof(g_format_infos);
@@ -630,30 +636,29 @@ FormatManager::GetFormat(ValueObject &valobj,
TypeFormatImplSP retval;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (match_data.GetTypeForCache()) {
- if (log)
- log->Printf(
- "\n\n[FormatManager::GetFormat] Looking into cache for type %s",
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log,
+ "\n\n[FormatManager::GetFormat] Looking into cache for type %s",
+ match_data.GetTypeForCache().AsCString("<invalid>"));
if (m_format_cache.GetFormat(match_data.GetTypeForCache(), retval)) {
if (log) {
- log->Printf(
- "[FormatManager::GetFormat] Cache search success. Returning.");
+ LLDB_LOGF(
+ log, "[FormatManager::GetFormat] Cache search success. Returning.");
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
m_format_cache.GetCacheHits(),
m_format_cache.GetCacheMisses());
}
return retval;
}
- if (log)
- log->Printf(
- "[FormatManager::GetFormat] Cache search failed. Going normal route");
+ LLDB_LOGF(
+ log,
+ "[FormatManager::GetFormat] Cache search failed. Going normal route");
}
retval = m_categories_map.GetFormat(match_data);
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetFormat] Search failed. Giving language a "
- "chance.");
+ LLDB_LOGF(log,
+ "[FormatManager::GetFormat] Search failed. Giving language a "
+ "chance.");
for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
if (lang_category->Get(match_data, retval))
@@ -661,24 +666,22 @@ FormatManager::GetFormat(ValueObject &valobj,
}
}
if (retval) {
- if (log)
- log->Printf(
- "[FormatManager::GetFormat] Language search success. Returning.");
+ LLDB_LOGF(
+ log,
+ "[FormatManager::GetFormat] Language search success. Returning.");
return retval;
}
}
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetFormat] Search failed. Giving hardcoded "
- "a chance.");
+ LLDB_LOGF(log, "[FormatManager::GetFormat] Search failed. Giving hardcoded "
+ "a chance.");
retval = GetHardcodedFormat(match_data);
}
if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
- if (log)
- log->Printf("[FormatManager::GetFormat] Caching %p for type %s",
- static_cast<void *>(retval.get()),
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log, "[FormatManager::GetFormat] Caching %p for type %s",
+ static_cast<void *>(retval.get()),
+ match_data.GetTypeForCache().AsCString("<invalid>"));
m_format_cache.SetFormat(match_data.GetTypeForCache(), retval);
}
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
@@ -708,30 +711,29 @@ FormatManager::GetSummaryFormat(ValueObject &valobj,
TypeSummaryImplSP retval;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (match_data.GetTypeForCache()) {
- if (log)
- log->Printf("\n\n[FormatManager::GetSummaryFormat] Looking into cache "
- "for type %s",
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log,
+ "\n\n[FormatManager::GetSummaryFormat] Looking into cache "
+ "for type %s",
+ match_data.GetTypeForCache().AsCString("<invalid>"));
if (m_format_cache.GetSummary(match_data.GetTypeForCache(), retval)) {
if (log) {
- log->Printf("[FormatManager::GetSummaryFormat] Cache search success. "
- "Returning.");
+ LLDB_LOGF(log,
+ "[FormatManager::GetSummaryFormat] Cache search success. "
+ "Returning.");
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
m_format_cache.GetCacheHits(),
m_format_cache.GetCacheMisses());
}
return retval;
}
- if (log)
- log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. "
- "Going normal route");
+ LLDB_LOGF(log, "[FormatManager::GetSummaryFormat] Cache search failed. "
+ "Going normal route");
}
retval = m_categories_map.GetSummaryFormat(match_data);
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
- "language a chance.");
+ LLDB_LOGF(log, "[FormatManager::GetSummaryFormat] Search failed. Giving "
+ "language a chance.");
for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
if (lang_category->Get(match_data, retval))
@@ -739,24 +741,21 @@ FormatManager::GetSummaryFormat(ValueObject &valobj,
}
}
if (retval) {
- if (log)
- log->Printf("[FormatManager::GetSummaryFormat] Language search "
- "success. Returning.");
+ LLDB_LOGF(log, "[FormatManager::GetSummaryFormat] Language search "
+ "success. Returning.");
return retval;
}
}
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetSummaryFormat] Search failed. Giving "
- "hardcoded a chance.");
+ LLDB_LOGF(log, "[FormatManager::GetSummaryFormat] Search failed. Giving "
+ "hardcoded a chance.");
retval = GetHardcodedSummaryFormat(match_data);
}
if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
- if (log)
- log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",
- static_cast<void *>(retval.get()),
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log, "[FormatManager::GetSummaryFormat] Caching %p for type %s",
+ static_cast<void *>(retval.get()),
+ match_data.GetTypeForCache().AsCString("<invalid>"));
m_format_cache.SetSummary(match_data.GetTypeForCache(), retval);
}
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
@@ -786,30 +785,29 @@ FormatManager::GetSyntheticChildren(ValueObject &valobj,
SyntheticChildrenSP retval;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (match_data.GetTypeForCache()) {
- if (log)
- log->Printf("\n\n[FormatManager::GetSyntheticChildren] Looking into "
- "cache for type %s",
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log,
+ "\n\n[FormatManager::GetSyntheticChildren] Looking into "
+ "cache for type %s",
+ match_data.GetTypeForCache().AsCString("<invalid>"));
if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), retval)) {
if (log) {
- log->Printf("[FormatManager::GetSyntheticChildren] Cache search "
- "success. Returning.");
+ LLDB_LOGF(log, "[FormatManager::GetSyntheticChildren] Cache search "
+ "success. Returning.");
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
m_format_cache.GetCacheHits(),
m_format_cache.GetCacheMisses());
}
return retval;
}
- if (log)
- log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. "
- "Going normal route");
+ LLDB_LOGF(log, "[FormatManager::GetSyntheticChildren] Cache search failed. "
+ "Going normal route");
}
retval = m_categories_map.GetSyntheticChildren(match_data);
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
- "language a chance.");
+ LLDB_LOGF(log,
+ "[FormatManager::GetSyntheticChildren] Search failed. Giving "
+ "language a chance.");
for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
if (lang_category->Get(match_data, retval))
@@ -817,25 +815,23 @@ FormatManager::GetSyntheticChildren(ValueObject &valobj,
}
}
if (retval) {
- if (log)
- log->Printf("[FormatManager::GetSyntheticChildren] Language search "
- "success. Returning.");
+ LLDB_LOGF(log, "[FormatManager::GetSyntheticChildren] Language search "
+ "success. Returning.");
return retval;
}
}
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetSyntheticChildren] Search failed. Giving "
- "hardcoded a chance.");
+ LLDB_LOGF(log,
+ "[FormatManager::GetSyntheticChildren] Search failed. Giving "
+ "hardcoded a chance.");
retval = GetHardcodedSyntheticChildren(match_data);
}
if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
- if (log)
- log->Printf(
- "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
- static_cast<void *>(retval.get()),
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log,
+ "[FormatManager::GetSyntheticChildren] Caching %p for type %s",
+ static_cast<void *>(retval.get()),
+ match_data.GetTypeForCache().AsCString("<invalid>"));
m_format_cache.SetSynthetic(match_data.GetTypeForCache(), retval);
}
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
@@ -851,13 +847,13 @@ FormatManager::GetValidator(ValueObject &valobj,
TypeValidatorImplSP retval;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (match_data.GetTypeForCache()) {
- if (log)
- log->Printf(
- "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(
+ log, "\n\n[FormatManager::GetValidator] Looking into cache for type %s",
+ match_data.GetTypeForCache().AsCString("<invalid>"));
if (m_format_cache.GetValidator(match_data.GetTypeForCache(), retval)) {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"[FormatManager::GetValidator] Cache search success. Returning.");
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
m_format_cache.GetCacheHits(),
@@ -865,16 +861,14 @@ FormatManager::GetValidator(ValueObject &valobj,
}
return retval;
}
- if (log)
- log->Printf("[FormatManager::GetValidator] Cache search failed. Going "
- "normal route");
+ LLDB_LOGF(log, "[FormatManager::GetValidator] Cache search failed. Going "
+ "normal route");
}
retval = m_categories_map.GetValidator(match_data);
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetValidator] Search failed. Giving "
- "language a chance.");
+ LLDB_LOGF(log, "[FormatManager::GetValidator] Search failed. Giving "
+ "language a chance.");
for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) {
if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) {
if (lang_category->Get(match_data, retval))
@@ -882,24 +876,21 @@ FormatManager::GetValidator(ValueObject &valobj,
}
}
if (retval) {
- if (log)
- log->Printf("[FormatManager::GetValidator] Language search success. "
- "Returning.");
+ LLDB_LOGF(log, "[FormatManager::GetValidator] Language search success. "
+ "Returning.");
return retval;
}
}
if (!retval) {
- if (log)
- log->Printf("[FormatManager::GetValidator] Search failed. Giving "
- "hardcoded a chance.");
+ LLDB_LOGF(log, "[FormatManager::GetValidator] Search failed. Giving "
+ "hardcoded a chance.");
retval = GetHardcodedValidator(match_data);
}
if (match_data.GetTypeForCache() && (!retval || !retval->NonCacheable())) {
- if (log)
- log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
- static_cast<void *>(retval.get()),
- match_data.GetTypeForCache().AsCString("<invalid>"));
+ LLDB_LOGF(log, "[FormatManager::GetValidator] Caching %p for type %s",
+ static_cast<void *>(retval.get()),
+ match_data.GetTypeForCache().AsCString("<invalid>"));
m_format_cache.SetValidator(match_data.GetTypeForCache(), retval);
}
LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}",
@@ -961,10 +952,7 @@ void FormatManager::LoadSystemFormatters() {
lldb::TypeSummaryImplSP string_array_format(
new StringSummaryFormat(string_array_flags, "${var%s}"));
- lldb::RegularExpressionSP any_size_char_arr(
- new RegularExpression(llvm::StringRef("char \\[[0-9]+\\]")));
- lldb::RegularExpressionSP any_size_wchar_arr(
- new RegularExpression(llvm::StringRef("wchar_t \\[[0-9]+\\]")));
+ RegularExpression any_size_char_arr(llvm::StringRef("char \\[[0-9]+\\]"));
TypeCategoryImpl::SharedPointer sys_category_sp =
GetCategory(m_system_category_name);
@@ -973,8 +961,8 @@ void FormatManager::LoadSystemFormatters() {
string_format);
sys_category_sp->GetTypeSummariesContainer()->Add(
ConstString("unsigned char *"), string_format);
- sys_category_sp->GetRegexTypeSummariesContainer()->Add(any_size_char_arr,
- string_array_format);
+ sys_category_sp->GetRegexTypeSummariesContainer()->Add(
+ std::move(any_size_char_arr), string_array_format);
lldb::TypeSummaryImplSP ostype_summary(
new StringSummaryFormat(TypeSummaryImpl::Flags()
diff --git a/source/DataFormatters/FormattersHelpers.cpp b/source/DataFormatters/FormattersHelpers.cpp
index 8f007df03faa..b2a5a17595c8 100644
--- a/source/DataFormatters/FormattersHelpers.cpp
+++ b/source/DataFormatters/FormattersHelpers.cpp
@@ -29,10 +29,10 @@ void lldb_private::formatters::AddFormat(
if (regex)
category_sp->GetRegexTypeFormatsContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- format_sp);
+ RegularExpression(type_name.GetStringRef()), format_sp);
else
- category_sp->GetTypeFormatsContainer()->Add(type_name, format_sp);
+ category_sp->GetTypeFormatsContainer()->Add(std::move(type_name),
+ format_sp);
}
void lldb_private::formatters::AddSummary(
@@ -40,10 +40,10 @@ void lldb_private::formatters::AddSummary(
ConstString type_name, bool regex) {
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- summary_sp);
+ RegularExpression(type_name.GetStringRef()), summary_sp);
else
- category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
+ category_sp->GetTypeSummariesContainer()->Add(std::move(type_name),
+ summary_sp);
}
void lldb_private::formatters::AddStringSummary(
@@ -53,10 +53,10 @@ void lldb_private::formatters::AddStringSummary(
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- summary_sp);
+ RegularExpression(type_name.GetStringRef()), summary_sp);
else
- category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
+ category_sp->GetTypeSummariesContainer()->Add(std::move(type_name),
+ summary_sp);
}
void lldb_private::formatters::AddOneLineSummary(
@@ -67,10 +67,10 @@ void lldb_private::formatters::AddOneLineSummary(
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- summary_sp);
+ RegularExpression(type_name.GetStringRef()), summary_sp);
else
- category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
+ category_sp->GetTypeSummariesContainer()->Add(std::move(type_name),
+ summary_sp);
}
void lldb_private::formatters::AddCXXSummary(
@@ -81,10 +81,10 @@ void lldb_private::formatters::AddCXXSummary(
new CXXFunctionSummaryFormat(flags, funct, description));
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- summary_sp);
+ RegularExpression(type_name.GetStringRef()), summary_sp);
else
- category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
+ category_sp->GetTypeSummariesContainer()->Add(std::move(type_name),
+ summary_sp);
}
void lldb_private::formatters::AddCXXSynthetic(
@@ -96,10 +96,10 @@ void lldb_private::formatters::AddCXXSynthetic(
new CXXSyntheticChildren(flags, description, generator));
if (regex)
category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- synth_sp);
+ RegularExpression(type_name.GetStringRef()), synth_sp);
else
- category_sp->GetTypeSyntheticsContainer()->Add(type_name, synth_sp);
+ category_sp->GetTypeSyntheticsContainer()->Add(std::move(type_name),
+ synth_sp);
}
void lldb_private::formatters::AddFilter(
@@ -111,10 +111,10 @@ void lldb_private::formatters::AddFilter(
filter_sp->AddExpressionPath(child);
if (regex)
category_sp->GetRegexTypeFiltersContainer()->Add(
- RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
- filter_sp);
+ RegularExpression(type_name.GetStringRef()), filter_sp);
else
- category_sp->GetTypeFiltersContainer()->Add(type_name, filter_sp);
+ category_sp->GetTypeFiltersContainer()->Add(std::move(type_name),
+ filter_sp);
}
size_t lldb_private::formatters::ExtractIndexFromString(const char *item_name) {
diff --git a/source/DataFormatters/TypeCategoryMap.cpp b/source/DataFormatters/TypeCategoryMap.cpp
index 69757c9844e1..b1075e9878d8 100644
--- a/source/DataFormatters/TypeCategoryMap.cpp
+++ b/source/DataFormatters/TypeCategoryMap.cpp
@@ -180,7 +180,8 @@ TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
if (log) {
for (auto match : match_data.GetMatchesVector()) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
"%" PRIu32,
match.GetTypeName().GetCString(),
@@ -194,18 +195,16 @@ TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeFormatImplSP current_format;
- if (log)
- log->Printf("[TypeCategoryMap::GetFormat] Trying to use category %s",
- category_sp->GetName());
+ LLDB_LOGF(log, "[TypeCategoryMap::GetFormat] Trying to use category %s",
+ category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
- if (log)
- log->Printf(
- "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
+ LLDB_LOGF(log,
+ "[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
return lldb::TypeFormatImplSP();
}
@@ -220,7 +219,8 @@ TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
if (log) {
for (auto match : match_data.GetMatchesVector()) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
"reason = %" PRIu32,
match.GetTypeName().GetCString(),
@@ -234,18 +234,17 @@ TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeSummaryImplSP current_format;
- if (log)
- log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s",
- category_sp->GetName());
+ LLDB_LOGF(log, "[CategoryMap::GetSummaryFormat] Trying to use category %s",
+ category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
- if (log)
- log->Printf(
- "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
+ LLDB_LOGF(
+ log,
+ "[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
return lldb::TypeSummaryImplSP();
}
@@ -261,7 +260,8 @@ TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
if (log) {
for (auto match : match_data.GetMatchesVector()) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
"reason = %" PRIu32,
match.GetTypeName().GetCString(),
@@ -275,19 +275,18 @@ TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::SyntheticChildrenSP current_format;
- if (log)
- log->Printf(
- "[CategoryMap::GetSyntheticChildren] Trying to use category %s",
- category_sp->GetName());
+ LLDB_LOGF(log,
+ "[CategoryMap::GetSyntheticChildren] Trying to use category %s",
+ category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
- if (log)
- log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
- "empty SP");
+ LLDB_LOGF(log,
+ "[CategoryMap::GetSyntheticChildren] nothing found - returning "
+ "empty SP");
return lldb::SyntheticChildrenSP();
}
@@ -302,7 +301,8 @@ TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
if (log) {
for (auto match : match_data.GetMatchesVector()) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
"%" PRIu32,
match.GetTypeName().GetCString(),
@@ -316,18 +316,16 @@ TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeValidatorImplSP current_format;
- if (log)
- log->Printf("[CategoryMap::GetValidator] Trying to use category %s",
- category_sp->GetName());
+ LLDB_LOGF(log, "[CategoryMap::GetValidator] Trying to use category %s",
+ category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
- if (log)
- log->Printf(
- "[CategoryMap::GetValidator] nothing found - returning empty SP");
+ LLDB_LOGF(log,
+ "[CategoryMap::GetValidator] nothing found - returning empty SP");
return lldb::TypeValidatorImplSP();
}
diff --git a/source/DataFormatters/TypeFormat.cpp b/source/DataFormatters/TypeFormat.cpp
index b526e9a744bc..b272c2e8dc3b 100644
--- a/source/DataFormatters/TypeFormat.cpp
+++ b/source/DataFormatters/TypeFormat.cpp
@@ -164,7 +164,7 @@ bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj,
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
images.FindTypes(nullptr, m_enum_type, false, UINT32_MAX,
searched_symbol_files, types);
- if (types.GetSize() == 0)
+ if (types.Empty())
return false;
for (lldb::TypeSP type_sp : types.Types()) {
if (!type_sp)
diff --git a/source/DataFormatters/ValueObjectPrinter.cpp b/source/DataFormatters/ValueObjectPrinter.cpp
index 409cffed9b0f..fa43c677a194 100644
--- a/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/source/DataFormatters/ValueObjectPrinter.cpp
@@ -456,7 +456,7 @@ bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed,
if (object_desc[object_end] == '\n')
m_stream->Printf("%s", object_desc);
else
- m_stream->Printf("%s\n", object_desc);
+ m_stream->Printf("%s\n", object_desc);
return true;
} else if (!value_printed && !summary_printed)
return true;
@@ -751,34 +751,30 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
bool summary_printed) {
- // this flag controls whether we tried to display a description for this
- // object and failed if that happens, we want to display the children, if any
+ // This flag controls whether we tried to display a description for this
+ // object and failed if that happens, we want to display the children if any.
bool is_failed_description =
!PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
- auto curr_ptr_depth = m_ptr_depth;
- bool print_children =
+ DumpValueObjectOptions::PointerDepth curr_ptr_depth = m_ptr_depth;
+ const bool print_children =
ShouldPrintChildren(is_failed_description, curr_ptr_depth);
- bool print_oneline =
+ const bool print_oneline =
(curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types ||
!m_options.m_allow_oneliner_mode || m_options.m_flat_output ||
(m_options.m_pointer_as_array) || m_options.m_show_location)
? false
: DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
- bool is_instance_ptr = IsInstancePointer();
- uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;
-
- if (print_children && is_instance_ptr) {
- instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
+ if (print_children && IsInstancePointer()) {
+ uint64_t instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
if (m_printed_instance_pointers->count(instance_ptr_value)) {
- // we already printed this instance-is-pointer thing, so don't expand it
+ // We already printed this instance-is-pointer thing, so don't expand it.
m_stream->PutCString(" {...}\n");
-
- // we're done here - get out fast
return;
- } else
- m_printed_instance_pointers->emplace(
- instance_ptr_value); // remember this guy for future reference
+ } else {
+ // Remember this guy for future reference.
+ m_printed_instance_pointers->emplace(instance_ptr_value);
+ }
}
if (print_children) {
diff --git a/source/DataFormatters/VectorType.cpp b/source/DataFormatters/VectorType.cpp
index 18880f72ef2e..26fc03a4cdc2 100644
--- a/source/DataFormatters/VectorType.cpp
+++ b/source/DataFormatters/VectorType.cpp
@@ -15,6 +15,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -219,13 +220,20 @@ public:
CompilerType parent_type(m_backend.GetCompilerType());
CompilerType element_type;
parent_type.IsVectorType(&element_type, nullptr);
- TargetSP target_sp(m_backend.GetTargetSP());
- m_child_type = ::GetCompilerTypeForFormat(
- m_parent_format, element_type,
- target_sp
- ? target_sp->GetScratchTypeSystemForLanguage(nullptr,
- lldb::eLanguageTypeC)
- : nullptr);
+ TypeSystem *type_system = nullptr;
+ if (auto target_sp = m_backend.GetTargetSP()) {
+ auto type_system_or_err =
+ target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
+ std::move(err), "Unable to update from scratch TypeSystem");
+ } else {
+ type_system = &type_system_or_err.get();
+ }
+ }
+ m_child_type =
+ ::GetCompilerTypeForFormat(m_parent_format, element_type, type_system);
m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
return false;
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp
index a9d365325d9e..3789d9147737 100644
--- a/source/Expression/DWARFExpression.cpp
+++ b/source/Expression/DWARFExpression.cpp
@@ -33,6 +33,7 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StackID.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
@@ -59,12 +60,9 @@ DWARFExpression::DWARFExpression()
DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
const DataExtractor &data,
- const DWARFUnit *dwarf_cu,
- lldb::offset_t data_offset,
- lldb::offset_t data_length)
- : m_module_wp(), m_data(data, data_offset, data_length),
- m_dwarf_cu(dwarf_cu), m_reg_kind(eRegisterKindDWARF),
- m_loclist_slide(LLDB_INVALID_ADDRESS) {
+ const DWARFUnit *dwarf_cu)
+ : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu),
+ m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {
if (module_sp)
m_module_wp = module_sp;
}
@@ -90,387 +88,10 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset,
lldb::offset_t length,
lldb::DescriptionLevel level,
ABI *abi) const {
- if (!m_data.ValidOffsetForDataOfSize(offset, length))
- return;
- const lldb::offset_t start_offset = offset;
- const lldb::offset_t end_offset = offset + length;
- while (m_data.ValidOffset(offset) && offset < end_offset) {
- const lldb::offset_t op_offset = offset;
- const uint8_t op = m_data.GetU8(&offset);
-
- switch (level) {
- default:
- break;
-
- case lldb::eDescriptionLevelBrief:
- if (op_offset > start_offset)
- s->PutChar(' ');
- break;
-
- case lldb::eDescriptionLevelFull:
- case lldb::eDescriptionLevelVerbose:
- if (op_offset > start_offset)
- s->EOL();
- s->Indent();
- if (level == lldb::eDescriptionLevelFull)
- break;
- // Fall through for verbose and print offset and DW_OP prefix..
- s->Printf("0x%8.8" PRIx64 ": %s", op_offset,
- op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
- break;
- }
-
- switch (op) {
- case DW_OP_addr:
- *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") ";
- break; // 0x03 1 address
- case DW_OP_deref:
- *s << "DW_OP_deref";
- break; // 0x06
- case DW_OP_const1u:
- s->Printf("DW_OP_const1u(0x%2.2x)", m_data.GetU8(&offset));
- break; // 0x08 1 1-byte constant
- case DW_OP_const1s:
- s->Printf("DW_OP_const1s(0x%2.2x)", m_data.GetU8(&offset));
- break; // 0x09 1 1-byte constant
- case DW_OP_const2u:
- s->Printf("DW_OP_const2u(0x%4.4x)", m_data.GetU16(&offset));
- break; // 0x0a 1 2-byte constant
- case DW_OP_const2s:
- s->Printf("DW_OP_const2s(0x%4.4x)", m_data.GetU16(&offset));
- break; // 0x0b 1 2-byte constant
- case DW_OP_const4u:
- s->Printf("DW_OP_const4u(0x%8.8x)", m_data.GetU32(&offset));
- break; // 0x0c 1 4-byte constant
- case DW_OP_const4s:
- s->Printf("DW_OP_const4s(0x%8.8x)", m_data.GetU32(&offset));
- break; // 0x0d 1 4-byte constant
- case DW_OP_const8u:
- s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ")", m_data.GetU64(&offset));
- break; // 0x0e 1 8-byte constant
- case DW_OP_const8s:
- s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ")", m_data.GetU64(&offset));
- break; // 0x0f 1 8-byte constant
- case DW_OP_constu:
- s->Printf("DW_OP_constu(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
- break; // 0x10 1 ULEB128 constant
- case DW_OP_consts:
- s->Printf("DW_OP_consts(0x%" PRId64 ")", m_data.GetSLEB128(&offset));
- break; // 0x11 1 SLEB128 constant
- case DW_OP_dup:
- s->PutCString("DW_OP_dup");
- break; // 0x12
- case DW_OP_drop:
- s->PutCString("DW_OP_drop");
- break; // 0x13
- case DW_OP_over:
- s->PutCString("DW_OP_over");
- break; // 0x14
- case DW_OP_pick:
- s->Printf("DW_OP_pick(0x%2.2x)", m_data.GetU8(&offset));
- break; // 0x15 1 1-byte stack index
- case DW_OP_swap:
- s->PutCString("DW_OP_swap");
- break; // 0x16
- case DW_OP_rot:
- s->PutCString("DW_OP_rot");
- break; // 0x17
- case DW_OP_xderef:
- s->PutCString("DW_OP_xderef");
- break; // 0x18
- case DW_OP_abs:
- s->PutCString("DW_OP_abs");
- break; // 0x19
- case DW_OP_and:
- s->PutCString("DW_OP_and");
- break; // 0x1a
- case DW_OP_div:
- s->PutCString("DW_OP_div");
- break; // 0x1b
- case DW_OP_minus:
- s->PutCString("DW_OP_minus");
- break; // 0x1c
- case DW_OP_mod:
- s->PutCString("DW_OP_mod");
- break; // 0x1d
- case DW_OP_mul:
- s->PutCString("DW_OP_mul");
- break; // 0x1e
- case DW_OP_neg:
- s->PutCString("DW_OP_neg");
- break; // 0x1f
- case DW_OP_not:
- s->PutCString("DW_OP_not");
- break; // 0x20
- case DW_OP_or:
- s->PutCString("DW_OP_or");
- break; // 0x21
- case DW_OP_plus:
- s->PutCString("DW_OP_plus");
- break; // 0x22
- case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
- s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ")",
- m_data.GetULEB128(&offset));
- break;
-
- case DW_OP_shl:
- s->PutCString("DW_OP_shl");
- break; // 0x24
- case DW_OP_shr:
- s->PutCString("DW_OP_shr");
- break; // 0x25
- case DW_OP_shra:
- s->PutCString("DW_OP_shra");
- break; // 0x26
- case DW_OP_xor:
- s->PutCString("DW_OP_xor");
- break; // 0x27
- case DW_OP_skip:
- s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset));
- break; // 0x2f 1 signed 2-byte constant
- case DW_OP_bra:
- s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset));
- break; // 0x28 1 signed 2-byte constant
- case DW_OP_eq:
- s->PutCString("DW_OP_eq");
- break; // 0x29
- case DW_OP_ge:
- s->PutCString("DW_OP_ge");
- break; // 0x2a
- case DW_OP_gt:
- s->PutCString("DW_OP_gt");
- break; // 0x2b
- case DW_OP_le:
- s->PutCString("DW_OP_le");
- break; // 0x2c
- case DW_OP_lt:
- s->PutCString("DW_OP_lt");
- break; // 0x2d
- case DW_OP_ne:
- s->PutCString("DW_OP_ne");
- break; // 0x2e
-
- case DW_OP_lit0: // 0x30
- case DW_OP_lit1: // 0x31
- case DW_OP_lit2: // 0x32
- case DW_OP_lit3: // 0x33
- case DW_OP_lit4: // 0x34
- case DW_OP_lit5: // 0x35
- case DW_OP_lit6: // 0x36
- case DW_OP_lit7: // 0x37
- case DW_OP_lit8: // 0x38
- case DW_OP_lit9: // 0x39
- case DW_OP_lit10: // 0x3A
- case DW_OP_lit11: // 0x3B
- case DW_OP_lit12: // 0x3C
- case DW_OP_lit13: // 0x3D
- case DW_OP_lit14: // 0x3E
- case DW_OP_lit15: // 0x3F
- case DW_OP_lit16: // 0x40
- case DW_OP_lit17: // 0x41
- case DW_OP_lit18: // 0x42
- case DW_OP_lit19: // 0x43
- case DW_OP_lit20: // 0x44
- case DW_OP_lit21: // 0x45
- case DW_OP_lit22: // 0x46
- case DW_OP_lit23: // 0x47
- case DW_OP_lit24: // 0x48
- case DW_OP_lit25: // 0x49
- case DW_OP_lit26: // 0x4A
- case DW_OP_lit27: // 0x4B
- case DW_OP_lit28: // 0x4C
- case DW_OP_lit29: // 0x4D
- case DW_OP_lit30: // 0x4E
- case DW_OP_lit31:
- s->Printf("DW_OP_lit%i", op - DW_OP_lit0);
- break; // 0x4f
-
- case DW_OP_reg0: // 0x50
- case DW_OP_reg1: // 0x51
- case DW_OP_reg2: // 0x52
- case DW_OP_reg3: // 0x53
- case DW_OP_reg4: // 0x54
- case DW_OP_reg5: // 0x55
- case DW_OP_reg6: // 0x56
- case DW_OP_reg7: // 0x57
- case DW_OP_reg8: // 0x58
- case DW_OP_reg9: // 0x59
- case DW_OP_reg10: // 0x5A
- case DW_OP_reg11: // 0x5B
- case DW_OP_reg12: // 0x5C
- case DW_OP_reg13: // 0x5D
- case DW_OP_reg14: // 0x5E
- case DW_OP_reg15: // 0x5F
- case DW_OP_reg16: // 0x60
- case DW_OP_reg17: // 0x61
- case DW_OP_reg18: // 0x62
- case DW_OP_reg19: // 0x63
- case DW_OP_reg20: // 0x64
- case DW_OP_reg21: // 0x65
- case DW_OP_reg22: // 0x66
- case DW_OP_reg23: // 0x67
- case DW_OP_reg24: // 0x68
- case DW_OP_reg25: // 0x69
- case DW_OP_reg26: // 0x6A
- case DW_OP_reg27: // 0x6B
- case DW_OP_reg28: // 0x6C
- case DW_OP_reg29: // 0x6D
- case DW_OP_reg30: // 0x6E
- case DW_OP_reg31: // 0x6F
- {
- uint32_t reg_num = op - DW_OP_reg0;
- if (abi) {
- RegisterInfo reg_info;
- if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
- if (reg_info.name) {
- s->PutCString(reg_info.name);
- break;
- } else if (reg_info.alt_name) {
- s->PutCString(reg_info.alt_name);
- break;
- }
- }
- }
- s->Printf("DW_OP_reg%u", reg_num);
- break;
- } break;
-
- case DW_OP_breg0:
- case DW_OP_breg1:
- case DW_OP_breg2:
- case DW_OP_breg3:
- case DW_OP_breg4:
- case DW_OP_breg5:
- case DW_OP_breg6:
- case DW_OP_breg7:
- case DW_OP_breg8:
- case DW_OP_breg9:
- case DW_OP_breg10:
- case DW_OP_breg11:
- case DW_OP_breg12:
- case DW_OP_breg13:
- case DW_OP_breg14:
- case DW_OP_breg15:
- case DW_OP_breg16:
- case DW_OP_breg17:
- case DW_OP_breg18:
- case DW_OP_breg19:
- case DW_OP_breg20:
- case DW_OP_breg21:
- case DW_OP_breg22:
- case DW_OP_breg23:
- case DW_OP_breg24:
- case DW_OP_breg25:
- case DW_OP_breg26:
- case DW_OP_breg27:
- case DW_OP_breg28:
- case DW_OP_breg29:
- case DW_OP_breg30:
- case DW_OP_breg31: {
- uint32_t reg_num = op - DW_OP_breg0;
- int64_t reg_offset = m_data.GetSLEB128(&offset);
- if (abi) {
- RegisterInfo reg_info;
- if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
- if (reg_info.name) {
- s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
- break;
- } else if (reg_info.alt_name) {
- s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
- break;
- }
- }
- }
- s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset);
- } break;
-
- case DW_OP_regx: // 0x90 1 ULEB128 register
- {
- uint32_t reg_num = m_data.GetULEB128(&offset);
- if (abi) {
- RegisterInfo reg_info;
- if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
- if (reg_info.name) {
- s->PutCString(reg_info.name);
- break;
- } else if (reg_info.alt_name) {
- s->PutCString(reg_info.alt_name);
- break;
- }
- }
- }
- s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num);
- break;
- } break;
- case DW_OP_fbreg: // 0x91 1 SLEB128 offset
- s->Printf("DW_OP_fbreg(%" PRIi64 ")", m_data.GetSLEB128(&offset));
- break;
- case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset
- {
- uint32_t reg_num = m_data.GetULEB128(&offset);
- int64_t reg_offset = m_data.GetSLEB128(&offset);
- if (abi) {
- RegisterInfo reg_info;
- if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) {
- if (reg_info.name) {
- s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
- break;
- } else if (reg_info.alt_name) {
- s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
- break;
- }
- }
- }
- s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num,
- reg_offset);
- } break;
- case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed
- s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
- break;
- case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved
- s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset));
- break;
- case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
- s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset));
- break;
- case DW_OP_nop:
- s->PutCString("DW_OP_nop");
- break; // 0x96
- case DW_OP_push_object_address:
- s->PutCString("DW_OP_push_object_address");
- break; // 0x97 DWARF3
- case DW_OP_call2: // 0x98 DWARF3 1 2-byte offset of DIE
- s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset));
- break;
- case DW_OP_call4: // 0x99 DWARF3 1 4-byte offset of DIE
- s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset));
- break;
- case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE
- s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset));
- break;
- case DW_OP_form_tls_address:
- s->PutCString("DW_OP_form_tls_address"); // 0x9b
- break;
- case DW_OP_GNU_addr_index: // 0xfb
- s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")",
- m_data.GetULEB128(&offset));
- break;
- case DW_OP_addrx:
- s->Printf("DW_OP_addrx(0x%" PRIx64 ")",
- m_data.GetULEB128(&offset));
- break;
- case DW_OP_GNU_const_index: // 0xfc
- s->Printf("DW_OP_GNU_const_index(0x%" PRIx64 ")",
- m_data.GetULEB128(&offset));
- break;
- case DW_OP_GNU_push_tls_address:
- s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0
- break;
- case DW_OP_APPLE_uninit:
- s->PutCString("DW_OP_APPLE_uninit"); // 0xF0
- break;
- }
- }
+ llvm::DWARFExpression(DataExtractor(m_data, offset, length).GetAsLLVM(),
+ llvm::dwarf::DWARF_VERSION, m_data.GetAddressByteSize())
+ .print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr,
+ nullptr);
}
void DWARFExpression::SetLocationListSlide(addr_t slide) {
@@ -583,6 +204,8 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
return false;
}
+/// Return the length in bytes of the set of operands for \p op. No guarantees
+/// are made on the state of \p data after this call.
static offset_t GetOpcodeDataSize(const DataExtractor &data,
const lldb::offset_t data_offset,
const uint8_t op) {
@@ -779,6 +402,12 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
return offset - data_offset;
}
+ case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block
+ {
+ uint64_t subexpr_len = data.GetULEB128(&offset);
+ return (offset - data_offset) + subexpr_len;
+ }
+
default:
break;
}
@@ -1007,6 +636,11 @@ bool DWARFExpression::LocationListContainsAddress(
if (lo_pc == 0 && hi_pc == 0)
break;
+ if ((m_data.GetAddressByteSize() == 4 && (lo_pc == UINT32_MAX)) ||
+ (m_data.GetAddressByteSize() == 8 && (lo_pc == UINT64_MAX))) {
+ loclist_base_addr = hi_pc + m_loclist_slide;
+ continue;
+ }
lo_pc += loclist_base_addr - m_loclist_slide;
hi_pc += loclist_base_addr - m_loclist_slide;
@@ -1042,6 +676,12 @@ bool DWARFExpression::GetLocation(addr_t base_addr, addr_t pc,
if (lo_pc == 0 && hi_pc == 0)
break;
+ if ((m_data.GetAddressByteSize() == 4 && (lo_pc == UINT32_MAX)) ||
+ (m_data.GetAddressByteSize() == 8 && (lo_pc == UINT64_MAX))) {
+ curr_base_addr = hi_pc + m_loclist_slide;
+ continue;
+ }
+
lo_pc += curr_base_addr - m_loclist_slide;
hi_pc += curr_base_addr - m_loclist_slide;
@@ -1074,6 +714,216 @@ bool DWARFExpression::DumpLocationForAddress(Stream *s,
return false;
}
+static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
+ ExecutionContext *exe_ctx,
+ RegisterContext *reg_ctx,
+ const DataExtractor &opcodes,
+ lldb::offset_t &opcode_offset,
+ Status *error_ptr, Log *log) {
+ // DW_OP_entry_value(sub-expr) describes the location a variable had upon
+ // function entry: this variable location is presumed to be optimized out at
+ // the current PC value. The caller of the function may have call site
+ // information that describes an alternate location for the variable (e.g. a
+ // constant literal, or a spilled stack value) in the parent frame.
+ //
+ // Example (this is pseudo-code & pseudo-DWARF, but hopefully illustrative):
+ //
+ // void child(int &sink, int x) {
+ // ...
+ // /* "x" gets optimized out. */
+ //
+ // /* The location of "x" here is: DW_OP_entry_value($reg2). */
+ // ++sink;
+ // }
+ //
+ // void parent() {
+ // int sink;
+ //
+ // /*
+ // * The callsite information emitted here is:
+ // *
+ // * DW_TAG_call_site
+ // * DW_AT_return_pc ... (for "child(sink, 123);")
+ // * DW_TAG_call_site_parameter (for "sink")
+ // * DW_AT_location ($reg1)
+ // * DW_AT_call_value ($SP - 8)
+ // * DW_TAG_call_site_parameter (for "x")
+ // * DW_AT_location ($reg2)
+ // * DW_AT_call_value ($literal 123)
+ // *
+ // * DW_TAG_call_site
+ // * DW_AT_return_pc ... (for "child(sink, 456);")
+ // * ...
+ // */
+ // child(sink, 123);
+ // child(sink, 456);
+ // }
+ //
+ // When the program stops at "++sink" within `child`, the debugger determines
+ // the call site by analyzing the return address. Once the call site is found,
+ // the debugger determines which parameter is referenced by DW_OP_entry_value
+ // and evaluates the corresponding location for that parameter in `parent`.
+
+ // 1. Find the function which pushed the current frame onto the stack.
+ if ((!exe_ctx || !exe_ctx->HasTargetScope()) || !reg_ctx) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no exe/reg context");
+ return false;
+ }
+
+ StackFrame *current_frame = exe_ctx->GetFramePtr();
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (!current_frame || !thread) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no current frame/thread");
+ return false;
+ }
+
+ Target &target = exe_ctx->GetTargetRef();
+ StackFrameSP parent_frame = nullptr;
+ addr_t return_pc = LLDB_INVALID_ADDRESS;
+ uint32_t current_frame_idx = current_frame->GetFrameIndex();
+ uint32_t num_frames = thread->GetStackFrameCount();
+ for (uint32_t parent_frame_idx = current_frame_idx + 1;
+ parent_frame_idx < num_frames; ++parent_frame_idx) {
+ parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);
+ // Require a valid sequence of frames.
+ if (!parent_frame)
+ break;
+
+ // Record the first valid return address, even if this is an inlined frame,
+ // in order to look up the associated call edge in the first non-inlined
+ // parent frame.
+ if (return_pc == LLDB_INVALID_ADDRESS) {
+ return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
+ LLDB_LOG(log,
+ "Evaluate_DW_OP_entry_value: immediate ancestor with pc = {0:x}",
+ return_pc);
+ }
+
+ // If we've found an inlined frame, skip it (these have no call site
+ // parameters).
+ if (parent_frame->IsInlined())
+ continue;
+
+ // We've found the first non-inlined parent frame.
+ break;
+ }
+ if (!parent_frame || !parent_frame->GetRegisterContext()) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no parent frame with reg ctx");
+ return false;
+ }
+
+ Function *parent_func =
+ parent_frame->GetSymbolContext(eSymbolContextFunction).function;
+ if (!parent_func) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no parent function");
+ return false;
+ }
+
+ // 2. Find the call edge in the parent function responsible for creating the
+ // current activation.
+ Function *current_func =
+ current_frame->GetSymbolContext(eSymbolContextFunction).function;
+ if (!current_func) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no current function");
+ return false;
+ }
+
+ CallEdge *call_edge = nullptr;
+ ModuleList &modlist = target.GetImages();
+ if (!parent_frame->IsArtificial()) {
+ // If the parent frame is not artificial, the current activation may be
+ // produced by an ambiguous tail call. In this case, refuse to proceed.
+ call_edge = parent_func->GetCallEdgeForReturnAddress(return_pc, target);
+ if (!call_edge) {
+ LLDB_LOG(log,
+ "Evaluate_DW_OP_entry_value: no call edge for retn-pc = {0:x} "
+ "in parent frame {1}",
+ return_pc, parent_func->GetName());
+ return false;
+ }
+ Function *callee_func = call_edge->GetCallee(modlist);
+ if (callee_func != current_func) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: ambiguous call sequence, "
+ "can't find real parent frame");
+ return false;
+ }
+ } else {
+ // The StackFrameList solver machinery has deduced that an unambiguous tail
+ // call sequence that produced the current activation. The first edge in
+ // the parent that points to the current function must be valid.
+ for (CallEdge &edge : parent_func->GetTailCallingEdges()) {
+ if (edge.GetCallee(modlist) == current_func) {
+ call_edge = &edge;
+ break;
+ }
+ }
+ }
+ if (!call_edge) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: no unambiguous edge from parent "
+ "to current function");
+ return false;
+ }
+
+ // 3. Attempt to locate the DW_OP_entry_value expression in the set of
+ // available call site parameters. If found, evaluate the corresponding
+ // parameter in the context of the parent frame.
+ const uint32_t subexpr_len = opcodes.GetULEB128(&opcode_offset);
+ const void *subexpr_data = opcodes.GetData(&opcode_offset, subexpr_len);
+ if (!subexpr_data) {
+ LLDB_LOG(log, "Evaluate_DW_OP_entry_value: subexpr could not be read");
+ return false;
+ }
+
+ const CallSiteParameter *matched_param = nullptr;
+ for (const CallSiteParameter &param : call_edge->GetCallSiteParameters()) {
+ DataExtractor param_subexpr_extractor;
+ if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))
+ continue;
+ lldb::offset_t param_subexpr_offset = 0;
+ const void *param_subexpr_data =
+ param_subexpr_extractor.GetData(&param_subexpr_offset, subexpr_len);
+ if (!param_subexpr_data ||
+ param_subexpr_extractor.BytesLeft(param_subexpr_offset) != 0)
+ continue;
+
+ // At this point, the DW_OP_entry_value sub-expression and the callee-side
+ // expression in the call site parameter are known to have the same length.
+ // Check whether they are equal.
+ //
+ // Note that an equality check is sufficient: the contents of the
+ // DW_OP_entry_value subexpression are only used to identify the right call
+ // site parameter in the parent, and do not require any special handling.
+ if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {
+ matched_param = &param;
+ break;
+ }
+ }
+ if (!matched_param) {
+ LLDB_LOG(log,
+ "Evaluate_DW_OP_entry_value: no matching call site param found");
+ return false;
+ }
+
+ // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
+ // subexpresion whenever llvm does.
+ Value result;
+ ExecutionContext parent_exe_ctx = *exe_ctx;
+ parent_exe_ctx.SetFrameSP(parent_frame);
+ const DWARFExpression &param_expr = matched_param->LocationInCaller;
+ if (!param_expr.Evaluate(&parent_exe_ctx,
+ parent_frame->GetRegisterContext().get(),
+ /*loclist_base_addr=*/LLDB_INVALID_ADDRESS,
+ /*initial_value_ptr=*/nullptr,
+ /*object_address_ptr=*/nullptr, result, error_ptr)) {
+ LLDB_LOG(log,
+ "Evaluate_DW_OP_entry_value: call site param evaluation failed");
+ return false;
+ }
+
+ stack.push_back(result);
+ return true;
+}
+
bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr,
@@ -1128,6 +978,13 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
if (lo_pc == 0 && hi_pc == 0)
break;
+ if ((m_data.GetAddressByteSize() == 4 &&
+ (lo_pc == UINT32_MAX)) ||
+ (m_data.GetAddressByteSize() == 8 &&
+ (lo_pc == UINT64_MAX))) {
+ curr_loclist_base_load_addr = hi_pc + m_loclist_slide;
+ continue;
+ }
lo_pc += curr_loclist_base_load_addr - m_loclist_slide;
hi_pc += curr_loclist_base_load_addr - m_loclist_slide;
@@ -1135,9 +992,9 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
if (length > 0 && lo_pc <= pc && pc < hi_pc) {
return DWARFExpression::Evaluate(
- exe_ctx, reg_ctx, module_sp, m_data, m_dwarf_cu, offset, length,
- m_reg_kind, initial_value_ptr, object_address_ptr, result,
- error_ptr);
+ exe_ctx, reg_ctx, module_sp,
+ DataExtractor(m_data, offset, length), m_dwarf_cu, m_reg_kind,
+ initial_value_ptr, object_address_ptr, result, error_ptr);
}
offset += length;
}
@@ -1148,20 +1005,19 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
}
// Not a location list, just a single expression.
- return DWARFExpression::Evaluate(
- exe_ctx, reg_ctx, module_sp, m_data, m_dwarf_cu, 0, m_data.GetByteSize(),
- m_reg_kind, initial_value_ptr, object_address_ptr, result, error_ptr);
+ return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, m_data,
+ m_dwarf_cu, m_reg_kind, initial_value_ptr,
+ object_address_ptr, result, error_ptr);
}
bool DWARFExpression::Evaluate(
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
- const DWARFUnit *dwarf_cu, const lldb::offset_t opcodes_offset,
- const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind,
+ const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
const Value *initial_value_ptr, const Value *object_address_ptr,
Value &result, Status *error_ptr) {
- if (opcodes_length == 0) {
+ if (opcodes.GetByteSize() == 0) {
if (error_ptr)
error_ptr->SetErrorString(
"no location, value may have been optimized out");
@@ -1182,8 +1038,7 @@ bool DWARFExpression::Evaluate(
if (initial_value_ptr)
stack.push_back(*initial_value_ptr);
- lldb::offset_t offset = opcodes_offset;
- const lldb::offset_t end_offset = opcodes_offset + opcodes_length;
+ lldb::offset_t offset = 0;
Value tmp;
uint32_t reg_num;
@@ -1191,30 +1046,24 @@ bool DWARFExpression::Evaluate(
uint64_t op_piece_offset = 0;
Value pieces; // Used for DW_OP_piece
- // Make sure all of the data is available in opcodes.
- if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length)) {
- if (error_ptr)
- error_ptr->SetErrorString(
- "invalid offset and/or length for opcodes buffer.");
- return false;
- }
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- while (opcodes.ValidOffset(offset) && offset < end_offset) {
+ while (opcodes.ValidOffset(offset)) {
const lldb::offset_t op_offset = offset;
const uint8_t op = opcodes.GetU8(&offset);
if (log && log->GetVerbose()) {
size_t count = stack.size();
- log->Printf("Stack before operation has %" PRIu64 " values:",
- (uint64_t)count);
+ LLDB_LOGF(log, "Stack before operation has %" PRIu64 " values:",
+ (uint64_t)count);
for (size_t i = 0; i < count; ++i) {
StreamString new_value;
new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
stack[i].Dump(&new_value);
- log->Printf(" %s", new_value.GetData());
+ LLDB_LOGF(log, " %s", new_value.GetData());
}
- log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
+ LLDB_LOGF(log, "0x%8.8" PRIx64 ": %s", op_offset,
+ DW_OP_value_to_name(op));
}
switch (op) {
@@ -1945,7 +1794,7 @@ bool DWARFExpression::Evaluate(
case DW_OP_skip: {
int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
lldb::offset_t new_offset = offset + skip_offset;
- if (new_offset >= opcodes_offset && new_offset < end_offset)
+ if (opcodes.ValidOffset(new_offset))
offset = new_offset;
else {
if (error_ptr)
@@ -1974,7 +1823,7 @@ bool DWARFExpression::Evaluate(
Scalar zero(0);
if (tmp.ResolveValue(exe_ctx) != zero) {
lldb::offset_t new_offset = offset + bra_offset;
- if (new_offset >= opcodes_offset && new_offset < end_offset)
+ if (opcodes.ValidOffset(new_offset))
offset = new_offset;
else {
if (error_ptr)
@@ -2570,6 +2419,83 @@ bool DWARFExpression::Evaluate(
stack.back().SetValueType(Value::eValueTypeScalar);
break;
+ // OPCODE: DW_OP_convert
+ // OPERANDS: 1
+ // A ULEB128 that is either a DIE offset of a
+ // DW_TAG_base_type or 0 for the generic (pointer-sized) type.
+ //
+ // DESCRIPTION: Pop the top stack element, convert it to a
+ // different type, and push the result.
+ case DW_OP_convert: {
+ if (stack.size() < 1) {
+ if (error_ptr)
+ error_ptr->SetErrorString(
+ "Expression stack needs at least 1 item for DW_OP_convert.");
+ return false;
+ }
+ const uint64_t die_offset = opcodes.GetULEB128(&offset);
+ Scalar::Type type = Scalar::e_void;
+ uint64_t bit_size;
+ if (die_offset == 0) {
+ // The generic type has the size of an address on the target
+ // machine and an unspecified signedness. Scalar has no
+ // "unspecified signedness", so we use unsigned types.
+ if (!module_sp) {
+ if (error_ptr)
+ error_ptr->SetErrorString("No module");
+ return false;
+ }
+ bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
+ if (!bit_size) {
+ if (error_ptr)
+ error_ptr->SetErrorString("unspecified architecture");
+ return false;
+ }
+ type = Scalar::GetBestTypeForBitSize(bit_size, false);
+ } else {
+ // Retrieve the type DIE that the value is being converted to.
+ // FIXME: the constness has annoying ripple effects.
+ DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
+ if (!die) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
+ return false;
+ }
+ uint64_t encoding =
+ die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
+ bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+ if (!bit_size)
+ bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
+ if (!bit_size) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
+ return false;
+ }
+ switch (encoding) {
+ case DW_ATE_signed:
+ case DW_ATE_signed_char:
+ type = Scalar::GetBestTypeForBitSize(bit_size, true);
+ break;
+ case DW_ATE_unsigned:
+ case DW_ATE_unsigned_char:
+ type = Scalar::GetBestTypeForBitSize(bit_size, false);
+ break;
+ default:
+ if (error_ptr)
+ error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
+ return false;
+ }
+ }
+ if (type == Scalar::e_void) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Unsupported pointer size");
+ return false;
+ }
+ Scalar &top = stack.back().ResolveValue(exe_ctx);
+ top.TruncOrExtendTo(type, bit_size);
+ break;
+ }
+
// OPCODE: DW_OP_call_frame_cfa
// OPERANDS: None
// DESCRIPTION: Specifies a DWARF expression that pushes the value of
@@ -2685,10 +2611,19 @@ bool DWARFExpression::Evaluate(
stack.push_back(Scalar(value));
} break;
- default:
- if (log)
- log->Printf("Unhandled opcode %s in DWARFExpression.",
+ case DW_OP_entry_value: {
+ if (!Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx, opcodes, offset,
+ error_ptr, log)) {
+ LLDB_ERRORF(error_ptr, "Could not evaluate %s.",
DW_OP_value_to_name(op));
+ return false;
+ }
+ break;
+ }
+
+ default:
+ LLDB_LOGF(log, "Unhandled opcode %s in DWARFExpression.",
+ DW_OP_value_to_name(op));
break;
}
}
@@ -2706,13 +2641,13 @@ bool DWARFExpression::Evaluate(
} else {
if (log && log->GetVerbose()) {
size_t count = stack.size();
- log->Printf("Stack after operation has %" PRIu64 " values:",
- (uint64_t)count);
+ LLDB_LOGF(log, "Stack after operation has %" PRIu64 " values:",
+ (uint64_t)count);
for (size_t i = 0; i < count; ++i) {
StreamString new_value;
new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
stack[i].Dump(&new_value);
- log->Printf(" %s", new_value.GetData());
+ LLDB_LOGF(log, " %s", new_value.GetData());
}
}
result = stack.back();
@@ -2720,29 +2655,6 @@ bool DWARFExpression::Evaluate(
return true; // Return true on success
}
-size_t DWARFExpression::LocationListSize(const DWARFUnit *dwarf_cu,
- const DataExtractor &debug_loc_data,
- lldb::offset_t offset) {
- const lldb::offset_t debug_loc_offset = offset;
- while (debug_loc_data.ValidOffset(offset)) {
- lldb::addr_t start_addr = LLDB_INVALID_ADDRESS;
- lldb::addr_t end_addr = LLDB_INVALID_ADDRESS;
- if (!AddressRangeForLocationListEntry(dwarf_cu, debug_loc_data, &offset,
- start_addr, end_addr))
- break;
-
- if (start_addr == 0 && end_addr == 0)
- break;
-
- uint16_t loc_length = debug_loc_data.GetU16(&offset);
- offset += loc_length;
- }
-
- if (offset > debug_loc_offset)
- return offset - debug_loc_offset;
- return 0;
-}
-
bool DWARFExpression::AddressRangeForLocationListEntry(
const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data,
lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc) {
@@ -2823,6 +2735,11 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data,
s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
return true;
}
+ if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_entry_value) {
+ uint = data.GetULEB128(offset_ptr);
+ s.Printf("%" PRIu64 " ", uint);
+ return true;
+ }
if (opcode_class != DRC_ONEOPERAND) {
s.Printf("UNKNOWN OP %u", opcode);
return false;
@@ -2923,6 +2840,7 @@ static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data,
case DW_OP_regx:
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
+ case DW_OP_entry_value:
size = 128;
break;
default:
diff --git a/source/Expression/DiagnosticManager.cpp b/source/Expression/DiagnosticManager.cpp
index 53d85f8a6d54..48eba3586d30 100644
--- a/source/Expression/DiagnosticManager.cpp
+++ b/source/Expression/DiagnosticManager.cpp
@@ -47,7 +47,7 @@ static const char *StringForSeverity(DiagnosticSeverity severity) {
std::string DiagnosticManager::GetString(char separator) {
std::string ret;
- for (const Diagnostic *diagnostic : Diagnostics()) {
+ for (const auto &diagnostic : Diagnostics()) {
ret.append(StringForSeverity(diagnostic->GetSeverity()));
ret.append(diagnostic->GetMessage());
ret.push_back(separator);
@@ -70,19 +70,9 @@ size_t DiagnosticManager::Printf(DiagnosticSeverity severity,
return result;
}
-size_t DiagnosticManager::PutString(DiagnosticSeverity severity,
- llvm::StringRef str) {
+void DiagnosticManager::PutString(DiagnosticSeverity severity,
+ llvm::StringRef str) {
if (str.empty())
- return 0;
+ return;
AddDiagnostic(str, severity, eDiagnosticOriginLLDB);
- return str.size();
-}
-
-void DiagnosticManager::CopyDiagnostics(DiagnosticManager &otherDiagnostics) {
- for (const DiagnosticList::value_type &other_diagnostic:
- otherDiagnostics.Diagnostics()) {
- AddDiagnostic(
- other_diagnostic->GetMessage(), other_diagnostic->GetSeverity(),
- other_diagnostic->getKind(), other_diagnostic->GetCompilerID());
- }
}
diff --git a/source/Expression/ExpressionVariable.cpp b/source/Expression/ExpressionVariable.cpp
index 97305dcf5a02..ed8da0ad8675 100644
--- a/source/Expression/ExpressionVariable.cpp
+++ b/source/Expression/ExpressionVariable.cpp
@@ -45,8 +45,7 @@ void PersistentExpressionState::RegisterExecutionUnit(
m_execution_units.insert(execution_unit_sp);
- if (log)
- log->Printf("Registering JITted Functions:\n");
+ LLDB_LOGF(log, "Registering JITted Functions:\n");
for (const IRExecutionUnit::JittedFunction &jitted_function :
execution_unit_sp->GetJittedFunctions()) {
@@ -55,15 +54,13 @@ void PersistentExpressionState::RegisterExecutionUnit(
jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS) {
m_symbol_map[jitted_function.m_name.GetCString()] =
jitted_function.m_remote_addr;
- if (log)
- log->Printf(" Function: %s at 0x%" PRIx64 ".",
- jitted_function.m_name.GetCString(),
- jitted_function.m_remote_addr);
+ LLDB_LOGF(log, " Function: %s at 0x%" PRIx64 ".",
+ jitted_function.m_name.GetCString(),
+ jitted_function.m_remote_addr);
}
}
- if (log)
- log->Printf("Registering JIIted Symbols:\n");
+ LLDB_LOGF(log, "Registering JIIted Symbols:\n");
for (const IRExecutionUnit::JittedGlobalVariable &global_var :
execution_unit_sp->GetJittedGlobalVariables()) {
@@ -74,9 +71,8 @@ void PersistentExpressionState::RegisterExecutionUnit(
Mangled mangler(global_var.m_name);
mangler.GetDemangledName(lldb::eLanguageTypeUnknown);
m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr;
- if (log)
- log->Printf(" Symbol: %s at 0x%" PRIx64 ".",
- global_var.m_name.GetCString(), global_var.m_remote_addr);
+ LLDB_LOGF(log, " Symbol: %s at 0x%" PRIx64 ".",
+ global_var.m_name.GetCString(), global_var.m_remote_addr);
}
}
}
diff --git a/source/Expression/FunctionCaller.cpp b/source/Expression/FunctionCaller.cpp
index 618c1a13212c..203cfff63d80 100644
--- a/source/Expression/FunctionCaller.cpp
+++ b/source/Expression/FunctionCaller.cpp
@@ -217,9 +217,8 @@ bool FunctionCaller::InsertFunction(ExecutionContext &exe_ctx,
return false;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n",
- m_jit_start_addr, args_addr_ref);
+ LLDB_LOGF(log, "Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n",
+ m_jit_start_addr, args_addr_ref);
return true;
}
@@ -231,10 +230,10 @@ lldb::ThreadPlanSP FunctionCaller::GetThreadPlanToCallFunction(
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("-- [FunctionCaller::GetThreadPlanToCallFunction] Creating "
- "thread plan to call function \"%s\" --",
- m_name.c_str());
+ LLDB_LOGF(log,
+ "-- [FunctionCaller::GetThreadPlanToCallFunction] Creating "
+ "thread plan to call function \"%s\" --",
+ m_name.c_str());
// FIXME: Use the errors Stream for better error reporting.
Thread *thread = exe_ctx.GetThreadPtr();
@@ -271,10 +270,10 @@ bool FunctionCaller::FetchFunctionResults(ExecutionContext &exe_ctx,
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("-- [FunctionCaller::FetchFunctionResults] Fetching function "
- "results for \"%s\"--",
- m_name.c_str());
+ LLDB_LOGF(log,
+ "-- [FunctionCaller::FetchFunctionResults] Fetching function "
+ "results for \"%s\"--",
+ m_name.c_str());
Process *process = exe_ctx.GetProcessPtr();
@@ -341,10 +340,9 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction(
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
LIBLLDB_LOG_STEP));
- if (log)
- log->Printf(
- "== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==",
- m_name.c_str());
+ LLDB_LOGF(log,
+ "== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==",
+ m_name.c_str());
lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction(
exe_ctx, args_addr, real_options, diagnostic_manager);
@@ -362,13 +360,15 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction(
if (log) {
if (return_value != lldb::eExpressionCompleted) {
- log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
- "completed abnormally ==",
- m_name.c_str());
+ LLDB_LOGF(log,
+ "== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
+ "completed abnormally ==",
+ m_name.c_str());
} else {
- log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
- "completed normally ==",
- m_name.c_str());
+ LLDB_LOGF(log,
+ "== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
+ "completed normally ==",
+ m_name.c_str());
}
}
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index 25404ad313e1..b10628e10cc5 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -122,10 +122,10 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream,
return ret;
}
- if (log)
- log->Printf("Found function, has local address 0x%" PRIx64
- " and remote address 0x%" PRIx64,
- (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
+ LLDB_LOGF(log,
+ "Found function, has local address 0x%" PRIx64
+ " and remote address 0x%" PRIx64,
+ (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
std::pair<lldb::addr_t, lldb::addr_t> func_range;
@@ -138,9 +138,8 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream,
return ret;
}
- if (log)
- log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]",
- func_range.first, func_range.second);
+ LLDB_LOGF(log, "Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]",
+ func_range.first, func_range.second);
Target *target = exe_ctx.GetTargetPtr();
if (!target) {
@@ -188,7 +187,7 @@ Status IRExecutionUnit::DisassembleFunction(Stream &stream,
target->GetArchitecture().GetAddressByteSize());
if (log) {
- log->Printf("Function data has contents:");
+ LLDB_LOGF(log, "Function data has contents:");
extractor.PutToLog(log, 0, extractor.GetByteSize(), func_remote_addr, 16,
DataExtractor::TypeUInt8);
}
@@ -255,7 +254,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
oss.flush();
- log->Printf("Module being sent to JIT: \n%s", s.c_str());
+ LLDB_LOGF(log, "Module being sent to JIT: \n%s", s.c_str());
}
m_module_up->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError,
@@ -317,7 +316,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
};
if (process_sp->GetTarget().GetEnableSaveObjects()) {
- m_object_cache_up = llvm::make_unique<ObjectDumper>();
+ m_object_cache_up = std::make_unique<ObjectDumper>();
m_execution_engine_up->setObjectCache(m_object_cache_up.get());
}
@@ -433,20 +432,20 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
}
if (log) {
- log->Printf("Code can be run in the target.");
+ LLDB_LOGF(log, "Code can be run in the target.");
StreamString disassembly_stream;
Status err = DisassembleFunction(disassembly_stream, process_sp);
if (!err.Success()) {
- log->Printf("Couldn't disassemble function : %s",
- err.AsCString("unknown error"));
+ LLDB_LOGF(log, "Couldn't disassemble function : %s",
+ err.AsCString("unknown error"));
} else {
- log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
+ LLDB_LOGF(log, "Function disassembly:\n%s", disassembly_stream.GetData());
}
- log->Printf("Sections: ");
+ LLDB_LOGF(log, "Sections: ");
for (AllocationRecord &record : m_records) {
if (record.m_process_address != LLDB_INVALID_ADDRESS) {
record.dump(log);
@@ -599,11 +598,10 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection(
GetSectionTypeFromSectionName(SectionName, AllocationKind::Code), Size,
Alignment, SectionID, SectionName.str().c_str()));
- if (log) {
- log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64
- ", Alignment=%u, SectionID=%u) = %p",
- (uint64_t)Size, Alignment, SectionID, (void *)return_value);
- }
+ LLDB_LOGF(log,
+ "IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64
+ ", Alignment=%u, SectionID=%u) = %p",
+ (uint64_t)Size, Alignment, SectionID, (void *)return_value);
if (m_parent.m_reported_allocations) {
Status err;
@@ -631,11 +629,10 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection(
(uintptr_t)return_value, permissions,
GetSectionTypeFromSectionName(SectionName, AllocationKind::Data), Size,
Alignment, SectionID, SectionName.str().c_str()));
- if (log) {
- log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64
- ", Alignment=%u, SectionID=%u) = %p",
- (uint64_t)Size, Alignment, SectionID, (void *)return_value);
- }
+ LLDB_LOGF(log,
+ "IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64
+ ", Alignment=%u, SectionID=%u) = %p",
+ (uint64_t)Size, Alignment, SectionID, (void *)return_value);
if (m_parent.m_reported_allocations) {
Status err;
@@ -661,11 +658,7 @@ FindBestAlternateMangledName(ConstString demangled,
if (!sym_ctx.module_sp)
return ConstString();
- SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
- if (!sym_vendor)
- return ConstString();
-
- lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+ lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();
if (!sym_file)
return ConstString();
@@ -676,7 +669,7 @@ FindBestAlternateMangledName(ConstString demangled,
std::vector<ConstString> param_matches;
for (size_t i = 0; i < alternates.size(); i++) {
ConstString alternate_mangled_name = alternates[i];
- Mangled mangled(alternate_mangled_name, true);
+ Mangled mangled(alternate_mangled_name);
ConstString demangled = mangled.GetDemangledName(lang_type);
CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
@@ -724,7 +717,7 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames(
ConstString name = C_spec.name;
if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
- Mangled mangled(name, true);
+ Mangled mangled(name);
ConstString demangled =
mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
@@ -861,7 +854,6 @@ lldb::addr_t IRExecutionUnit::FindInSymbols(
sc.module_sp->FindFunctions(spec.name, nullptr, spec.mask,
true, // include_symbols
false, // include_inlines
- true, // append
sc_list);
}
@@ -877,7 +869,6 @@ lldb::addr_t IRExecutionUnit::FindInSymbols(
sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask,
true, // include_symbols
false, // include_inlines
- true, // append
sc_list);
}
@@ -1042,17 +1033,15 @@ IRExecutionUnit::MemoryManager::GetSymbolAddressAndPresence(
lldb::addr_t ret = m_parent.FindSymbol(name_cs, missing_weak);
if (ret == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf(
- "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
- Name.c_str());
+ LLDB_LOGF(log,
+ "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
+ Name.c_str());
m_parent.ReportSymbolLookupError(name_cs);
return 0;
} else {
- if (log)
- log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
- Name.c_str(), ret);
+ LLDB_LOGF(log, "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
+ Name.c_str(), ret);
return ret;
}
}
@@ -1075,15 +1064,14 @@ IRExecutionUnit::GetRemoteAddressForLocal(lldb::addr_t local_address) {
lldb::addr_t ret =
record.m_process_address + (local_address - record.m_host_address);
- if (log) {
- log->Printf(
- "IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64
- " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64
- " from [0x%" PRIx64 "..0x%" PRIx64 "].",
- local_address, (uint64_t)record.m_host_address,
- (uint64_t)record.m_host_address + (uint64_t)record.m_size, ret,
- record.m_process_address, record.m_process_address + record.m_size);
- }
+ LLDB_LOGF(log,
+ "IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64
+ " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64
+ " from [0x%" PRIx64 "..0x%" PRIx64 "].",
+ local_address, (uint64_t)record.m_host_address,
+ (uint64_t)record.m_host_address + (uint64_t)record.m_size, ret,
+ record.m_process_address,
+ record.m_process_address + record.m_size);
return ret;
}
@@ -1210,10 +1198,11 @@ void IRExecutionUnit::AllocationRecord::dump(Log *log) {
if (!log)
return;
- log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
- (unsigned long long)m_host_address, (unsigned long long)m_size,
- (unsigned long long)m_process_address, (unsigned)m_alignment,
- (unsigned)m_section_id, m_name.c_str());
+ LLDB_LOGF(log,
+ "[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
+ (unsigned long long)m_host_address, (unsigned long long)m_size,
+ (unsigned long long)m_process_address, (unsigned)m_alignment,
+ (unsigned)m_section_id, m_name.c_str());
}
lldb::ByteOrder IRExecutionUnit::GetByteOrder() const {
diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp
index 5a9814d15362..856c9a0244fb 100644
--- a/source/Expression/IRInterpreter.cpp
+++ b/source/Expression/IRInterpreter.cpp
@@ -327,10 +327,11 @@ public:
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
- log->Printf("Made an allocation for argument %s",
- PrintValue(value).c_str());
- log->Printf(" Data region : %llx", (unsigned long long)address);
- log->Printf(" Ref region : %llx", (unsigned long long)data_address);
+ LLDB_LOGF(log, "Made an allocation for argument %s",
+ PrintValue(value).c_str());
+ LLDB_LOGF(log, " Data region : %llx", (unsigned long long)address);
+ LLDB_LOGF(log, " Ref region : %llx",
+ (unsigned long long)data_address);
}
return true;
@@ -494,8 +495,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
++fi) {
if (fi->begin() != fi->end()) {
if (saw_function_with_body) {
- if (log)
- log->Printf("More than one function in the module has a body");
+ LLDB_LOGF(log, "More than one function in the module has a body");
error.SetErrorToGenericError();
error.SetErrorString(too_many_functions_error);
return false;
@@ -510,8 +510,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
++ii) {
switch (ii->getOpcode()) {
default: {
- if (log)
- log->Printf("Unsupported instruction: %s", PrintValue(&*ii).c_str());
+ LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&*ii).c_str());
error.SetErrorToGenericError();
error.SetErrorString(unsupported_opcode_error);
return false;
@@ -532,9 +531,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
}
if (!CanIgnoreCall(call_inst) && !support_function_calls) {
- if (log)
- log->Printf("Unsupported instruction: %s",
- PrintValue(&*ii).c_str());
+ LLDB_LOGF(log, "Unsupported instruction: %s",
+ PrintValue(&*ii).c_str());
error.SetErrorToGenericError();
error.SetErrorString(unsupported_opcode_error);
return false;
@@ -553,9 +551,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
switch (icmp_inst->getPredicate()) {
default: {
- if (log)
- log->Printf("Unsupported ICmp predicate: %s",
- PrintValue(&*ii).c_str());
+ LLDB_LOGF(log, "Unsupported ICmp predicate: %s",
+ PrintValue(&*ii).c_str());
error.SetErrorToGenericError();
error.SetErrorString(unsupported_opcode_error);
@@ -605,9 +602,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
default:
break;
case Type::VectorTyID: {
- if (log)
- log->Printf("Unsupported operand type: %s",
- PrintType(operand_type).c_str());
+ LLDB_LOGF(log, "Unsupported operand type: %s",
+ PrintType(operand_type).c_str());
error.SetErrorString(unsupported_operand_error);
return false;
}
@@ -618,18 +614,16 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
// we can just fall back to the JIT rather than
// choking.
if (operand_type->getPrimitiveSizeInBits() > 64) {
- if (log)
- log->Printf("Unsupported operand type: %s",
- PrintType(operand_type).c_str());
+ LLDB_LOGF(log, "Unsupported operand type: %s",
+ PrintType(operand_type).c_str());
error.SetErrorString(unsupported_operand_error);
return false;
}
if (Constant *constant = llvm::dyn_cast<Constant>(operand)) {
if (!CanResolveConstant(constant)) {
- if (log)
- log->Printf("Unsupported constant: %s",
- PrintValue(constant).c_str());
+ LLDB_LOGF(log, "Unsupported constant: %s",
+ PrintValue(constant).c_str());
error.SetErrorString(unsupported_operand_error);
return false;
}
@@ -659,8 +653,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
oss.flush();
- log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"",
- s.c_str());
+ LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"",
+ s.c_str());
}
DataLayout data_layout(&module);
@@ -694,8 +688,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
while (frame.m_ii != frame.m_ie && (++num_insts < 4096)) {
const Instruction *inst = &*frame.m_ii;
- if (log)
- log->Printf("Interpreting %s", PrintValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str());
switch (inst->getOpcode()) {
default:
@@ -717,10 +710,10 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
if (!bin_op) {
- if (log)
- log->Printf(
- "getOpcode() returns %s, but instruction is not a BinaryOperator",
- inst->getOpcodeName());
+ LLDB_LOGF(
+ log,
+ "getOpcode() returns %s, but instruction is not a BinaryOperator",
+ inst->getOpcodeName());
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -733,16 +726,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar R;
if (!frame.EvaluateValue(L, lhs, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
}
if (!frame.EvaluateValue(R, rhs, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -806,28 +797,26 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, result, module);
if (log) {
- log->Printf("Interpreted a %s", inst->getOpcodeName());
- log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
- log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
- log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+ LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str());
+ LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str());
+ LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::Alloca: {
const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
if (!alloca_inst) {
- if (log)
- log->Printf("getOpcode() returns Alloca, but instruction is not an "
- "AllocaInst");
+ LLDB_LOGF(log, "getOpcode() returns Alloca, but instruction is not an "
+ "AllocaInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
}
if (alloca_inst->isArrayAllocation()) {
- if (log)
- log->Printf(
- "AllocaInsts are not handled if isArrayAllocation() is true");
+ LLDB_LOGF(log,
+ "AllocaInsts are not handled if isArrayAllocation() is true");
error.SetErrorToGenericError();
error.SetErrorString(unsupported_opcode_error);
return false;
@@ -846,8 +835,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb::addr_t R = frame.Malloc(T);
if (R == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Couldn't allocate memory for an AllocaInst");
+ LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_allocation_error);
return false;
@@ -856,8 +844,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb::addr_t P = frame.Malloc(Tptr);
if (P == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Couldn't allocate the result pointer for an AllocaInst");
+ LLDB_LOGF(log,
+ "Couldn't allocate the result pointer for an AllocaInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_allocation_error);
return false;
@@ -868,8 +856,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.WritePointerToMemory(P, R, write_error);
if (!write_error.Success()) {
- if (log)
- log->Printf("Couldn't write the result pointer for an AllocaInst");
+ LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_write_error);
lldb_private::Status free_error;
@@ -881,9 +868,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.m_values[alloca_inst] = P;
if (log) {
- log->Printf("Interpreted an AllocaInst");
- log->Printf(" R : 0x%" PRIx64, R);
- log->Printf(" P : 0x%" PRIx64, P);
+ LLDB_LOGF(log, "Interpreted an AllocaInst");
+ LLDB_LOGF(log, " R : 0x%" PRIx64, R);
+ LLDB_LOGF(log, " P : 0x%" PRIx64, P);
}
} break;
case Instruction::BitCast:
@@ -891,10 +878,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const CastInst *cast_inst = dyn_cast<CastInst>(inst);
if (!cast_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns %s, but instruction is not a BitCastInst",
- cast_inst->getOpcodeName());
+ LLDB_LOGF(
+ log, "getOpcode() returns %s, but instruction is not a BitCastInst",
+ cast_inst->getOpcodeName());
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -905,8 +891,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar S;
if (!frame.EvaluateValue(S, source, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -918,10 +903,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const CastInst *cast_inst = dyn_cast<CastInst>(inst);
if (!cast_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns %s, but instruction is not a BitCastInst",
- cast_inst->getOpcodeName());
+ LLDB_LOGF(
+ log, "getOpcode() returns %s, but instruction is not a BitCastInst",
+ cast_inst->getOpcodeName());
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -932,8 +916,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar S;
if (!frame.EvaluateValue(S, source, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -949,9 +932,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
if (!br_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns Br, but instruction is not a BranchInst");
+ LLDB_LOGF(
+ log, "getOpcode() returns Br, but instruction is not a BranchInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -963,8 +945,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar C;
if (!frame.EvaluateValue(C, condition, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -976,14 +957,15 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.Jump(br_inst->getSuccessor(1));
if (log) {
- log->Printf("Interpreted a BrInst with a condition");
- log->Printf(" cond : %s", frame.SummarizeValue(condition).c_str());
+ LLDB_LOGF(log, "Interpreted a BrInst with a condition");
+ LLDB_LOGF(log, " cond : %s",
+ frame.SummarizeValue(condition).c_str());
}
} else {
frame.Jump(br_inst->getSuccessor(0));
if (log) {
- log->Printf("Interpreted a BrInst with no condition");
+ LLDB_LOGF(log, "Interpreted a BrInst with no condition");
}
}
}
@@ -992,17 +974,16 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const PHINode *phi_inst = dyn_cast<PHINode>(inst);
if (!phi_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns PHI, but instruction is not a PHINode");
+ LLDB_LOGF(log,
+ "getOpcode() returns PHI, but instruction is not a PHINode");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
}
if (!frame.m_prev_bb) {
- if (log)
- log->Printf("Encountered PHI node without having jumped from another "
- "basic block");
+ LLDB_LOGF(log,
+ "Encountered PHI node without having jumped from another "
+ "basic block");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1011,8 +992,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);
lldb_private::Scalar result;
if (!frame.EvaluateValue(result, value, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(value).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1020,18 +1000,17 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, result, module);
if (log) {
- log->Printf("Interpreted a %s", inst->getOpcodeName());
- log->Printf(" Incoming value : %s",
- frame.SummarizeValue(value).c_str());
+ LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+ LLDB_LOGF(log, " Incoming value : %s",
+ frame.SummarizeValue(value).c_str());
}
} break;
case Instruction::GetElementPtr: {
const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
if (!gep_inst) {
- if (log)
- log->Printf("getOpcode() returns GetElementPtr, but instruction is "
- "not a GetElementPtrInst");
+ LLDB_LOGF(log, "getOpcode() returns GetElementPtr, but instruction is "
+ "not a GetElementPtrInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1043,9 +1022,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar P;
if (!frame.EvaluateValue(P, pointer_operand, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s",
- PrintValue(pointer_operand).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s",
+ PrintValue(pointer_operand).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1067,17 +1045,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar I;
if (!frame.EvaluateValue(I, *ii, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(*ii).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
}
- if (log)
- log->Printf("Evaluated constant index %s as %llu",
- PrintValue(*ii).c_str(),
- I.ULongLong(LLDB_INVALID_ADDRESS));
+ LLDB_LOGF(log, "Evaluated constant index %s as %llu",
+ PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
constant_index = cast<ConstantInt>(ConstantInt::get(
(*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
@@ -1094,19 +1069,19 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, Poffset, module);
if (log) {
- log->Printf("Interpreted a GetElementPtrInst");
- log->Printf(" P : %s",
- frame.SummarizeValue(pointer_operand).c_str());
- log->Printf(" Poffset : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted a GetElementPtrInst");
+ LLDB_LOGF(log, " P : %s",
+ frame.SummarizeValue(pointer_operand).c_str());
+ LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::ICmp: {
const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
if (!icmp_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns ICmp, but instruction is not an ICmpInst");
+ LLDB_LOGF(
+ log,
+ "getOpcode() returns ICmp, but instruction is not an ICmpInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1121,16 +1096,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar R;
if (!frame.EvaluateValue(L, lhs, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
}
if (!frame.EvaluateValue(R, rhs, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1192,19 +1165,19 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, result, module);
if (log) {
- log->Printf("Interpreted an ICmpInst");
- log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
- log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
- log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted an ICmpInst");
+ LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str());
+ LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str());
+ LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::IntToPtr: {
const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
if (!int_to_ptr_inst) {
- if (log)
- log->Printf("getOpcode() returns IntToPtr, but instruction is not an "
- "IntToPtrInst");
+ LLDB_LOGF(log,
+ "getOpcode() returns IntToPtr, but instruction is not an "
+ "IntToPtrInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1215,8 +1188,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar I;
if (!frame.EvaluateValue(I, src_operand, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1225,18 +1197,18 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, I, module);
if (log) {
- log->Printf("Interpreted an IntToPtr");
- log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
- log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted an IntToPtr");
+ LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());
+ LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::PtrToInt: {
const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
if (!ptr_to_int_inst) {
- if (log)
- log->Printf("getOpcode() returns PtrToInt, but instruction is not an "
- "PtrToIntInst");
+ LLDB_LOGF(log,
+ "getOpcode() returns PtrToInt, but instruction is not an "
+ "PtrToIntInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1247,8 +1219,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar I;
if (!frame.EvaluateValue(I, src_operand, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1257,18 +1228,18 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, I, module);
if (log) {
- log->Printf("Interpreted a PtrToInt");
- log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
- log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted a PtrToInt");
+ LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());
+ LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::Trunc: {
const TruncInst *trunc_inst = dyn_cast<TruncInst>(inst);
if (!trunc_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns Trunc, but instruction is not a TruncInst");
+ LLDB_LOGF(
+ log,
+ "getOpcode() returns Trunc, but instruction is not a TruncInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1279,8 +1250,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::Scalar I;
if (!frame.EvaluateValue(I, src_operand, module)) {
- if (log)
- log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
+ LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1289,18 +1259,17 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
frame.AssignValue(inst, I, module);
if (log) {
- log->Printf("Interpreted a Trunc");
- log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
- log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ LLDB_LOGF(log, "Interpreted a Trunc");
+ LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());
+ LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
case Instruction::Load: {
const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
if (!load_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns Load, but instruction is not a LoadInst");
+ LLDB_LOGF(
+ log, "getOpcode() returns Load, but instruction is not a LoadInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1317,8 +1286,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
Type *pointer_ty = pointer_operand->getType();
PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
if (!pointer_ptr_ty) {
- if (log)
- log->Printf("getPointerOperand()->getType() is not a PointerType");
+ LLDB_LOGF(log, "getPointerOperand()->getType() is not a PointerType");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1329,16 +1297,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
if (D == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("LoadInst's value doesn't resolve to anything");
+ LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything");
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
}
if (P == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("LoadInst's pointer doesn't resolve to anything");
+ LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything");
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1349,8 +1315,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.ReadPointerFromMemory(&R, P, read_error);
if (!read_error.Success()) {
- if (log)
- log->Printf("Couldn't read the address to be loaded for a LoadInst");
+ LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_read_error);
return false;
@@ -1363,8 +1328,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(),
read_error);
if (!read_error.Success()) {
- if (log)
- log->Printf("Couldn't read from a region on behalf of a LoadInst");
+ LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_read_error);
return false;
@@ -1374,18 +1338,17 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(),
write_error);
if (!write_error.Success()) {
- if (log)
- log->Printf("Couldn't write to a region on behalf of a LoadInst");
+ LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_read_error);
return false;
}
if (log) {
- log->Printf("Interpreted a LoadInst");
- log->Printf(" P : 0x%" PRIx64, P);
- log->Printf(" R : 0x%" PRIx64, R);
- log->Printf(" D : 0x%" PRIx64, D);
+ LLDB_LOGF(log, "Interpreted a LoadInst");
+ LLDB_LOGF(log, " P : 0x%" PRIx64, P);
+ LLDB_LOGF(log, " R : 0x%" PRIx64, R);
+ LLDB_LOGF(log, " D : 0x%" PRIx64, D);
}
} break;
case Instruction::Ret: {
@@ -1395,9 +1358,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
if (!store_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns Store, but instruction is not a StoreInst");
+ LLDB_LOGF(
+ log,
+ "getOpcode() returns Store, but instruction is not a StoreInst");
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
@@ -1422,16 +1385,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
if (D == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("StoreInst's value doesn't resolve to anything");
+ LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything");
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
}
if (P == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("StoreInst's pointer doesn't resolve to anything");
+ LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything");
error.SetErrorToGenericError();
error.SetErrorString(bad_value_error);
return false;
@@ -1442,8 +1403,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.ReadPointerFromMemory(&R, P, read_error);
if (!read_error.Success()) {
- if (log)
- log->Printf("Couldn't read the address to be loaded for a LoadInst");
+ LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_read_error);
return false;
@@ -1456,8 +1416,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(),
read_error);
if (!read_error.Success()) {
- if (log)
- log->Printf("Couldn't read from a region on behalf of a StoreInst");
+ LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_read_error);
return false;
@@ -1467,28 +1426,26 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(),
write_error);
if (!write_error.Success()) {
- if (log)
- log->Printf("Couldn't write to a region on behalf of a StoreInst");
+ LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst");
error.SetErrorToGenericError();
error.SetErrorString(memory_write_error);
return false;
}
if (log) {
- log->Printf("Interpreted a StoreInst");
- log->Printf(" D : 0x%" PRIx64, D);
- log->Printf(" P : 0x%" PRIx64, P);
- log->Printf(" R : 0x%" PRIx64, R);
+ LLDB_LOGF(log, "Interpreted a StoreInst");
+ LLDB_LOGF(log, " D : 0x%" PRIx64, D);
+ LLDB_LOGF(log, " P : 0x%" PRIx64, P);
+ LLDB_LOGF(log, " R : 0x%" PRIx64, R);
}
} break;
case Instruction::Call: {
const CallInst *call_inst = dyn_cast<CallInst>(inst);
if (!call_inst) {
- if (log)
- log->Printf(
- "getOpcode() returns %s, but instruction is not a CallInst",
- inst->getOpcodeName());
+ LLDB_LOGF(log,
+ "getOpcode() returns %s, but instruction is not a CallInst",
+ inst->getOpcodeName());
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp
index 70e62ac12b0e..5fdf452bf94e 100644
--- a/source/Expression/IRMemoryMap.cpp
+++ b/source/Expression/IRMemoryMap.cpp
@@ -327,12 +327,12 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
break;
case eAllocationPolicyMirror:
process_sp = m_process_wp.lock();
- if (log)
- log->Printf("IRMemoryMap::%s process_sp=0x%" PRIx64
- ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s",
- __FUNCTION__, (lldb::addr_t)process_sp.get(),
- process_sp && process_sp->CanJIT() ? "true" : "false",
- process_sp && process_sp->IsAlive() ? "true" : "false");
+ LLDB_LOGF(log,
+ "IRMemoryMap::%s process_sp=0x%" PRIx64
+ ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s",
+ __FUNCTION__, (lldb::addr_t)process_sp.get(),
+ process_sp && process_sp->CanJIT() ? "true" : "false",
+ process_sp && process_sp->IsAlive() ? "true" : "false");
if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) {
if (!zero_memory)
allocation_address =
@@ -344,10 +344,10 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
if (!error.Success())
return LLDB_INVALID_ADDRESS;
} else {
- if (log)
- log->Printf("IRMemoryMap::%s switching to eAllocationPolicyHostOnly "
- "due to failed condition (see previous expr log message)",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "IRMemoryMap::%s switching to eAllocationPolicyHostOnly "
+ "due to failed condition (see previous expr log message)",
+ __FUNCTION__);
policy = eAllocationPolicyHostOnly;
allocation_address = FindSpace(allocation_size);
if (allocation_address == LLDB_INVALID_ADDRESS) {
@@ -417,10 +417,11 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
break;
}
- log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64
- ", %s) -> 0x%" PRIx64,
- (uint64_t)allocation_size, (uint64_t)alignment,
- (uint64_t)permissions, policy_string, aligned_address);
+ LLDB_LOGF(log,
+ "IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64
+ ", %s) -> 0x%" PRIx64,
+ (uint64_t)allocation_size, (uint64_t)alignment,
+ (uint64_t)permissions, policy_string, aligned_address);
}
return aligned_address;
@@ -477,10 +478,11 @@ void IRMemoryMap::Free(lldb::addr_t process_address, Status &error) {
if (lldb_private::Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
- log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64
- "..0x%" PRIx64 ")",
- (uint64_t)process_address, iter->second.m_process_start,
- iter->second.m_process_start + iter->second.m_size);
+ LLDB_LOGF(log,
+ "IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64
+ "..0x%" PRIx64 ")",
+ (uint64_t)process_address, iter->second.m_process_start,
+ iter->second.m_process_start + iter->second.m_size);
}
m_allocations.erase(iter);
@@ -574,12 +576,13 @@ void IRMemoryMap::WriteMemory(lldb::addr_t process_address,
if (lldb_private::Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
- log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64
- ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
- (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size,
- (uint64_t)allocation.m_process_start,
- (uint64_t)allocation.m_process_start +
- (uint64_t)allocation.m_size);
+ LLDB_LOGF(log,
+ "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64
+ ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
+ (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size,
+ (uint64_t)allocation.m_process_start,
+ (uint64_t)allocation.m_process_start +
+ (uint64_t)allocation.m_size);
}
}
@@ -704,12 +707,13 @@ void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address,
if (lldb_private::Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
- log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64
- ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
- (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size,
- (uint64_t)allocation.m_process_start,
- (uint64_t)allocation.m_process_start +
- (uint64_t)allocation.m_size);
+ LLDB_LOGF(log,
+ "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64
+ ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
+ (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size,
+ (uint64_t)allocation.m_process_start,
+ (uint64_t)allocation.m_process_start +
+ (uint64_t)allocation.m_size);
}
}
diff --git a/source/Expression/LLVMUserExpression.cpp b/source/Expression/LLVMUserExpression.cpp
index 5a1b750318c9..99e0c11df420 100644
--- a/source/Expression/LLVMUserExpression.cpp
+++ b/source/Expression/LLVMUserExpression.cpp
@@ -12,13 +12,12 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
@@ -48,9 +47,7 @@ LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false),
m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(),
- m_materializer_up(), m_jit_module_wp(), m_enforce_valid_object(true),
- m_in_cplusplus_method(false), m_in_objectivec_method(false),
- m_in_static_method(false), m_needs_object_ptr(false), m_target(nullptr),
+ m_materializer_up(), m_jit_module_wp(),
m_can_interpret(false), m_materialized_address(LLDB_INVALID_ADDRESS) {}
LLVMUserExpression::~LLVMUserExpression() {
@@ -161,9 +158,9 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
function_stack_top = function_stack_pointer;
- if (log)
- log->Printf(
- "-- [UserExpression::Execute] Execution of expression begins --");
+ LLDB_LOGF(
+ log,
+ "-- [UserExpression::Execute] Execution of expression begins --");
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
@@ -175,9 +172,8 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
if (exe_ctx.GetProcessPtr())
exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
- if (log)
- log->Printf("-- [UserExpression::Execute] Execution of expression "
- "completed --");
+ LLDB_LOGF(log, "-- [UserExpression::Execute] Execution of expression "
+ "completed --");
if (execution_result == lldb::eExpressionInterrupted ||
execution_result == lldb::eExpressionHitBreakpoint) {
@@ -251,9 +247,8 @@ bool LLVMUserExpression::FinalizeJITExecution(
lldb::addr_t function_stack_top) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing "
- "after execution --");
+ LLDB_LOGF(log, "-- [UserExpression::FinalizeJITExecution] Dematerializing "
+ "after execution --");
if (!m_dematerializer_sp) {
diagnostic_manager.Printf(eDiagnosticSeverityError,
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index 0f871fcbefbc..cd332484debb 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -11,7 +11,6 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/ExpressionVariable.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
@@ -46,20 +45,6 @@ uint32_t Materializer::AddStructMember(Entity &entity) {
return ret;
}
-void Materializer::Entity::SetSizeAndAlignmentFromType(CompilerType &type) {
- if (llvm::Optional<uint64_t> size = type.GetByteSize(nullptr))
- m_size = *size;
-
- uint32_t bit_alignment = type.GetTypeBitAlign();
-
- if (bit_alignment % 8) {
- bit_alignment += 8;
- bit_alignment &= ~((uint32_t)0x111u);
- }
-
- m_alignment = bit_alignment / 8;
-}
-
class EntityPersistentVariable : public Materializer::Entity {
public:
EntityPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp,
@@ -94,9 +79,8 @@ public:
return;
}
- if (log)
- log->Printf("Allocated %s (0x%" PRIx64 ") successfully",
- m_persistent_variable_sp->GetName().GetCString(), mem);
+ LLDB_LOGF(log, "Allocated %s (0x%" PRIx64 ") successfully",
+ m_persistent_variable_sp->GetName().GetCString(), mem);
// Put the location of the spare memory into the live data of the
// ValueObject.
@@ -158,11 +142,12 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64
- ", m_name = %s, m_flags = 0x%hx]",
- (uint64_t)load_addr,
- m_persistent_variable_sp->GetName().AsCString(),
- m_persistent_variable_sp->m_flags);
+ LLDB_LOGF(log,
+ "EntityPersistentVariable::Materialize [address = 0x%" PRIx64
+ ", m_name = %s, m_flags = 0x%hx]",
+ (uint64_t)load_addr,
+ m_persistent_variable_sp->GetName().AsCString(),
+ m_persistent_variable_sp->m_flags);
}
if (m_persistent_variable_sp->m_flags &
@@ -209,12 +194,12 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf(
- "EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64
- ", m_name = %s, m_flags = 0x%hx]",
- (uint64_t)process_address + m_offset,
- m_persistent_variable_sp->GetName().AsCString(),
- m_persistent_variable_sp->m_flags);
+ LLDB_LOGF(log,
+ "EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64
+ ", m_name = %s, m_flags = 0x%hx]",
+ (uint64_t)process_address + m_offset,
+ m_persistent_variable_sp->GetName().AsCString(),
+ m_persistent_variable_sp->m_flags);
}
if (m_delegate) {
@@ -291,11 +276,10 @@ public:
ExpressionVariable::EVNeedsFreezeDry ||
m_persistent_variable_sp->m_flags &
ExpressionVariable::EVKeepInTarget) {
- if (log)
- log->Printf(
- "Dematerializing %s from 0x%" PRIx64 " (size = %llu)",
- m_persistent_variable_sp->GetName().GetCString(), (uint64_t)mem,
- (unsigned long long)m_persistent_variable_sp->GetByteSize());
+ LLDB_LOGF(log, "Dematerializing %s from 0x%" PRIx64 " (size = %llu)",
+ m_persistent_variable_sp->GetName().GetCString(),
+ (uint64_t)mem,
+ (unsigned long long)m_persistent_variable_sp->GetByteSize());
// Read the contents of the spare memory area
@@ -441,9 +425,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntityVariable::Materialize [address = 0x%" PRIx64
- ", m_variable_sp = %s]",
- (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
+ LLDB_LOGF(log,
+ "EntityVariable::Materialize [address = 0x%" PRIx64
+ ", m_variable_sp = %s]",
+ (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
}
ExecutionContextScope *scope = frame_sp.get();
@@ -545,12 +530,15 @@ public:
return;
}
- size_t bit_align =
- m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign();
- size_t byte_align = (bit_align + 7) / 8;
+ llvm::Optional<size_t> opt_bit_align =
+ m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(scope);
+ if (!opt_bit_align) {
+ err.SetErrorStringWithFormat("can't get the type alignment for %s",
+ m_variable_sp->GetName().AsCString());
+ return;
+ }
- if (!byte_align)
- byte_align = 1;
+ size_t byte_align = (*opt_bit_align + 7) / 8;
Status alloc_error;
const bool zero_memory = false;
@@ -606,9 +594,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntityVariable::Dematerialize [address = 0x%" PRIx64
- ", m_variable_sp = %s]",
- (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
+ LLDB_LOGF(log,
+ "EntityVariable::Dematerialize [address = 0x%" PRIx64
+ ", m_variable_sp = %s]",
+ (uint64_t)load_addr, m_variable_sp->GetName().AsCString());
}
if (m_temporary_allocation != LLDB_INVALID_ADDRESS) {
@@ -802,11 +791,14 @@ public:
err.SetErrorString("can't get size of type");
return;
}
- size_t bit_align = m_type.GetTypeBitAlign();
- size_t byte_align = (bit_align + 7) / 8;
- if (!byte_align)
- byte_align = 1;
+ llvm::Optional<size_t> opt_bit_align = m_type.GetTypeBitAlign(exe_scope);
+ if (!opt_bit_align) {
+ err.SetErrorStringWithFormat("can't get the type alignment");
+ return;
+ }
+
+ size_t byte_align = (*opt_bit_align + 7) / 8;
Status alloc_error;
const bool zero_memory = true;
@@ -869,20 +861,18 @@ public:
return;
}
- Status type_system_error;
- TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
- &type_system_error, m_type.GetMinimumLanguage());
+ auto type_system_or_err =
+ target_sp->GetScratchTypeSystemForLanguage(m_type.GetMinimumLanguage());
- if (!type_system) {
+ if (auto error = type_system_or_err.takeError()) {
err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: "
"couldn't get the corresponding type "
"system: %s",
- type_system_error.AsCString());
+ llvm::toString(std::move(error)).c_str());
return;
}
-
PersistentExpressionState *persistent_state =
- type_system->GetPersistentExpressionState();
+ type_system_or_err->GetPersistentExpressionState();
if (!persistent_state) {
err.SetErrorString("Couldn't dematerialize a result variable: "
@@ -1064,9 +1054,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntitySymbol::Materialize [address = 0x%" PRIx64
- ", m_symbol = %s]",
- (uint64_t)load_addr, m_symbol.GetName().AsCString());
+ LLDB_LOGF(log,
+ "EntitySymbol::Materialize [address = 0x%" PRIx64
+ ", m_symbol = %s]",
+ (uint64_t)load_addr, m_symbol.GetName().AsCString());
}
const Address sym_address = m_symbol.GetAddress();
@@ -1110,9 +1101,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntitySymbol::Dematerialize [address = 0x%" PRIx64
- ", m_symbol = %s]",
- (uint64_t)load_addr, m_symbol.GetName().AsCString());
+ LLDB_LOGF(log,
+ "EntitySymbol::Dematerialize [address = 0x%" PRIx64
+ ", m_symbol = %s]",
+ (uint64_t)load_addr, m_symbol.GetName().AsCString());
}
// no work needs to be done
@@ -1179,9 +1171,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntityRegister::Materialize [address = 0x%" PRIx64
- ", m_register_info = %s]",
- (uint64_t)load_addr, m_register_info.name);
+ LLDB_LOGF(log,
+ "EntityRegister::Materialize [address = 0x%" PRIx64
+ ", m_register_info = %s]",
+ (uint64_t)load_addr, m_register_info.name);
}
RegisterValue reg_value;
@@ -1241,9 +1234,10 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
if (log) {
- log->Printf("EntityRegister::Dematerialize [address = 0x%" PRIx64
- ", m_register_info = %s]",
- (uint64_t)load_addr, m_register_info.name);
+ LLDB_LOGF(log,
+ "EntityRegister::Dematerialize [address = 0x%" PRIx64
+ ", m_register_info = %s]",
+ (uint64_t)load_addr, m_register_info.name);
}
Status extract_error;
@@ -1380,7 +1374,8 @@ Materializer::Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
if (Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
") materialized:",
static_cast<void *>(frame_sp.get()), process_address);
@@ -1415,9 +1410,10 @@ void Materializer::Dematerializer::Dematerialize(Status &error,
} else {
if (Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
- log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address "
- "= 0x%" PRIx64 ") about to dematerialize:",
- static_cast<void *>(frame_sp.get()), m_process_address);
+ LLDB_LOGF(log,
+ "Materializer::Dematerialize (frame_sp = %p, process_address "
+ "= 0x%" PRIx64 ") about to dematerialize:",
+ static_cast<void *>(frame_sp.get()), m_process_address);
for (EntityUP &entity_up : m_materializer->m_entities)
entity_up->DumpToLog(*m_map, m_process_address, log);
}
diff --git a/source/Expression/REPL.cpp b/source/Expression/REPL.cpp
index f4ed887729d8..4f81ee3e56dd 100644
--- a/source/Expression/REPL.cpp
+++ b/source/Expression/REPL.cpp
@@ -96,7 +96,7 @@ void REPL::IOHandlerActivated(IOHandler &io_handler, bool interactive) {
lldb::ProcessSP process_sp = m_target.GetProcessSP();
if (process_sp && process_sp->IsAlive())
return;
- lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
error_sp->Printf("REPL requires a running target process.\n");
io_handler.SetIsDone(true);
}
@@ -180,8 +180,8 @@ int REPL::IOHandlerFixIndentation(IOHandler &io_handler,
}
void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
- lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
+ lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
bool extra_line = false;
bool did_quit = false;
@@ -206,7 +206,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
// Meta command
// Strip the ':'
code.erase(0, 1);
- if (Args::StripSpaces(code)) {
+ if (!llvm::StringRef(code).trim().empty()) {
// "lldb" was followed by arguments, so just execute the command dump
// the results
@@ -398,17 +398,22 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
// Update our code on disk
if (!m_repl_source_path.empty()) {
- lldb_private::File file;
- FileSystem::Instance().Open(file, FileSpec(m_repl_source_path),
- File::eOpenOptionWrite |
- File::eOpenOptionTruncate |
- File::eOpenOptionCanCreate,
- lldb::eFilePermissionsFileDefault);
- std::string code(m_code.CopyList());
- code.append(1, '\n');
- size_t bytes_written = code.size();
- file.Write(code.c_str(), bytes_written);
- file.Close();
+ auto file = FileSystem::Instance().Open(
+ FileSpec(m_repl_source_path),
+ File::eOpenOptionWrite | File::eOpenOptionTruncate |
+ File::eOpenOptionCanCreate,
+ lldb::eFilePermissionsFileDefault);
+ if (file) {
+ std::string code(m_code.CopyList());
+ code.append(1, '\n');
+ size_t bytes_written = code.size();
+ file.get()->Write(code.c_str(), bytes_written);
+ file.get()->Close();
+ } else {
+ std::string message = llvm::toString(file.takeError());
+ error_sp->Printf("error: couldn't open %s: %s\n",
+ m_repl_source_path.c_str(), message.c_str());
+ }
// Now set the default file and line to the REPL source file
m_target.GetSourceManager().SetDefaultFileAndLine(
@@ -418,7 +423,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
.SetBaseLineNumber(m_code.GetSize() + 1);
}
if (extra_line) {
- fprintf(output_sp->GetFile().GetStream(), "\n");
+ output_sp->Printf("\n");
}
}
}
@@ -433,31 +438,30 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
}
}
-int REPL::IOHandlerComplete(IOHandler &io_handler, const char *current_line,
- const char *cursor, const char *last_char,
- int skip_first_n_matches, int max_matches,
- StringList &matches, StringList &descriptions) {
- matches.Clear();
-
- llvm::StringRef line(current_line, cursor - current_line);
-
+void REPL::IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) {
// Complete an LLDB command if the first character is a colon...
- if (!line.empty() && line[0] == ':') {
+ if (request.GetRawLine().startswith(":")) {
Debugger &debugger = m_target.GetDebugger();
// auto complete LLDB commands
- const char *lldb_current_line = line.substr(1).data();
- return debugger.GetCommandInterpreter().HandleCompletion(
- lldb_current_line, cursor, last_char, skip_first_n_matches, max_matches,
- matches, descriptions);
+ llvm::StringRef new_line = request.GetRawLine().drop_front();
+ CompletionResult sub_result;
+ CompletionRequest sub_request(new_line, request.GetRawCursorPos() - 1,
+ sub_result);
+ debugger.GetCommandInterpreter().HandleCompletion(sub_request);
+ StringList matches, descriptions;
+ sub_result.GetMatches(matches);
+ sub_result.GetDescriptions(descriptions);
+ request.AddCompletions(matches, descriptions);
+ return;
}
// Strip spaces from the line and see if we had only spaces
- line = line.ltrim();
- if (line.empty()) {
+ if (request.GetRawLine().trim().empty()) {
// Only spaces on this line, so just indent
- matches.AppendString(m_indent_str);
- return 1;
+ request.AddCompletion(m_indent_str);
+ return;
}
std::string current_code;
@@ -479,12 +483,17 @@ int REPL::IOHandlerComplete(IOHandler &io_handler, const char *current_line,
}
}
- if (cursor > current_line) {
- current_code.append("\n");
- current_code.append(current_line, cursor - current_line);
- }
-
- return CompleteCode(current_code, matches);
+ current_code.append("\n");
+ current_code += request.GetRawLine();
+
+ StringList matches;
+ int result = CompleteCode(current_code, matches);
+ if (result == -2) {
+ assert(matches.GetSize() == 1);
+ request.AddCompletion(matches.GetStringAtIndex(0), "",
+ CompletionMode::RewriteLine);
+ } else
+ request.AddCompletions(matches);
}
bool QuitCommandOverrideCallback(void *baton, const char **argv) {
diff --git a/source/Expression/UserExpression.cpp b/source/Expression/UserExpression.cpp
index a72e2a07599e..e2d1d2f2b3d2 100644
--- a/source/Expression/UserExpression.cpp
+++ b/source/Expression/UserExpression.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -165,9 +167,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
Target *target = exe_ctx.GetTargetPtr();
if (!target) {
- if (log)
- log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't "
- "run expressions.");
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Passed a NULL target, can't "
+ "run expressions.");
error.SetErrorString("expression passed a null target");
return lldb::eExpressionSetupError;
}
@@ -176,9 +177,9 @@ lldb::ExpressionResults UserExpression::Evaluate(
if (process == nullptr || process->GetState() != lldb::eStateStopped) {
if (execution_policy == eExecutionPolicyAlways) {
- if (log)
- log->Printf("== [UserExpression::Evaluate] Expression may not run, but "
- "is not constant ==");
+ LLDB_LOGF(log,
+ "== [UserExpression::Evaluate] Expression may not run, but "
+ "is not constant ==");
error.SetErrorString("expression needed to run but couldn't");
@@ -224,14 +225,14 @@ lldb::ExpressionResults UserExpression::Evaluate(
error));
if (error.Fail()) {
if (log)
- log->Printf("== [UserExpression::Evaluate] Getting expression: %s ==",
- error.AsCString());
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Getting expression: %s ==",
+ error.AsCString());
return lldb::eExpressionSetupError;
}
if (log)
- log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==",
- expr.str().c_str());
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Parsing expression %s ==",
+ expr.str().c_str());
const bool keep_expression_in_memory = true;
const bool generate_debug_info = options.GetGenerateDebugInfo();
@@ -310,8 +311,9 @@ lldb::ExpressionResults UserExpression::Evaluate(
if (execution_policy == eExecutionPolicyNever &&
!user_expression_sp->CanInterpret()) {
if (log)
- log->Printf("== [UserExpression::Evaluate] Expression may not run, but "
- "is not constant ==");
+ LLDB_LOGF(log,
+ "== [UserExpression::Evaluate] Expression may not run, but "
+ "is not constant ==");
if (!diagnostic_manager.Diagnostics().size())
error.SetExpressionError(lldb::eExpressionSetupError,
@@ -332,7 +334,7 @@ lldb::ExpressionResults UserExpression::Evaluate(
diagnostic_manager.Clear();
if (log)
- log->Printf("== [UserExpression::Evaluate] Executing expression ==");
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Executing expression ==");
execution_results =
user_expression_sp->Execute(diagnostic_manager, exe_ctx, options,
@@ -340,8 +342,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
if (execution_results != lldb::eExpressionCompleted) {
if (log)
- log->Printf("== [UserExpression::Evaluate] Execution completed "
- "abnormally ==");
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed "
+ "abnormally ==");
if (!diagnostic_manager.Diagnostics().size())
error.SetExpressionError(
@@ -354,13 +356,14 @@ lldb::ExpressionResults UserExpression::Evaluate(
result_valobj_sp = expr_result->GetValueObject();
if (log)
- log->Printf("== [UserExpression::Evaluate] Execution completed "
- "normally with result %s ==",
- result_valobj_sp->GetValueAsCString());
+ LLDB_LOGF(log,
+ "== [UserExpression::Evaluate] Execution completed "
+ "normally with result %s ==",
+ result_valobj_sp->GetValueAsCString());
} else {
if (log)
- log->Printf("== [UserExpression::Evaluate] Execution completed "
- "normally with no result ==");
+ LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed "
+ "normally with no result ==");
error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
}
diff --git a/source/Expression/UtilityFunction.cpp b/source/Expression/UtilityFunction.cpp
index eeaeca18da86..aac8b33a6bfa 100644
--- a/source/Expression/UtilityFunction.cpp
+++ b/source/Expression/UtilityFunction.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index d3a70aeaa326..3e655244b107 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -14,6 +14,7 @@
#include "lldb/Host/Editline.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/SelectHelper.h"
@@ -863,26 +864,59 @@ unsigned char Editline::BufferEndCommand(int ch) {
/// Prints completions and their descriptions to the given file. Only the
/// completions in the interval [start, end) are printed.
-static void PrintCompletion(FILE *output_file, size_t start, size_t end,
- StringList &completions, StringList &descriptions) {
- // This is an 'int' because of printf.
- int max_len = 0;
-
- for (size_t i = start; i < end; i++) {
- const char *completion_str = completions.GetStringAtIndex(i);
- max_len = std::max((int)strlen(completion_str), max_len);
+static void
+PrintCompletion(FILE *output_file,
+ llvm::ArrayRef<CompletionResult::Completion> results,
+ size_t max_len) {
+ for (const CompletionResult::Completion &c : results) {
+ fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str());
+ if (!c.GetDescription().empty())
+ fprintf(output_file, " -- %s", c.GetDescription().c_str());
+ fprintf(output_file, "\n");
}
+}
+
+static void
+DisplayCompletions(::EditLine *editline, FILE *output_file,
+ llvm::ArrayRef<CompletionResult::Completion> results) {
+ assert(!results.empty());
- for (size_t i = start; i < end; i++) {
- const char *completion_str = completions.GetStringAtIndex(i);
- const char *description_str = descriptions.GetStringAtIndex(i);
+ fprintf(output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n");
+ const size_t page_size = 40;
+ bool all = false;
- if (completion_str)
- fprintf(output_file, "\n\t%-*s", max_len, completion_str);
+ auto longest =
+ std::max_element(results.begin(), results.end(), [](auto &c1, auto &c2) {
+ return c1.GetCompletion().size() < c2.GetCompletion().size();
+ });
- // Print the description if we got one.
- if (description_str && strlen(description_str))
- fprintf(output_file, " -- %s", description_str);
+ const size_t max_len = longest->GetCompletion().size();
+
+ if (results.size() < page_size) {
+ PrintCompletion(output_file, results, max_len);
+ return;
+ }
+
+ size_t cur_pos = 0;
+ while (cur_pos < results.size()) {
+ size_t remaining = results.size() - cur_pos;
+ size_t next_size = all ? remaining : std::min(page_size, remaining);
+
+ PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len);
+
+ cur_pos += next_size;
+
+ if (cur_pos >= results.size())
+ break;
+
+ fprintf(output_file, "More (Y/n/a): ");
+ char reply = 'n';
+ int got_char = el_getc(editline, &reply);
+ fprintf(output_file, "\n");
+ if (got_char == -1 || reply == 'n')
+ break;
+ if (reply == 'a')
+ all = true;
}
}
@@ -891,74 +925,64 @@ unsigned char Editline::TabCommand(int ch) {
return CC_ERROR;
const LineInfo *line_info = el_line(m_editline);
- StringList completions, descriptions;
- int page_size = 40;
- const int num_completions = m_completion_callback(
- line_info->buffer, line_info->cursor, line_info->lastchar,
- 0, // Don't skip any matches (start at match zero)
- -1, // Get all the matches
- completions, descriptions, m_completion_callback_baton);
+ llvm::StringRef line(line_info->buffer,
+ line_info->lastchar - line_info->buffer);
+ unsigned cursor_index = line_info->cursor - line_info->buffer;
+ CompletionResult result;
+ CompletionRequest request(line, cursor_index, result);
- if (num_completions == 0)
+ m_completion_callback(request, m_completion_callback_baton);
+
+ llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults();
+
+ StringList completions;
+ result.GetMatches(completions);
+
+ if (results.size() == 0)
return CC_ERROR;
- // if (num_completions == -1)
- // {
- // el_insertstr (m_editline, m_completion_key);
- // return CC_REDISPLAY;
- // }
- // else
- if (num_completions == -2) {
- // Replace the entire line with the first string...
- el_deletestr(m_editline, line_info->cursor - line_info->buffer);
- el_insertstr(m_editline, completions.GetStringAtIndex(0));
+
+ if (results.size() == 1) {
+ CompletionResult::Completion completion = results.front();
+ switch (completion.GetMode()) {
+ case CompletionMode::Normal: {
+ std::string to_add = completion.GetCompletion();
+ to_add = to_add.substr(request.GetCursorArgumentPrefix().size());
+ if (request.GetParsedArg().IsQuoted())
+ to_add.push_back(request.GetParsedArg().GetQuoteChar());
+ to_add.push_back(' ');
+ el_insertstr(m_editline, to_add.c_str());
+ break;
+ }
+ case CompletionMode::Partial: {
+ std::string to_add = completion.GetCompletion();
+ to_add = to_add.substr(request.GetCursorArgumentPrefix().size());
+ el_insertstr(m_editline, to_add.c_str());
+ break;
+ }
+ case CompletionMode::RewriteLine: {
+ el_deletestr(m_editline, line_info->cursor - line_info->buffer);
+ el_insertstr(m_editline, completion.GetCompletion().c_str());
+ break;
+ }
+ }
return CC_REDISPLAY;
}
// If we get a longer match display that first.
- const char *completion_str = completions.GetStringAtIndex(0);
- if (completion_str != nullptr && *completion_str != '\0') {
- el_insertstr(m_editline, completion_str);
+ std::string longest_prefix = completions.LongestCommonPrefix();
+ if (!longest_prefix.empty())
+ longest_prefix =
+ longest_prefix.substr(request.GetCursorArgumentPrefix().size());
+ if (!longest_prefix.empty()) {
+ el_insertstr(m_editline, longest_prefix.c_str());
return CC_REDISPLAY;
}
- if (num_completions > 1) {
- int num_elements = num_completions + 1;
- fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:");
- if (num_completions < page_size) {
- PrintCompletion(m_output_file, 1, num_elements, completions,
- descriptions);
- fprintf(m_output_file, "\n");
- } else {
- int cur_pos = 1;
- char reply;
- int got_char;
- while (cur_pos < num_elements) {
- int endpoint = cur_pos + page_size;
- if (endpoint > num_elements)
- endpoint = num_elements;
-
- PrintCompletion(m_output_file, cur_pos, endpoint, completions,
- descriptions);
- cur_pos = endpoint;
-
- if (cur_pos >= num_elements) {
- fprintf(m_output_file, "\n");
- break;
- }
-
- fprintf(m_output_file, "\nMore (Y/n/a): ");
- reply = 'n';
- got_char = el_getc(m_editline, &reply);
- if (got_char == -1 || reply == 'n')
- break;
- if (reply == 'a')
- page_size = num_elements - cur_pos;
- }
- }
- DisplayInput();
- MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
- }
+ DisplayCompletions(m_editline, m_output_file, results);
+
+ DisplayInput();
+ MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
return CC_REDISPLAY;
}
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index c8c8d7a0d496..9dae24d766f6 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -37,8 +37,10 @@
using namespace lldb;
using namespace lldb_private;
+using llvm::Expected;
-static const char *GetStreamOpenModeFromOptions(uint32_t options) {
+Expected<const char *>
+File::GetStreamOpenModeFromOptions(File::OpenOptions options) {
if (options & File::eOpenOptionAppend) {
if (options & File::eOpenOptionRead) {
if (options & File::eOpenOptionCanCreateNewOnly)
@@ -65,15 +67,188 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) {
} else if (options & File::eOpenOptionWrite) {
return "w";
}
- return nullptr;
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "invalid options, cannot convert to mode string");
+}
+
+Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) {
+ OpenOptions opts =
+ llvm::StringSwitch<OpenOptions>(mode)
+ .Cases("r", "rb", eOpenOptionRead)
+ .Cases("w", "wb", eOpenOptionWrite)
+ .Cases("a", "ab",
+ eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate)
+ .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite)
+ .Cases("w+", "wb+", "w+b",
+ eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate |
+ eOpenOptionTruncate)
+ .Cases("a+", "ab+", "a+b",
+ eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend |
+ eOpenOptionCanCreate)
+ .Default(OpenOptions());
+ if (opts)
+ return opts;
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "invalid mode, cannot convert to File::OpenOptions");
}
int File::kInvalidDescriptor = -1;
FILE *File::kInvalidStream = nullptr;
-File::~File() { Close(); }
+Status File::Read(void *buf, size_t &num_bytes) {
+ return std::error_code(ENOTSUP, std::system_category());
+}
+Status File::Write(const void *buf, size_t &num_bytes) {
+ return std::error_code(ENOTSUP, std::system_category());
+}
+
+bool File::IsValid() const { return false; }
+
+Status File::Close() { return Flush(); }
+
+IOObject::WaitableHandle File::GetWaitableHandle() {
+ return IOObject::kInvalidHandleValue;
+}
-int File::GetDescriptor() const {
+Status File::GetFileSpec(FileSpec &file_spec) const {
+ file_spec.Clear();
+ return std::error_code(ENOTSUP, std::system_category());
+}
+
+int File::GetDescriptor() const { return kInvalidDescriptor; }
+
+FILE *File::GetStream() { return nullptr; }
+
+off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
+ if (error_ptr)
+ *error_ptr = std::error_code(ENOTSUP, std::system_category());
+ return -1;
+}
+
+off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
+ if (error_ptr)
+ *error_ptr = std::error_code(ENOTSUP, std::system_category());
+ return -1;
+}
+
+off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
+ if (error_ptr)
+ *error_ptr = std::error_code(ENOTSUP, std::system_category());
+ return -1;
+}
+
+Status File::Read(void *dst, size_t &num_bytes, off_t &offset) {
+ return std::error_code(ENOTSUP, std::system_category());
+}
+
+Status File::Write(const void *src, size_t &num_bytes, off_t &offset) {
+ return std::error_code(ENOTSUP, std::system_category());
+}
+
+Status File::Flush() { return Status(); }
+
+Status File::Sync() { return Flush(); }
+
+void File::CalculateInteractiveAndTerminal() {
+ const int fd = GetDescriptor();
+ if (!DescriptorIsValid(fd)) {
+ m_is_interactive = eLazyBoolNo;
+ m_is_real_terminal = eLazyBoolNo;
+ m_supports_colors = eLazyBoolNo;
+ return;
+ }
+ m_is_interactive = eLazyBoolNo;
+ m_is_real_terminal = eLazyBoolNo;
+#if defined(_WIN32)
+ if (_isatty(fd)) {
+ m_is_interactive = eLazyBoolYes;
+ m_is_real_terminal = eLazyBoolYes;
+#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ m_supports_colors = eLazyBoolYes;
+#endif
+ }
+#else
+ if (isatty(fd)) {
+ m_is_interactive = eLazyBoolYes;
+ struct winsize window_size;
+ if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) {
+ if (window_size.ws_col > 0) {
+ m_is_real_terminal = eLazyBoolYes;
+ if (llvm::sys::Process::FileDescriptorHasColors(fd))
+ m_supports_colors = eLazyBoolYes;
+ }
+ }
+ }
+#endif
+}
+
+bool File::GetIsInteractive() {
+ if (m_is_interactive == eLazyBoolCalculate)
+ CalculateInteractiveAndTerminal();
+ return m_is_interactive == eLazyBoolYes;
+}
+
+bool File::GetIsRealTerminal() {
+ if (m_is_real_terminal == eLazyBoolCalculate)
+ CalculateInteractiveAndTerminal();
+ return m_is_real_terminal == eLazyBoolYes;
+}
+
+bool File::GetIsTerminalWithColors() {
+ if (m_supports_colors == eLazyBoolCalculate)
+ CalculateInteractiveAndTerminal();
+ return m_supports_colors == eLazyBoolYes;
+}
+
+size_t File::Printf(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ size_t result = PrintfVarArg(format, args);
+ va_end(args);
+ return result;
+}
+
+size_t File::PrintfVarArg(const char *format, va_list args) {
+ size_t result = 0;
+ char *s = nullptr;
+ result = vasprintf(&s, format, args);
+ if (s != nullptr) {
+ if (result > 0) {
+ size_t s_len = result;
+ Write(s, s_len);
+ result = s_len;
+ }
+ free(s);
+ }
+ return result;
+}
+
+Expected<File::OpenOptions> File::GetOptions() const {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "GetOptions() not implemented for this File class");
+}
+
+uint32_t File::GetPermissions(Status &error) const {
+ int fd = GetDescriptor();
+ if (!DescriptorIsValid(fd)) {
+ error = std::error_code(ENOTSUP, std::system_category());
+ return 0;
+ }
+ struct stat file_stats;
+ if (::fstat(fd, &file_stats) == -1) {
+ error.SetErrorToErrno();
+ return 0;
+ }
+ error.Clear();
+ return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+}
+
+Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; }
+
+int NativeFile::GetDescriptor() const {
if (DescriptorIsValid())
return m_descriptor;
@@ -91,21 +266,18 @@ int File::GetDescriptor() const {
return kInvalidDescriptor;
}
-IOObject::WaitableHandle File::GetWaitableHandle() { return m_descriptor; }
-
-void File::SetDescriptor(int fd, bool transfer_ownership) {
- if (IsValid())
- Close();
- m_descriptor = fd;
- m_should_close_fd = transfer_ownership;
+IOObject::WaitableHandle NativeFile::GetWaitableHandle() {
+ return GetDescriptor();
}
-FILE *File::GetStream() {
+FILE *NativeFile::GetStream() {
if (!StreamIsValid()) {
if (DescriptorIsValid()) {
- const char *mode = GetStreamOpenModeFromOptions(m_options);
- if (mode) {
- if (!m_should_close_fd) {
+ auto mode = GetStreamOpenModeFromOptions(m_options);
+ if (!mode)
+ llvm::consumeError(mode.takeError());
+ else {
+ if (!m_own_descriptor) {
// We must duplicate the file descriptor if we don't own it because when you
// call fdopen, the stream will own the fd
#ifdef _WIN32
@@ -113,18 +285,18 @@ FILE *File::GetStream() {
#else
m_descriptor = dup(GetDescriptor());
#endif
- m_should_close_fd = true;
+ m_own_descriptor = true;
}
- m_stream =
- llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
+ m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor,
+ mode.get());
// If we got a stream, then we own the stream and should no longer own
// the descriptor because fclose() will close it for us
if (m_stream) {
m_own_stream = true;
- m_should_close_fd = false;
+ m_own_descriptor = false;
}
}
}
@@ -132,60 +304,32 @@ FILE *File::GetStream() {
return m_stream;
}
-void File::SetStream(FILE *fh, bool transfer_ownership) {
- if (IsValid())
- Close();
- m_stream = fh;
- m_own_stream = transfer_ownership;
-}
-
-uint32_t File::GetPermissions(Status &error) const {
- int fd = GetDescriptor();
- if (fd != kInvalidDescriptor) {
- struct stat file_stats;
- if (::fstat(fd, &file_stats) == -1)
- error.SetErrorToErrno();
- else {
- error.Clear();
- return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- }
- } else {
- error.SetErrorString("invalid file descriptor");
- }
- return 0;
-}
-
-Status File::Close() {
+Status NativeFile::Close() {
Status error;
- if (StreamIsValid() && m_own_stream) {
- if (::fclose(m_stream) == EOF)
- error.SetErrorToErrno();
+ if (StreamIsValid()) {
+ if (m_own_stream) {
+ if (::fclose(m_stream) == EOF)
+ error.SetErrorToErrno();
+ } else {
+ if (::fflush(m_stream) == EOF)
+ error.SetErrorToErrno();
+ }
}
-
- if (DescriptorIsValid() && m_should_close_fd) {
+ if (DescriptorIsValid() && m_own_descriptor) {
if (::close(m_descriptor) != 0)
error.SetErrorToErrno();
}
m_descriptor = kInvalidDescriptor;
m_stream = kInvalidStream;
- m_options = 0;
+ m_options = OpenOptions(0);
m_own_stream = false;
- m_should_close_fd = false;
+ m_own_descriptor = false;
m_is_interactive = eLazyBoolCalculate;
m_is_real_terminal = eLazyBoolCalculate;
return error;
}
-void File::Clear() {
- m_stream = nullptr;
- m_descriptor = kInvalidDescriptor;
- m_options = 0;
- m_own_stream = false;
- m_is_interactive = m_supports_colors = m_is_real_terminal =
- eLazyBoolCalculate;
-}
-
-Status File::GetFileSpec(FileSpec &file_spec) const {
+Status NativeFile::GetFileSpec(FileSpec &file_spec) const {
Status error;
#ifdef F_GETPATH
if (IsValid()) {
@@ -212,7 +356,8 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
}
}
#else
- error.SetErrorString("File::GetFileSpec is not supported on this platform");
+ error.SetErrorString(
+ "NativeFile::GetFileSpec is not supported on this platform");
#endif
if (error.Fail())
@@ -220,7 +365,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
return error;
}
-off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
+off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) {
off_t result = 0;
if (DescriptorIsValid()) {
result = ::lseek(m_descriptor, offset, SEEK_SET);
@@ -246,7 +391,7 @@ off_t File::SeekFromStart(off_t offset, Status *error_ptr) {
return result;
}
-off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
+off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) {
off_t result = -1;
if (DescriptorIsValid()) {
result = ::lseek(m_descriptor, offset, SEEK_CUR);
@@ -272,7 +417,7 @@ off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {
return result;
}
-off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
+off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) {
off_t result = -1;
if (DescriptorIsValid()) {
result = ::lseek(m_descriptor, offset, SEEK_END);
@@ -298,7 +443,7 @@ off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
return result;
}
-Status File::Flush() {
+Status NativeFile::Flush() {
Status error;
if (StreamIsValid()) {
if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
@@ -309,7 +454,7 @@ Status File::Flush() {
return error;
}
-Status File::Sync() {
+Status NativeFile::Sync() {
Status error;
if (DescriptorIsValid()) {
#ifdef _WIN32
@@ -332,7 +477,7 @@ Status File::Sync() {
#define MAX_WRITE_SIZE INT_MAX
#endif
-Status File::Read(void *buf, size_t &num_bytes) {
+Status NativeFile::Read(void *buf, size_t &num_bytes) {
Status error;
#if defined(MAX_READ_SIZE)
@@ -391,7 +536,7 @@ Status File::Read(void *buf, size_t &num_bytes) {
return error;
}
-Status File::Write(const void *buf, size_t &num_bytes) {
+Status NativeFile::Write(const void *buf, size_t &num_bytes) {
Status error;
#if defined(MAX_WRITE_SIZE)
@@ -453,7 +598,7 @@ Status File::Write(const void *buf, size_t &num_bytes) {
return error;
}
-Status File::Read(void *buf, size_t &num_bytes, off_t &offset) {
+Status NativeFile::Read(void *buf, size_t &num_bytes, off_t &offset) {
Status error;
#if defined(MAX_READ_SIZE)
@@ -513,51 +658,7 @@ Status File::Read(void *buf, size_t &num_bytes, off_t &offset) {
return error;
}
-Status File::Read(size_t &num_bytes, off_t &offset, bool null_terminate,
- DataBufferSP &data_buffer_sp) {
- Status error;
-
- if (num_bytes > 0) {
- int fd = GetDescriptor();
- if (fd != kInvalidDescriptor) {
- struct stat file_stats;
- if (::fstat(fd, &file_stats) == 0) {
- if (file_stats.st_size > offset) {
- const size_t bytes_left = file_stats.st_size - offset;
- if (num_bytes > bytes_left)
- num_bytes = bytes_left;
-
- size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0);
- std::unique_ptr<DataBufferHeap> data_heap_up;
- data_heap_up.reset(new DataBufferHeap());
- data_heap_up->SetByteSize(num_bytes_plus_nul_char);
-
- if (data_heap_up) {
- error = Read(data_heap_up->GetBytes(), num_bytes, offset);
- if (error.Success()) {
- // Make sure we read exactly what we asked for and if we got
- // less, adjust the array
- if (num_bytes_plus_nul_char < data_heap_up->GetByteSize())
- data_heap_up->SetByteSize(num_bytes_plus_nul_char);
- data_buffer_sp.reset(data_heap_up.release());
- return error;
- }
- }
- } else
- error.SetErrorString("file is empty");
- } else
- error.SetErrorToErrno();
- } else
- error.SetErrorString("invalid file handle");
- } else
- error.SetErrorString("invalid file handle");
-
- num_bytes = 0;
- data_buffer_sp.reset();
- return error;
-}
-
-Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) {
+Status NativeFile::Write(const void *buf, size_t &num_bytes, off_t &offset) {
Status error;
#if defined(MAX_WRITE_SIZE)
@@ -621,36 +722,15 @@ Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) {
return error;
}
-// Print some formatted output to the stream.
-size_t File::Printf(const char *format, ...) {
- va_list args;
- va_start(args, format);
- size_t result = PrintfVarArg(format, args);
- va_end(args);
- return result;
-}
-
-// Print some formatted output to the stream.
-size_t File::PrintfVarArg(const char *format, va_list args) {
- size_t result = 0;
- if (DescriptorIsValid()) {
- char *s = nullptr;
- result = vasprintf(&s, format, args);
- if (s != nullptr) {
- if (result > 0) {
- size_t s_len = result;
- Write(s, s_len);
- result = s_len;
- }
- free(s);
- }
- } else if (StreamIsValid()) {
- result = ::vfprintf(m_stream, format, args);
+size_t NativeFile::PrintfVarArg(const char *format, va_list args) {
+ if (StreamIsValid()) {
+ return ::vfprintf(m_stream, format, args);
+ } else {
+ return File::PrintfVarArg(format, args);
}
- return result;
}
-mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) {
+mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
mode_t mode = 0;
if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite)
mode |= O_RDWR;
@@ -674,49 +754,5 @@ mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) {
return mode;
}
-void File::CalculateInteractiveAndTerminal() {
- const int fd = GetDescriptor();
- if (fd >= 0) {
- m_is_interactive = eLazyBoolNo;
- m_is_real_terminal = eLazyBoolNo;
-#if defined(_WIN32)
- if (_isatty(fd)) {
- m_is_interactive = eLazyBoolYes;
- m_is_real_terminal = eLazyBoolYes;
-#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
- m_supports_colors = eLazyBoolYes;
-#endif
- }
-#else
- if (isatty(fd)) {
- m_is_interactive = eLazyBoolYes;
- struct winsize window_size;
- if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) {
- if (window_size.ws_col > 0) {
- m_is_real_terminal = eLazyBoolYes;
- if (llvm::sys::Process::FileDescriptorHasColors(fd))
- m_supports_colors = eLazyBoolYes;
- }
- }
- }
-#endif
- }
-}
-
-bool File::GetIsInteractive() {
- if (m_is_interactive == eLazyBoolCalculate)
- CalculateInteractiveAndTerminal();
- return m_is_interactive == eLazyBoolYes;
-}
-
-bool File::GetIsRealTerminal() {
- if (m_is_real_terminal == eLazyBoolCalculate)
- CalculateInteractiveAndTerminal();
- return m_is_real_terminal == eLazyBoolYes;
-}
-
-bool File::GetIsTerminalWithColors() {
- if (m_supports_colors == eLazyBoolCalculate)
- CalculateInteractiveAndTerminal();
- return m_supports_colors == eLazyBoolYes;
-}
+char File::ID = 0;
+char NativeFile::ID = 0;
diff --git a/source/Host/common/FileCache.cpp b/source/Host/common/FileCache.cpp
index 4bd3efda7fb0..d9dcad992c33 100644
--- a/source/Host/common/FileCache.cpp
+++ b/source/Host/common/FileCache.cpp
@@ -23,18 +23,20 @@ FileCache &FileCache::GetInstance() {
return *m_instance;
}
-lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags,
- uint32_t mode, Status &error) {
+lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec,
+ File::OpenOptions flags, uint32_t mode,
+ Status &error) {
if (!file_spec) {
error.SetErrorString("empty path");
return UINT64_MAX;
}
- FileSP file_sp(new File());
- error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode);
- if (!file_sp->IsValid())
+ auto file = FileSystem::Instance().Open(file_spec, flags, mode);
+ if (!file) {
+ error = file.takeError();
return UINT64_MAX;
- lldb::user_id_t fd = file_sp->GetDescriptor();
- m_cache[fd] = file_sp;
+ }
+ lldb::user_id_t fd = file.get()->GetDescriptor();
+ m_cache[fd] = std::move(file.get());
return fd;
}
@@ -48,12 +50,12 @@ bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) {
error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
return false;
}
- FileSP file_sp = pos->second;
- if (!file_sp) {
+ FileUP &file_up = pos->second;
+ if (!file_up) {
error.SetErrorString("invalid host backing file");
return false;
}
- error = file_sp->Close();
+ error = file_up->Close();
m_cache.erase(pos);
return error.Success();
}
@@ -70,16 +72,16 @@ uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset,
error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
return false;
}
- FileSP file_sp = pos->second;
- if (!file_sp) {
+ FileUP &file_up = pos->second;
+ if (!file_up) {
error.SetErrorString("invalid host backing file");
return UINT64_MAX;
}
- if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset ||
+ if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||
error.Fail())
return UINT64_MAX;
size_t bytes_written = src_len;
- error = file_sp->Write(src, bytes_written);
+ error = file_up->Write(src, bytes_written);
if (error.Fail())
return UINT64_MAX;
return bytes_written;
@@ -96,16 +98,16 @@ uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);
return false;
}
- FileSP file_sp = pos->second;
- if (!file_sp) {
+ FileUP &file_up = pos->second;
+ if (!file_up) {
error.SetErrorString("invalid host backing file");
return UINT64_MAX;
}
- if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset ||
+ if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||
error.Fail())
return UINT64_MAX;
size_t bytes_read = dst_len;
- error = file_sp->Read(dst, bytes_read);
+ error = file_up->Read(dst, bytes_read);
if (error.Fail())
return UINT64_MAX;
return bytes_read;
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index d5ac05bd447c..2db5bff3207f 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -49,7 +49,7 @@ void FileSystem::Initialize() {
InstanceImpl().emplace();
}
-void FileSystem::Initialize(FileCollector &collector) {
+void FileSystem::Initialize(std::shared_ptr<FileCollector> collector) {
lldbassert(!InstanceImpl() && "Already initialized.");
InstanceImpl().emplace(collector);
}
@@ -280,7 +280,7 @@ std::shared_ptr<DataBufferLLVM>
FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
uint64_t offset) {
if (m_collector)
- m_collector->AddFile(path);
+ m_collector->addFile(path);
const bool is_volatile = !IsLocal(path);
const ErrorOr<std::string> external_path = GetExternalPath(path);
@@ -415,13 +415,11 @@ static mode_t GetOpenMode(uint32_t permissions) {
return mode;
}
-Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options,
- uint32_t permissions, bool should_close_fd) {
+Expected<FileUP> FileSystem::Open(const FileSpec &file_spec,
+ File::OpenOptions options,
+ uint32_t permissions, bool should_close_fd) {
if (m_collector)
- m_collector->AddFile(file_spec);
-
- if (File.IsValid())
- File.Close();
+ m_collector->addFile(file_spec.GetPath());
const int open_flags = GetOpenFlags(options);
const mode_t open_mode =
@@ -429,20 +427,19 @@ Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options,
auto path = GetExternalPath(file_spec);
if (!path)
- return Status(path.getError());
+ return errorCodeToError(path.getError());
int descriptor = llvm::sys::RetryAfterSignal(
-1, OpenWithFS, *this, path->c_str(), open_flags, open_mode);
- Status error;
- if (!File::DescriptorIsValid(descriptor)) {
- File.SetDescriptor(descriptor, false);
- error.SetErrorToErrno();
- } else {
- File.SetDescriptor(descriptor, should_close_fd);
- File.SetOptions(options);
- }
- return error;
+ if (!File::DescriptorIsValid(descriptor))
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::system_category()));
+
+ auto file = std::unique_ptr<File>(
+ new NativeFile(descriptor, options, should_close_fd));
+ assert(file->IsValid());
+ return std::move(file);
}
ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) {
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 3ba9ab7f21f3..8e210c7e5fa5 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -164,8 +164,7 @@ static bool CheckForMonitorCancellation() {
static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
const char *function = __FUNCTION__;
- if (log)
- log->Printf("%s (arg = %p) thread starting...", function, arg);
+ LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg);
MonitorInfo *info = (MonitorInfo *)arg;
@@ -193,9 +192,8 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
while (1) {
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...",
- function, pid, options);
+ LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...",
+ function, pid, options);
if (CheckForMonitorCancellation())
break;
@@ -245,12 +243,12 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
#endif
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf("%s ::waitpid (pid = %" PRIi32
- ", &status, options = %i) => pid = %" PRIi32
- ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
- function, pid, options, wait_pid, status, status_cstr,
- signal, exit_status);
+ LLDB_LOGF(log,
+ "%s ::waitpid (pid = %" PRIi32
+ ", &status, options = %i) => pid = %" PRIi32
+ ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+ function, pid, options, wait_pid, status, status_cstr, signal,
+ exit_status);
if (exited || (signal != 0 && monitor_signals)) {
bool callback_return = false;
@@ -259,18 +257,18 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
// If our process exited, then this thread should exit
if (exited && wait_pid == abs(pid)) {
- if (log)
- log->Printf("%s (arg = %p) thread exiting because pid received "
- "exit signal...",
- __FUNCTION__, arg);
+ LLDB_LOGF(log,
+ "%s (arg = %p) thread exiting because pid received "
+ "exit signal...",
+ __FUNCTION__, arg);
break;
}
// If the callback returns true, it means this process should exit
if (callback_return) {
- if (log)
- log->Printf("%s (arg = %p) thread exiting because callback "
- "returned true...",
- __FUNCTION__, arg);
+ LLDB_LOGF(log,
+ "%s (arg = %p) thread exiting because callback "
+ "returned true...",
+ __FUNCTION__, arg);
break;
}
}
@@ -279,8 +277,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
}
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
+ LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg);
return nullptr;
}
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index 130f0eb8ac8d..3765f36fc79a 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -221,25 +221,24 @@ bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec,
return false;
std::string raw_path = lldb_file_spec.GetPath();
- if (log)
- log->Printf("HostInfo::%s() attempting to "
- "derive the path %s relative to liblldb install path: %s",
- __FUNCTION__, dir.data(), raw_path.c_str());
+ LLDB_LOGF(log,
+ "HostInfo::%s() attempting to "
+ "derive the path %s relative to liblldb install path: %s",
+ __FUNCTION__, dir.data(), raw_path.c_str());
// Drop bin (windows) or lib
llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
if (parent_path.empty()) {
- if (log)
- log->Printf("HostInfo::%s() failed to find liblldb within the shared "
- "lib path",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "HostInfo::%s() failed to find liblldb within the shared "
+ "lib path",
+ __FUNCTION__);
return false;
}
raw_path = (parent_path + dir).str();
- if (log)
- log->Printf("HostInfo::%s() derived the path as: %s", __FUNCTION__,
- raw_path.c_str());
+ LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__,
+ raw_path.c_str());
file_spec.GetDirectory().SetString(raw_path);
return (bool)file_spec.GetDirectory();
}
diff --git a/source/Host/common/HostNativeThreadBase.cpp b/source/Host/common/HostNativeThreadBase.cpp
index a5f876a7232a..fe7d85acaf11 100644
--- a/source/Host/common/HostNativeThreadBase.cpp
+++ b/source/Host/common/HostNativeThreadBase.cpp
@@ -62,8 +62,7 @@ HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) {
thread_arg_t thread_arg = info->thread_arg;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("thread created");
+ LLDB_LOGF(log, "thread created");
delete info;
return thread_fptr(thread_arg);
diff --git a/source/Host/common/LZMA.cpp b/source/Host/common/LZMA.cpp
new file mode 100644
index 000000000000..02be8a09df66
--- /dev/null
+++ b/source/Host/common/LZMA.cpp
@@ -0,0 +1,146 @@
+//===-- LZMA.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/Host/Config.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+#if LLDB_ENABLE_LZMA
+#include <lzma.h>
+#endif // LLDB_ENABLE_LZMA
+
+namespace lldb_private {
+
+namespace lzma {
+
+#if !LLDB_ENABLE_LZMA
+bool isAvailable() { return false; }
+llvm::Expected<uint64_t>
+getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) {
+ llvm_unreachable("lzma::getUncompressedSize is unavailable");
+}
+
+llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
+ llvm::SmallVectorImpl<uint8_t> &Uncompressed) {
+ llvm_unreachable("lzma::uncompress is unavailable");
+}
+
+#else // LLDB_ENABLE_LZMA
+
+bool isAvailable() { return true; }
+
+static const char *convertLZMACodeToString(lzma_ret Code) {
+ switch (Code) {
+ case LZMA_STREAM_END:
+ return "lzma error: LZMA_STREAM_END";
+ case LZMA_NO_CHECK:
+ return "lzma error: LZMA_NO_CHECK";
+ case LZMA_UNSUPPORTED_CHECK:
+ return "lzma error: LZMA_UNSUPPORTED_CHECK";
+ case LZMA_GET_CHECK:
+ return "lzma error: LZMA_GET_CHECK";
+ case LZMA_MEM_ERROR:
+ return "lzma error: LZMA_MEM_ERROR";
+ case LZMA_MEMLIMIT_ERROR:
+ return "lzma error: LZMA_MEMLIMIT_ERROR";
+ case LZMA_FORMAT_ERROR:
+ return "lzma error: LZMA_FORMAT_ERROR";
+ case LZMA_OPTIONS_ERROR:
+ return "lzma error: LZMA_OPTIONS_ERROR";
+ case LZMA_DATA_ERROR:
+ return "lzma error: LZMA_DATA_ERROR";
+ case LZMA_BUF_ERROR:
+ return "lzma error: LZMA_BUF_ERROR";
+ case LZMA_PROG_ERROR:
+ return "lzma error: LZMA_PROG_ERROR";
+ default:
+ llvm_unreachable("unknown or unexpected lzma status code");
+ }
+}
+
+llvm::Expected<uint64_t>
+getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) {
+ lzma_stream_flags opts{};
+ if (InputBuffer.size() < LZMA_STREAM_HEADER_SIZE) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "size of xz-compressed blob (%lu bytes) is smaller than the "
+ "LZMA_STREAM_HEADER_SIZE (%lu bytes)",
+ InputBuffer.size(), LZMA_STREAM_HEADER_SIZE);
+ }
+
+ // Decode xz footer.
+ lzma_ret xzerr = lzma_stream_footer_decode(
+ &opts, InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE).data());
+ if (xzerr != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_stream_footer_decode()=%s",
+ convertLZMACodeToString(xzerr));
+ }
+ if (InputBuffer.size() < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "xz-compressed buffer size (%lu bytes) too small (required at "
+ "least %lu bytes) ",
+ InputBuffer.size(), (opts.backward_size + LZMA_STREAM_HEADER_SIZE));
+ }
+
+ // Decode xz index.
+ lzma_index *xzindex;
+ uint64_t memlimit(UINT64_MAX);
+ size_t inpos = 0;
+ xzerr = lzma_index_buffer_decode(
+ &xzindex, &memlimit, nullptr,
+ InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE + opts.backward_size)
+ .data(),
+ &inpos, InputBuffer.size());
+ if (xzerr != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_index_buffer_decode()=%s",
+ convertLZMACodeToString(xzerr));
+ }
+
+ // Get size of uncompressed file to construct an in-memory buffer of the
+ // same size on the calling end (if needed).
+ uint64_t uncompressedSize = lzma_index_uncompressed_size(xzindex);
+
+ // Deallocate xz index as it is no longer needed.
+ lzma_index_end(xzindex, nullptr);
+
+ return uncompressedSize;
+}
+
+llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer,
+ llvm::SmallVectorImpl<uint8_t> &Uncompressed) {
+ llvm::Expected<uint64_t> uncompressedSize = getUncompressedSize(InputBuffer);
+
+ if (auto err = uncompressedSize.takeError())
+ return err;
+
+ Uncompressed.resize(*uncompressedSize);
+
+ // Decompress xz buffer to buffer.
+ uint64_t memlimit = UINT64_MAX;
+ size_t inpos = 0;
+ size_t outpos = 0;
+ lzma_ret ret = lzma_stream_buffer_decode(
+ &memlimit, 0, nullptr, InputBuffer.data(), &inpos, InputBuffer.size(),
+ Uncompressed.data(), &outpos, Uncompressed.size());
+ if (ret != LZMA_OK) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "lzma_stream_buffer_decode()=%s",
+ convertLZMACodeToString(ret));
+ }
+
+ return llvm::Error::success();
+}
+
+#endif // LLDB_ENABLE_LZMA
+
+} // end of namespace lzma
+} // namespace lldb_private
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 1ce09a84671c..6f774451c8a4 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -320,6 +320,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
// Even if using kqueue, the signal handler will still be invoked, so it's
// important to replace it with our "benign" handler.
int ret = sigaction(signo, &new_action, &info.old_action);
+ (void)ret;
assert(ret == 0 && "sigaction failed");
#if HAVE_SYS_EVENT_H
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 90272cb8d0bc..fd349cc2915b 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -16,6 +16,8 @@
#include "lldb/Utility/State.h"
#include "lldb/lldb-enumerations.h"
+#include "llvm/Support/Process.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -329,22 +331,23 @@ void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged(
if (log) {
if (!m_delegates.empty()) {
- log->Printf("NativeProcessProtocol::%s: sent state notification [%s] "
- "from process %" PRIu64,
- __FUNCTION__, lldb_private::StateAsCString(state), GetID());
+ LLDB_LOGF(log,
+ "NativeProcessProtocol::%s: sent state notification [%s] "
+ "from process %" PRIu64,
+ __FUNCTION__, lldb_private::StateAsCString(state), GetID());
} else {
- log->Printf("NativeProcessProtocol::%s: would send state notification "
- "[%s] from process %" PRIu64 ", but no delegates",
- __FUNCTION__, lldb_private::StateAsCString(state), GetID());
+ LLDB_LOGF(log,
+ "NativeProcessProtocol::%s: would send state notification "
+ "[%s] from process %" PRIu64 ", but no delegates",
+ __FUNCTION__, lldb_private::StateAsCString(state), GetID());
}
}
}
void NativeProcessProtocol::NotifyDidExec() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessProtocol::%s - preparing to call delegates",
- __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessProtocol::%s - preparing to call delegates",
+ __FUNCTION__);
{
std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
@@ -524,6 +527,7 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
switch (GetArchitecture().GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return llvm::makeArrayRef(g_aarch64_opcode);
case llvm::Triple::x86:
@@ -560,6 +564,7 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
case llvm::Triple::arm:
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
case llvm::Triple::mips:
@@ -659,6 +664,58 @@ Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,
return Status();
}
+llvm::Expected<llvm::StringRef>
+NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer,
+ size_t max_size,
+ size_t &total_bytes_read) {
+ static const size_t cache_line_size =
+ llvm::sys::Process::getPageSizeEstimate();
+ size_t bytes_read = 0;
+ size_t bytes_left = max_size;
+ addr_t curr_addr = addr;
+ size_t string_size;
+ char *curr_buffer = buffer;
+ total_bytes_read = 0;
+ Status status;
+
+ while (bytes_left > 0 && status.Success()) {
+ addr_t cache_line_bytes_left =
+ cache_line_size - (curr_addr % cache_line_size);
+ addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+ status = ReadMemory(curr_addr, reinterpret_cast<void *>(curr_buffer),
+ bytes_to_read, bytes_read);
+
+ if (bytes_read == 0)
+ break;
+
+ void *str_end = std::memchr(curr_buffer, '\0', bytes_read);
+ if (str_end != nullptr) {
+ total_bytes_read =
+ (size_t)(reinterpret_cast<char *>(str_end) - buffer + 1);
+ status.Clear();
+ break;
+ }
+
+ total_bytes_read += bytes_read;
+ curr_buffer += bytes_read;
+ curr_addr += bytes_read;
+ bytes_left -= bytes_read;
+ }
+
+ string_size = total_bytes_read - 1;
+
+ // Make sure we return a null terminated string.
+ if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') {
+ buffer[max_size - 1] = '\0';
+ total_bytes_read--;
+ }
+
+ if (!status.Success())
+ return status.ToError();
+
+ return llvm::StringRef(buffer, string_size);
+}
+
lldb::StateType NativeProcessProtocol::GetState() const {
std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
return m_state;
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 2f30d52aea63..fe40073eb59d 100644
--- a/source/Host/common/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -114,16 +114,15 @@ lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) {
uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_PC);
- if (log)
- log->Printf("NativeRegisterContext::%s using reg index %" PRIu32
- " (default %" PRIu64 ")",
- __FUNCTION__, reg, fail_value);
+ LLDB_LOGF(log,
+ "NativeRegisterContext::%s using reg index %" PRIu32
+ " (default %" PRIu64 ")",
+ __FUNCTION__, reg, fail_value);
const uint64_t retval = ReadRegisterAsUnsigned(reg, fail_value);
- if (log)
- log->Printf("NativeRegisterContext::%s " PRIu32 " retval %" PRIu64,
- __FUNCTION__, retval);
+ LLDB_LOGF(log, "NativeRegisterContext::%s " PRIu32 " retval %" PRIu64,
+ __FUNCTION__, retval);
return retval;
}
@@ -192,20 +191,19 @@ NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
RegisterValue value;
Status error = ReadRegister(reg_info, value);
if (error.Success()) {
- if (log)
- log->Printf("NativeRegisterContext::%s ReadRegister() succeeded, value "
- "%" PRIu64,
- __FUNCTION__, value.GetAsUInt64());
+ LLDB_LOGF(log,
+ "NativeRegisterContext::%s ReadRegister() succeeded, value "
+ "%" PRIu64,
+ __FUNCTION__, value.GetAsUInt64());
return value.GetAsUInt64();
} else {
- if (log)
- log->Printf("NativeRegisterContext::%s ReadRegister() failed, error %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeRegisterContext::%s ReadRegister() failed, error %s",
+ __FUNCTION__, error.AsCString());
}
} else {
- if (log)
- log->Printf("NativeRegisterContext::%s ReadRegister() null reg_info",
- __FUNCTION__);
+ LLDB_LOGF(log, "NativeRegisterContext::%s ReadRegister() null reg_info",
+ __FUNCTION__);
}
return fail_value;
}
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index a89f1178e96c..6358ab8a8e77 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -74,9 +74,10 @@ bool IsInterrupted() {
Socket::Socket(SocketProtocol protocol, bool should_close,
bool child_processes_inherit)
- : IOObject(eFDTypeSocket, should_close), m_protocol(protocol),
+ : IOObject(eFDTypeSocket), m_protocol(protocol),
m_socket(kInvalidSocketValue),
- m_child_processes_inherit(child_processes_inherit) {}
+ m_child_processes_inherit(child_processes_inherit),
+ m_should_close_fd(should_close) {}
Socket::~Socket() { Close(); }
@@ -114,16 +115,16 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
switch (protocol) {
case ProtocolTcp:
socket_up =
- llvm::make_unique<TCPSocket>(true, child_processes_inherit);
+ std::make_unique<TCPSocket>(true, child_processes_inherit);
break;
case ProtocolUdp:
socket_up =
- llvm::make_unique<UDPSocket>(true, child_processes_inherit);
+ std::make_unique<UDPSocket>(true, child_processes_inherit);
break;
case ProtocolUnixDomain:
#ifndef LLDB_DISABLE_POSIX
socket_up =
- llvm::make_unique<DomainSocket>(true, child_processes_inherit);
+ std::make_unique<DomainSocket>(true, child_processes_inherit);
#else
error.SetErrorString(
"Unix domain sockets are not supported on this platform.");
@@ -132,7 +133,7 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
case ProtocolUnixAbstract:
#ifdef __linux__
socket_up =
- llvm::make_unique<AbstractSocket>(child_processes_inherit);
+ std::make_unique<AbstractSocket>(child_processes_inherit);
#else
error.SetErrorString(
"Abstract domain sockets are not supported on this platform.");
@@ -149,9 +150,8 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
Status Socket::TcpConnect(llvm::StringRef host_and_port,
bool child_processes_inherit, Socket *&socket) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
- if (log)
- log->Printf("Socket::%s (host/port = %s)", __FUNCTION__,
- host_and_port.str().c_str());
+ LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__,
+ host_and_port.str().c_str());
Status error;
std::unique_ptr<Socket> connect_socket(
@@ -170,8 +170,7 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,
bool child_processes_inherit, Socket *&socket,
Predicate<uint16_t> *predicate, int backlog) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str());
+ LLDB_LOGF(log, "Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str());
Status error;
std::string host_str;
@@ -209,9 +208,8 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,
Status Socket::UdpConnect(llvm::StringRef host_and_port,
bool child_processes_inherit, Socket *&socket) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("Socket::%s (host/port = %s)", __FUNCTION__,
- host_and_port.str().c_str());
+ LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__,
+ host_and_port.str().c_str());
return UDPSocket::Connect(host_and_port, child_processes_inherit, socket);
}
@@ -285,27 +283,25 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
int32_t &port, Status *error_ptr) {
static RegularExpression g_regex(
llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)"));
- RegularExpression::Match regex_match(2);
- if (g_regex.Execute(host_and_port, &regex_match)) {
- if (regex_match.GetMatchAtIndex(host_and_port, 1, host_str) &&
- regex_match.GetMatchAtIndex(host_and_port, 2, port_str)) {
- // IPv6 addresses are wrapped in [] when specified with ports
- if (host_str.front() == '[' && host_str.back() == ']')
- host_str = host_str.substr(1, host_str.size() - 2);
- bool ok = false;
- port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok);
- if (ok && port <= UINT16_MAX) {
- if (error_ptr)
- error_ptr->Clear();
- return true;
- }
- // port is too large
+ llvm::SmallVector<llvm::StringRef, 3> matches;
+ if (g_regex.Execute(host_and_port, &matches)) {
+ host_str = matches[1].str();
+ port_str = matches[2].str();
+ // IPv6 addresses are wrapped in [] when specified with ports
+ if (host_str.front() == '[' && host_str.back() == ']')
+ host_str = host_str.substr(1, host_str.size() - 2);
+ bool ok = false;
+ port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok);
+ if (ok && port <= UINT16_MAX) {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
- "invalid host:port specification: '%s'",
- host_and_port.str().c_str());
- return false;
+ error_ptr->Clear();
+ return true;
}
+ // port is too large
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat(
+ "invalid host:port specification: '%s'", host_and_port.str().c_str());
+ return false;
}
// If this was unsuccessful, then check if it's simply a signed 32-bit
@@ -345,18 +341,20 @@ Status Socket::Read(void *buf, size_t &num_bytes) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
if (log) {
- log->Printf("%p Socket::Read() (socket = %" PRIu64
- ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
- " (error = %s)",
- static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
- static_cast<uint64_t>(num_bytes),
- static_cast<int64_t>(bytes_received), error.AsCString());
+ LLDB_LOGF(log,
+ "%p Socket::Read() (socket = %" PRIu64
+ ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
+ " (error = %s)",
+ static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
+ static_cast<uint64_t>(num_bytes),
+ static_cast<int64_t>(bytes_received), error.AsCString());
}
return error;
}
Status Socket::Write(const void *buf, size_t &num_bytes) {
+ const size_t src_len = num_bytes;
Status error;
int bytes_sent = 0;
do {
@@ -371,12 +369,13 @@ Status Socket::Write(const void *buf, size_t &num_bytes) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
if (log) {
- log->Printf("%p Socket::Write() (socket = %" PRIu64
- ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
- " (error = %s)",
- static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
- static_cast<uint64_t>(num_bytes),
- static_cast<int64_t>(bytes_sent), error.AsCString());
+ LLDB_LOGF(log,
+ "%p Socket::Write() (socket = %" PRIu64
+ ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
+ " (error = %s)",
+ static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
+ static_cast<uint64_t>(src_len),
+ static_cast<int64_t>(bytes_sent), error.AsCString());
}
return error;
@@ -393,9 +392,8 @@ Status Socket::Close() {
return error;
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p Socket::Close (fd = %" PRIu64 ")",
- static_cast<void *>(this), static_cast<uint64_t>(m_socket));
+ LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")",
+ static_cast<void *>(this), static_cast<uint64_t>(m_socket));
#if defined(_WIN32)
bool success = !!closesocket(m_socket);
@@ -479,11 +477,11 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
if (!child_processes_inherit) {
flags |= SOCK_CLOEXEC;
}
- NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept4,
- sockfd, addr, addrlen, flags);
+ NativeSocket fd = llvm::sys::RetryAfterSignal(
+ static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags);
#else
- NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept,
- sockfd, addr, addrlen);
+ NativeSocket fd = llvm::sys::RetryAfterSignal(
+ static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen);
#endif
if (fd == kInvalidSocketValue)
SetLastError(error);
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index 58f99f7832fe..e84054f3f581 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -140,8 +140,7 @@ Status TCPSocket::CreateSocket(int domain) {
Status TCPSocket::Connect(llvm::StringRef name) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
- if (log)
- log->Printf("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
+ LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
Status error;
std::string host_str;
@@ -177,8 +176,7 @@ Status TCPSocket::Connect(llvm::StringRef name) {
Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data());
+ LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data());
Status error;
std::string host_str;
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 8dbf57d6fe4e..7accbb651ba9 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -58,8 +58,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
std::unique_ptr<UDPSocket> final_socket;
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
+ LLDB_LOGF(log, "UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
Status error;
std::string host_str;
@@ -81,7 +80,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
&service_info_list);
if (err != 0) {
error.SetErrorStringWithFormat(
-#if defined(_MSC_VER) && defined(UNICODE)
+#if defined(_WIN32) && defined(UNICODE)
"getaddrinfo(%s, %s, &hints, &info) returned error %i (%S)",
#else
"getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp
index e28cf4aa420f..7fc6f43d4676 100644
--- a/source/Host/freebsd/HostInfoFreeBSD.cpp
+++ b/source/Host/freebsd/HostInfoFreeBSD.cpp
@@ -64,13 +64,10 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() {
static FileSpec g_program_filespec;
if (!g_program_filespec) {
int exe_path_mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid()};
- size_t exe_path_size;
- if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) {
- char *exe_path = new char[exe_path_size];
- if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
- g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
- delete[] exe_path;
- }
+ char exe_path[PATH_MAX];
+ size_t exe_path_size = sizeof(exe_path);
+ if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
+ g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
}
return g_program_filespec;
}
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 067e85972eca..325d854921e3 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -79,23 +79,22 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
m_child_processes_inherit(child_processes_inherit) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
+ static_cast<void *>(this));
}
ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)
: Connection(), m_pipe(), m_mutex(), m_shutting_down(false),
m_waiting_for_accept(false), m_child_processes_inherit(false) {
- m_write_sp = std::make_shared<File>(fd, owns_fd);
- m_read_sp = std::make_shared<File>(fd, false);
+ m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, owns_fd);
+ m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false);
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = "
- "%i, owns_fd = %i)",
- static_cast<void *>(this), fd, owns_fd);
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = "
+ "%i, owns_fd = %i)",
+ static_cast<void *>(this), fd, owns_fd);
OpenCommandPipe();
}
@@ -108,9 +107,8 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket)
ConnectionFileDescriptor::~ConnectionFileDescriptor() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
+ static_cast<void *>(this));
Disconnect(nullptr);
CloseCommandPipe();
}
@@ -122,24 +120,23 @@ void ConnectionFileDescriptor::OpenCommandPipe() {
// Make the command file descriptor here:
Status result = m_pipe.CreateNew(m_child_processes_inherit);
if (!result.Success()) {
- if (log)
- log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe () - could not "
- "make pipe: %s",
- static_cast<void *>(this), result.AsCString());
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::OpenCommandPipe () - could not "
+ "make pipe: %s",
+ static_cast<void *>(this), result.AsCString());
} else {
- if (log)
- log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe() - success "
- "readfd=%d writefd=%d",
- static_cast<void *>(this), m_pipe.GetReadFileDescriptor(),
- m_pipe.GetWriteFileDescriptor());
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::OpenCommandPipe() - success "
+ "readfd=%d writefd=%d",
+ static_cast<void *>(this), m_pipe.GetReadFileDescriptor(),
+ m_pipe.GetWriteFileDescriptor());
}
}
void ConnectionFileDescriptor::CloseCommandPipe() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::CloseCommandPipe()",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "%p ConnectionFileDescriptor::CloseCommandPipe()",
+ static_cast<void *>(this));
m_pipe.Close();
}
@@ -153,9 +150,8 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
Status *error_ptr) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::Connect (url = '%s')",
- static_cast<void *>(this), path.str().c_str());
+ LLDB_LOGF(log, "%p ConnectionFileDescriptor::Connect (url = '%s')",
+ static_cast<void *>(this), path.str().c_str());
OpenCommandPipe();
@@ -222,8 +218,10 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
m_read_sp = std::move(tcp_socket);
m_write_sp = m_read_sp;
} else {
- m_read_sp = std::make_shared<File>(fd, false);
- m_write_sp = std::make_shared<File>(fd, false);
+ m_read_sp =
+ std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false);
+ m_write_sp =
+ std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);
}
m_uri = *addr;
return eConnectionStatusSuccess;
@@ -272,8 +270,8 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
::fcntl(fd, F_SETFL, flags);
}
}
- m_read_sp = std::make_shared<File>(fd, true);
- m_write_sp = std::make_shared<File>(fd, false);
+ m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, true);
+ m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);
return eConnectionStatusSuccess;
}
#endif
@@ -295,17 +293,15 @@ bool ConnectionFileDescriptor::InterruptRead() {
ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionFileDescriptor::Disconnect ()",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "%p ConnectionFileDescriptor::Disconnect ()",
+ static_cast<void *>(this));
ConnectionStatus status = eConnectionStatusSuccess;
if (!IsConnected()) {
- if (log)
- log->Printf(
- "%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect",
- static_cast<void *>(this));
+ LLDB_LOGF(
+ log, "%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect",
+ static_cast<void *>(this));
return eConnectionStatusSuccess;
}
@@ -318,27 +314,28 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
// descriptor. If that's the case, then send the "q" char to the command
// file channel so the read will wake up and the connection will then know to
// shut down.
-
- m_shutting_down = true;
-
std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
if (!locker.try_lock()) {
if (m_pipe.CanWrite()) {
size_t bytes_written = 0;
Status result = m_pipe.Write("q", 1, bytes_written);
- if (log)
- log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get "
- "the lock, sent 'q' to %d, error = '%s'.",
- static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(),
- result.AsCString());
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Disconnect(): Couldn't get "
+ "the lock, sent 'q' to %d, error = '%s'.",
+ static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(),
+ result.AsCString());
} else if (log) {
- log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the "
- "lock, but no command pipe is available.",
- static_cast<void *>(this));
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Disconnect(): Couldn't get the "
+ "lock, but no command pipe is available.",
+ static_cast<void *>(this));
}
locker.lock();
}
+ // Prevents reads and writes during shutdown.
+ m_shutting_down = true;
+
Status error = m_read_sp->Close();
Status error2 = m_write_sp->Close();
if (error.Fail() || error2.Fail())
@@ -362,10 +359,10 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
if (!locker.try_lock()) {
- if (log)
- log->Printf("%p ConnectionFileDescriptor::Read () failed to get the "
- "connection lock.",
- static_cast<void *>(this));
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Read () failed to get the "
+ "connection lock.",
+ static_cast<void *>(this));
if (error_ptr)
error_ptr->SetErrorString("failed to get the connection lock for read.");
@@ -374,6 +371,8 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
}
if (m_shutting_down) {
+ if (error_ptr)
+ error_ptr->SetErrorString("shutting down");
status = eConnectionStatusError;
return 0;
}
@@ -387,12 +386,13 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
error = m_read_sp->Read(dst, bytes_read);
if (log) {
- log->Printf("%p ConnectionFileDescriptor::Read() fd = %" PRIu64
- ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s",
- static_cast<void *>(this),
- static_cast<uint64_t>(m_read_sp->GetWaitableHandle()),
- static_cast<void *>(dst), static_cast<uint64_t>(dst_len),
- static_cast<uint64_t>(bytes_read), error.AsCString());
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Read() fd = %" PRIu64
+ ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s",
+ static_cast<void *>(this),
+ static_cast<uint64_t>(m_read_sp->GetWaitableHandle()),
+ static_cast<void *>(dst), static_cast<uint64_t>(dst_len),
+ static_cast<uint64_t>(bytes_read), error.AsCString());
}
if (bytes_read == 0) {
@@ -464,11 +464,11 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,
ConnectionStatus &status,
Status *error_ptr) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf(
- "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")",
- static_cast<void *>(this), static_cast<const void *>(src),
- static_cast<uint64_t>(src_len));
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64
+ ")",
+ static_cast<void *>(this), static_cast<const void *>(src),
+ static_cast<uint64_t>(src_len));
if (!IsConnected()) {
if (error_ptr)
@@ -477,19 +477,26 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,
return 0;
}
+ if (m_shutting_down) {
+ if (error_ptr)
+ error_ptr->SetErrorString("shutting down");
+ status = eConnectionStatusError;
+ return 0;
+ }
+
Status error;
size_t bytes_sent = src_len;
error = m_write_sp->Write(src, bytes_sent);
if (log) {
- log->Printf("%p ConnectionFileDescriptor::Write(fd = %" PRIu64
- ", src = %p, src_len = %" PRIu64 ") => %" PRIu64
- " (error = %s)",
- static_cast<void *>(this),
- static_cast<uint64_t>(m_write_sp->GetWaitableHandle()),
- static_cast<const void *>(src), static_cast<uint64_t>(src_len),
- static_cast<uint64_t>(bytes_sent), error.AsCString());
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::Write(fd = %" PRIu64
+ ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)",
+ static_cast<void *>(this),
+ static_cast<uint64_t>(m_write_sp->GetWaitableHandle()),
+ static_cast<const void *>(src), static_cast<uint64_t>(src_len),
+ static_cast<uint64_t>(bytes_sent), error.AsCString());
}
if (error_ptr)
@@ -559,7 +566,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
select_helper.SetTimeout(*timeout);
select_helper.FDSetRead(handle);
-#if defined(_MSC_VER)
+#if defined(_WIN32)
// select() won't accept pipes on Windows. The entire Windows codepath
// needs to be converted over to using WaitForMultipleObjects and event
// HANDLEs, but for now at least this will allow ::select() to not return
@@ -613,10 +620,10 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
(void)bytes_read;
switch (c) {
case 'q':
- if (log)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() "
- "got data: %c from the command channel.",
- static_cast<void *>(this), c);
+ LLDB_LOGF(log,
+ "%p ConnectionFileDescriptor::BytesAvailable() "
+ "got data: %c from the command channel.",
+ static_cast<void *>(this), c);
return eConnectionStatusEndOfFile;
case 'i':
// Interrupt the current read
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index f300e22e9e5c..63cc5dc65e00 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/posix/HostInfoPosix.h"
-#include "lldb/Utility/UserIDResolver.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/UserIDResolver.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
@@ -18,7 +18,6 @@
#include <grp.h>
#include <limits.h>
#include <mutex>
-#include <netdb.h>
#include <pwd.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -32,11 +31,7 @@ bool HostInfoPosix::GetHostname(std::string &s) {
char hostname[PATH_MAX];
hostname[sizeof(hostname) - 1] = '\0';
if (::gethostname(hostname, sizeof(hostname) - 1) == 0) {
- struct hostent *h = ::gethostbyname(hostname);
- if (h)
- s.assign(h->h_name);
- else
- s.assign(hostname);
+ s.assign(hostname);
return true;
}
return false;
@@ -57,15 +52,19 @@ protected:
};
} // namespace
-llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {
+struct PasswdEntry {
+ std::string username;
+ std::string shell;
+};
+
+static llvm::Optional<PasswdEntry> GetPassword(id_t uid) {
#ifdef USE_GETPWUID
// getpwuid_r is missing from android-9
- // UserIDResolver provides some thread safety by making sure noone calls this
- // function concurrently, but using getpwuid is ultimately not thread-safe as
- // we don't know who else might be calling it.
- struct passwd *user_info_ptr = ::getpwuid(uid);
- if (user_info_ptr)
- return std::string(user_info_ptr->pw_name);
+ // The caller should provide some thread safety by making sure no one calls
+ // this function concurrently, because using getpwuid is ultimately not
+ // thread-safe as we don't know who else might be calling it.
+ if (auto *user_info_ptr = ::getpwuid(uid))
+ return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};
#else
struct passwd user_info;
struct passwd *user_info_ptr = &user_info;
@@ -74,12 +73,18 @@ llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {
if (::getpwuid_r(uid, &user_info, user_buffer, user_buffer_size,
&user_info_ptr) == 0 &&
user_info_ptr) {
- return std::string(user_info_ptr->pw_name);
+ return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};
}
#endif
return llvm::None;
}
+llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {
+ if (llvm::Optional<PasswdEntry> password = GetPassword(uid))
+ return password->username;
+ return llvm::None;
+}
+
llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {
#ifndef __ANDROID__
char group_buffer[PATH_MAX];
@@ -98,8 +103,6 @@ llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {
if (group_info_ptr)
return std::string(group_info_ptr->gr_name);
}
-#else
- assert(false && "getgrgid_r() not supported on Android");
#endif
return llvm::None;
}
@@ -118,7 +121,13 @@ uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); }
uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); }
-FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); }
+FileSpec HostInfoPosix::GetDefaultShell() {
+ if (const char *v = ::getenv("SHELL"))
+ return FileSpec(v);
+ if (llvm::Optional<PasswdEntry> password = GetPassword(::geteuid()))
+ return FileSpec(password->shell);
+ return FileSpec("/bin/sh");
+}
bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {
return ComputePathRelativeToLibrary(file_spec, "/bin");
diff --git a/source/Initialization/SystemInitializerCommon.cpp b/source/Initialization/SystemInitializerCommon.cpp
index 8558911c2f4c..7ae8ef5d4d66 100644
--- a/source/Initialization/SystemInitializerCommon.cpp
+++ b/source/Initialization/SystemInitializerCommon.cpp
@@ -25,6 +25,7 @@
#if defined(_WIN32)
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
#include "lldb/Host/windows/windows.h"
+#include <crtdbg.h>
#endif
#include "llvm/Support/TargetSelect.h"
@@ -77,6 +78,17 @@ llvm::Error SystemInitializerCommon::Initialize() {
} else {
FileSystem::Initialize();
}
+ if (llvm::Expected<std::string> cwd =
+ loader->LoadBuffer<WorkingDirectoryProvider>()) {
+ llvm::StringRef working_dir = llvm::StringRef(*cwd).rtrim();
+ if (std::error_code ec = FileSystem::Instance()
+ .GetVirtualFileSystem()
+ ->setCurrentWorkingDirectory(working_dir)) {
+ return llvm::errorCodeToError(ec);
+ }
+ } else {
+ return cwd.takeError();
+ }
} else if (repro::Generator *g = r.GetGenerator()) {
repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>();
vp.SetVersion(lldb_private::GetVersion());
diff --git a/source/Interpreter/CommandAlias.cpp b/source/Interpreter/CommandAlias.cpp
index 8c40574ee50e..5139c53a47b3 100644
--- a/source/Interpreter/CommandAlias.cpp
+++ b/source/Interpreter/CommandAlias.cpp
@@ -64,8 +64,8 @@ static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp,
option_arg_vector->emplace_back("<argument>", -1, options_string);
else {
for (auto &entry : args.entries()) {
- if (!entry.ref.empty())
- option_arg_vector->emplace_back("<argument>", -1, entry.ref);
+ if (!entry.ref().empty())
+ option_arg_vector->emplace_back("<argument>", -1, entry.ref());
}
}
}
@@ -115,18 +115,16 @@ bool CommandAlias::WantsCompletion() {
return false;
}
-int CommandAlias::HandleCompletion(CompletionRequest &request) {
+void CommandAlias::HandleCompletion(CompletionRequest &request) {
if (IsValid())
- return m_underlying_command_sp->HandleCompletion(request);
- return -1;
+ m_underlying_command_sp->HandleCompletion(request);
}
-int CommandAlias::HandleArgumentCompletion(
+void CommandAlias::HandleArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector) {
if (IsValid())
- return m_underlying_command_sp->HandleArgumentCompletion(
- request, opt_element_vector);
- return -1;
+ m_underlying_command_sp->HandleArgumentCompletion(request,
+ opt_element_vector);
}
Options *CommandAlias::GetOptions() {
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 8948037a6307..0c059096c6cd 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -16,7 +16,6 @@
#include "Commands/CommandObjectApropos.h"
#include "Commands/CommandObjectBreakpoint.h"
-#include "Commands/CommandObjectBugreport.h"
#include "Commands/CommandObjectCommands.h"
#include "Commands/CommandObjectDisassemble.h"
#include "Commands/CommandObjectExpression.h"
@@ -64,11 +63,14 @@
#include "lldb/Utility/Args.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Target/UnixSignals.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -77,10 +79,6 @@ using namespace lldb_private;
static const char *k_white_space = " \t\v";
-static constexpr bool NoGlobalSetting = true;
-static constexpr uintptr_t DefaultValueTrue = true;
-static constexpr uintptr_t DefaultValueFalse = false;
-static constexpr const char *NoCStrDefault = nullptr;
static constexpr const char *InitFileWarning =
"There is a .lldbinit file in the current directory which is not being "
"read.\n"
@@ -93,38 +91,12 @@ static constexpr const char *InitFileWarning =
"and\n"
"accept the security risk.";
-static constexpr PropertyDefinition g_properties[] = {
- {"expand-regex-aliases", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, regular expression alias commands will show the "
- "expanded command that will be executed. This can be used to "
- "debug new regular expression alias commands."},
- {"prompt-on-quit", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will prompt you before quitting if there are any live "
- "processes being debugged. If false, LLDB will quit without asking in any "
- "case."},
- {"stop-command-source-on-error", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will stop running a 'command source' "
- "script upon encountering an error."},
- {"space-repl-prompts", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, blank lines will be printed between between REPL submissions."},
- {"echo-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed before they are evaluated."},
- {"echo-comment-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed even if they are pure comment lines."}};
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterProperties.inc"
enum {
- ePropertyExpandRegexAliases = 0,
- ePropertyPromptOnQuit = 1,
- ePropertyStopCmdSourceOnError = 2,
- eSpaceReplPrompts = 3,
- eEchoCommands = 4,
- eEchoCommentCommands = 5
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterPropertiesEnum.inc"
};
ConstString &CommandInterpreter::GetStaticBroadcasterClass() {
@@ -139,7 +111,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
Properties(OptionValuePropertiesSP(
new OptionValueProperties(ConstString("interpreter")))),
IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
- m_debugger(debugger), m_synchronous_execution(synchronous_execution),
+ m_debugger(debugger), m_synchronous_execution(true),
m_skip_lldbinit_files(false), m_skip_app_init_files(false),
m_command_io_handler_sp(), m_comment_char('#'),
m_batch_command_mode(false), m_truncation_warning(eNoTruncation),
@@ -148,20 +120,21 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit");
SetEventName(eBroadcastBitResetPrompt, "reset-prompt");
SetEventName(eBroadcastBitQuitCommandReceived, "quit");
+ SetSynchronous(synchronous_execution);
CheckInWithManager();
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_interpreter_properties);
}
bool CommandInterpreter::GetExpandRegexAliases() const {
const uint32_t idx = ePropertyExpandRegexAliases;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetPromptOnQuit() const {
const uint32_t idx = ePropertyPromptOnQuit;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetPromptOnQuit(bool b) {
@@ -170,24 +143,24 @@ void CommandInterpreter::SetPromptOnQuit(bool b) {
}
bool CommandInterpreter::GetEchoCommands() const {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommands(bool b) {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
bool CommandInterpreter::GetEchoCommentCommands() const {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommentCommands(bool b) {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
@@ -223,13 +196,13 @@ void CommandInterpreter::ResolveCommand(const char *command_line,
bool CommandInterpreter::GetStopCmdSourceOnError() const {
const uint32_t idx = ePropertyStopCmdSourceOnError;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetSpaceReplPrompts() const {
- const uint32_t idx = eSpaceReplPrompts;
+ const uint32_t idx = ePropertySpaceReplPrompts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::Initialize() {
@@ -473,8 +446,6 @@ void CommandInterpreter::LoadCommandDictionary() {
m_command_dict["apropos"] = CommandObjectSP(new CommandObjectApropos(*this));
m_command_dict["breakpoint"] =
CommandObjectSP(new CommandObjectMultiwordBreakpoint(*this));
- m_command_dict["bugreport"] =
- CommandObjectSP(new CommandObjectMultiwordBugreport(*this));
m_command_dict["command"] =
CommandObjectSP(new CommandObjectMultiwordCommands(*this));
m_command_dict["disassemble"] =
@@ -1628,8 +1599,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")",
command_line);
- if (log)
- log->Printf("Processing command: %s", command_line);
+ LLDB_LOGF(log, "Processing command: %s", command_line);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Handling command: %s.", command_line);
@@ -1735,13 +1705,13 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
// "br s -n main", command_string is now "breakpoint set -n main".
if (log) {
llvm::StringRef command_name = cmd_obj ? cmd_obj->GetCommandName() : "<not found>";
- log->Printf("HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
- log->Printf("HandleCommand, (revised) command_string: '%s'",
- command_string.c_str());
+ LLDB_LOGF(log, "HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
+ LLDB_LOGF(log, "HandleCommand, (revised) command_string: '%s'",
+ command_string.c_str());
const bool wants_raw_input =
(cmd_obj != nullptr) ? cmd_obj->WantsRawCommandString() : false;
- log->Printf("HandleCommand, wants_raw_input:'%s'",
- wants_raw_input ? "True" : "False");
+ LLDB_LOGF(log, "HandleCommand, wants_raw_input:'%s'",
+ wants_raw_input ? "True" : "False");
}
// Phase 2.
@@ -1771,34 +1741,30 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
if (pos != 0 && pos != std::string::npos)
remainder.erase(0, pos);
- if (log)
- log->Printf(
- "HandleCommand, command line after removing command name(s): '%s'",
- remainder.c_str());
+ LLDB_LOGF(
+ log, "HandleCommand, command line after removing command name(s): '%s'",
+ remainder.c_str());
cmd_obj->Execute(remainder.c_str(), result);
}
- if (log)
- log->Printf("HandleCommand, command %s",
- (result.Succeeded() ? "succeeded" : "did not succeed"));
+ LLDB_LOGF(log, "HandleCommand, command %s",
+ (result.Succeeded() ? "succeeded" : "did not succeed"));
return result.Succeeded();
}
-int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
- int num_command_matches = 0;
+void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
bool look_for_subcommand = false;
// For any of the command completions a unique match will be a complete word.
- request.SetWordComplete(true);
- if (request.GetCursorIndex() == -1) {
+ if (request.GetParsedLine().GetArgumentCount() == 0) {
// We got nothing on the command line, so return the list of commands
bool include_aliases = true;
StringList new_matches, descriptions;
- num_command_matches = GetCommandNamesMatchingPartialString(
- "", include_aliases, new_matches, descriptions);
+ GetCommandNamesMatchingPartialString("", include_aliases, new_matches,
+ descriptions);
request.AddCompletions(new_matches, descriptions);
} else if (request.GetCursorIndex() == 0) {
// The cursor is in the first argument, so just do a lookup in the
@@ -1808,24 +1774,18 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0),
&new_matches, &new_descriptions);
- if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() &&
+ if (new_matches.GetSize() && cmd_obj && cmd_obj->IsMultiwordObject() &&
new_matches.GetStringAtIndex(0) != nullptr &&
strcmp(request.GetParsedLine().GetArgumentAtIndex(0),
new_matches.GetStringAtIndex(0)) == 0) {
- if (request.GetParsedLine().GetArgumentCount() == 1) {
- request.SetWordComplete(true);
- } else {
+ if (request.GetParsedLine().GetArgumentCount() != 1) {
look_for_subcommand = true;
- num_command_matches = 0;
new_matches.DeleteStringAtIndex(0);
new_descriptions.DeleteStringAtIndex(0);
- request.GetParsedLine().AppendArgument(llvm::StringRef());
- request.SetCursorIndex(request.GetCursorIndex() + 1);
- request.SetCursorCharPosition(0);
+ request.AppendEmptyArgument();
}
}
request.AddCompletions(new_matches, new_descriptions);
- num_command_matches = request.GetNumberOfMatches();
}
if (request.GetCursorIndex() > 0 || look_for_subcommand) {
@@ -1834,81 +1794,31 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
// matching initial command:
CommandObject *command_object =
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0));
- if (command_object == nullptr) {
- return 0;
- } else {
- request.GetParsedLine().Shift();
- request.SetCursorIndex(request.GetCursorIndex() - 1);
- num_command_matches = command_object->HandleCompletion(request);
+ if (command_object) {
+ request.ShiftArguments();
+ command_object->HandleCompletion(request);
}
}
-
- return num_command_matches;
}
-int CommandInterpreter::HandleCompletion(
- const char *current_line, const char *cursor, const char *last_char,
- int match_start_point, int max_return_elements, StringList &matches,
- StringList &descriptions) {
+void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
- llvm::StringRef command_line(current_line, last_char - current_line);
- CompletionResult result;
- CompletionRequest request(command_line, cursor - current_line,
- match_start_point, max_return_elements, result);
// Don't complete comments, and if the line we are completing is just the
// history repeat character, substitute the appropriate history line.
- const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (first_arg) {
- if (first_arg[0] == m_comment_char)
- return 0;
- else if (first_arg[0] == CommandHistory::g_repeat_char) {
- if (auto hist_str = m_command_history.FindString(first_arg)) {
- matches.InsertStringAtIndex(0, *hist_str);
- descriptions.InsertStringAtIndex(0, "Previous command history event");
- return -2;
- } else
- return 0;
- }
- }
-
- // Only max_return_elements == -1 is supported at present:
- lldbassert(max_return_elements == -1);
-
- int num_command_matches = HandleCompletionMatches(request);
- result.GetMatches(matches);
- result.GetDescriptions(descriptions);
+ llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (num_command_matches <= 0)
- return num_command_matches;
-
- if (request.GetParsedLine().GetArgumentCount() == 0) {
- // If we got an empty string, insert nothing.
- matches.InsertStringAtIndex(0, "");
- descriptions.InsertStringAtIndex(0, "");
- } else {
- // Now figure out if there is a common substring, and if so put that in
- // element 0, otherwise put an empty string in element 0.
- std::string command_partial_str = request.GetCursorArgumentPrefix().str();
-
- std::string common_prefix;
- matches.LongestCommonPrefix(common_prefix);
- const size_t partial_name_len = command_partial_str.size();
- common_prefix.erase(0, partial_name_len);
-
- // If we matched a unique single command, add a space... Only do this if
- // the completer told us this was a complete word, however...
- if (num_command_matches == 1 && request.GetWordComplete()) {
- char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote;
- common_prefix =
- Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
- if (quote_char != '\0')
- common_prefix.push_back(quote_char);
- common_prefix.push_back(' ');
+ if (!first_arg.empty()) {
+ if (first_arg.front() == m_comment_char)
+ return;
+ if (first_arg.front() == CommandHistory::g_repeat_char) {
+ if (auto hist_str = m_command_history.FindString(first_arg))
+ request.AddCompletion(*hist_str, "Previous command history event",
+ CompletionMode::RewriteLine);
+ return;
}
- matches.InsertStringAtIndex(0, common_prefix.c_str());
- descriptions.InsertStringAtIndex(0, "");
}
- return num_command_matches;
+
+ HandleCompletionMatches(request);
}
CommandInterpreter::~CommandInterpreter() {}
@@ -2051,7 +1961,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
for (auto entry : llvm::enumerate(cmd_args.entries())) {
if (!used[entry.index()] && !wants_raw_input)
- new_args.AppendArgument(entry.value().ref);
+ new_args.AppendArgument(entry.value().ref());
}
cmd_args.Clear();
@@ -2231,6 +2141,45 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) {
return platform_sp;
}
+bool CommandInterpreter::DidProcessStopAbnormally() const {
+ TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget();
+ if (!target_sp)
+ return false;
+
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ if (eStateStopped != process_sp->GetState())
+ return false;
+
+ for (const auto &thread_sp : process_sp->GetThreadList().Threads()) {
+ StopInfoSP stop_info = thread_sp->GetStopInfo();
+ if (!stop_info)
+ return false;
+
+ const StopReason reason = stop_info->GetStopReason();
+ if (reason == eStopReasonException || reason == eStopReasonInstrumentation)
+ return true;
+
+ if (reason == eStopReasonSignal) {
+ const auto stop_signal = static_cast<int32_t>(stop_info->GetValue());
+ UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
+ if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
+ // The signal is unknown, treat it as abnormal.
+ return true;
+
+ const auto sigint_num = signals_sp->GetSignalNumberFromName("SIGINT");
+ const auto sigstop_num = signals_sp->GetSignalNumberFromName("SIGSTOP");
+ if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
+ // The signal very likely implies a crash.
+ return true;
+ }
+ }
+
+ return false;
+}
+
void CommandInterpreter::HandleCommands(const StringList &commands,
ExecutionContext *override_context,
CommandInterpreterRunOptions &options,
@@ -2341,38 +2290,22 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
}
// Also check for "stop on crash here:
- bool should_stop = false;
- if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) {
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if (reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- if (idx != num_lines - 1)
- result.AppendErrorWithFormat(
- "Aborting reading of commands after command #%" PRIu64
- ": '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
- else
- result.AppendMessageWithFormat(
- "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
+ if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash() &&
+ DidProcessStopAbnormally()) {
+ if (idx != num_lines - 1)
+ result.AppendErrorWithFormat(
+ "Aborting reading of commands after command #%" PRIu64
+ ": '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
+ else
+ result.AppendMessageWithFormat(
+ "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
- result.SetStatus(tmp_result.GetStatus());
- m_debugger.SetAsyncExecution(old_async_execution);
+ result.SetStatus(tmp_result.GetStatus());
+ m_debugger.SetAsyncExecution(old_async_execution);
- return;
- }
+ return;
}
}
@@ -2405,18 +2338,18 @@ void CommandInterpreter::HandleCommandsFromFile(
return;
}
- StreamFileSP input_file_sp(new StreamFile());
std::string cmd_file_path = cmd_file.GetPath();
- Status error = FileSystem::Instance().Open(input_file_sp->GetFile(), cmd_file,
- File::eOpenOptionRead);
-
- if (error.Fail()) {
- result.AppendErrorWithFormat(
- "error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(),
- error.AsCString());
+ auto input_file_up =
+ FileSystem::Instance().Open(cmd_file, File::eOpenOptionRead);
+ if (!input_file_up) {
+ std::string error = llvm::toString(input_file_up.takeError());
+ result.AppendErrorWithFormatv(
+ "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
+ llvm::fmt_consume(input_file_up.takeError()));
result.SetStatus(eReturnStatusFailed);
return;
}
+ FileSP input_file_sp = FileSP(std::move(input_file_up.get()));
Debugger &debugger = GetDebugger();
@@ -2502,8 +2435,8 @@ void CommandInterpreter::HandleCommandsFromFile(
}
if (flags & eHandleCommandFlagPrintResult) {
- debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n",
- cmd_file_path.c_str());
+ debugger.GetOutputFile().Printf("Executing commands in '%s'.\n",
+ cmd_file_path.c_str());
}
// Used for inheriting the right settings when "command source" might
@@ -2541,6 +2474,9 @@ void CommandInterpreter::HandleCommandsFromFile(
bool CommandInterpreter::GetSynchronous() { return m_synchronous_execution; }
void CommandInterpreter::SetSynchronous(bool value) {
+ // Asynchronous mode is not supported during reproducer replay.
+ if (repro::Reproducer::Instance().GetLoader())
+ return;
m_synchronous_execution = value;
}
@@ -2701,32 +2637,14 @@ void CommandInterpreter::UpdateExecutionContext(
}
}
-size_t CommandInterpreter::GetProcessOutput() {
- // The process has stuff waiting for stderr; get it and write it out to the
- // appropriate place.
- char stdio_buffer[1024];
- size_t len;
- size_t total_bytes = 0;
- Status error;
+void CommandInterpreter::GetProcessOutput() {
TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- while ((len = process_sp->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetOutputFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- while ((len = process_sp->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetErrorFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- }
- }
- return total_bytes;
+ if (!target_sp)
+ return;
+
+ if (ProcessSP process_sp = target_sp->GetProcessSP())
+ m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true,
+ /*flush_stderr*/ true);
}
void CommandInterpreter::StartHandlingCommand() {
@@ -2818,8 +2736,8 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// from a file) we need to echo the command out so we don't just see the
// command output and no command...
if (EchoCommandNonInteractive(line, io_handler.GetFlags()))
- io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(),
- line.c_str());
+ io_handler.GetOutputStreamFileSP()->Printf(
+ "%s%s\n", io_handler.GetPrompt(), line.c_str());
}
StartHandlingCommand();
@@ -2836,13 +2754,13 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
if (!result.GetImmediateOutputStream()) {
llvm::StringRef output = result.GetOutputData();
- PrintCommandOutput(*io_handler.GetOutputStreamFile(), output);
+ PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output);
}
// Now emit the command error text from the command we just executed
if (!result.GetImmediateErrorStream()) {
llvm::StringRef error = result.GetErrorData();
- PrintCommandOutput(*io_handler.GetErrorStreamFile(), error);
+ PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error);
}
}
@@ -2875,27 +2793,10 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// Finally, if we're going to stop on crash, check that here:
if (!m_quit_requested && result.GetDidChangeProcessState() &&
- io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) {
- bool should_stop = false;
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if ((reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) &&
- !result.GetAbnormalStopWasExpected()) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- io_handler.SetIsDone(true);
- m_stopped_for_crash = true;
- }
+ io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash) &&
+ DidProcessStopAbnormally()) {
+ io_handler.SetIsDone(true);
+ m_stopped_for_crash = true;
}
}
@@ -3009,8 +2910,8 @@ CommandInterpreter::GetIOHandler(bool force_create,
m_command_io_handler_sp = std::make_shared<IOHandlerEditline>(
m_debugger, IOHandler::Type::CommandInterpreter,
- m_debugger.GetInputFile(), m_debugger.GetOutputFile(),
- m_debugger.GetErrorFile(), flags, "lldb", m_debugger.GetPrompt(),
+ m_debugger.GetInputFileSP(), m_debugger.GetOutputStreamSP(),
+ m_debugger.GetErrorStreamSP(), flags, "lldb", m_debugger.GetPrompt(),
llvm::StringRef(), // Continuation prompt
false, // Don't enable multiple line input, just single line commands
m_debugger.GetUseColor(),
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 8e493c7a326f..d666852ee68c 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -257,14 +257,14 @@ void CommandObject::Cleanup() {
m_api_locker.unlock();
}
-int CommandObject::HandleCompletion(CompletionRequest &request) {
+void CommandObject::HandleCompletion(CompletionRequest &request) {
// Default implementation of WantsCompletion() is !WantsRawCommandString().
// Subclasses who want raw command string but desire, for example, argument
// completion should override WantsCompletion() to return true, instead.
if (WantsRawCommandString() && !WantsCompletion()) {
// FIXME: Abstract telling the completion to insert the completion
// character.
- return -1;
+ return;
} else {
// Can we do anything generic with the options?
Options *cur_options = GetOptions();
@@ -278,11 +278,11 @@ int CommandObject::HandleCompletion(CompletionRequest &request) {
bool handled_by_options = cur_options->HandleOptionCompletion(
request, opt_element_vector, GetCommandInterpreter());
if (handled_by_options)
- return request.GetNumberOfMatches();
+ return;
}
// If we got here, the last word is not an option or an option argument.
- return HandleArgumentCompletion(request, opt_element_vector);
+ HandleArgumentCompletion(request, opt_element_vector);
}
}
@@ -917,12 +917,21 @@ const char *CommandObject::GetArgumentDescriptionAsCString(
return g_arguments_data[arg_type].help_text;
}
-Target *CommandObject::GetDummyTarget() {
- return m_interpreter.GetDebugger().GetDummyTarget();
+Target &CommandObject::GetDummyTarget() {
+ return *m_interpreter.GetDebugger().GetDummyTarget();
+}
+
+Target &CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ return *m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
}
-Target *CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
- return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
+Target &CommandObject::GetSelectedTarget() {
+ assert(m_flags.AnySet(eCommandRequiresTarget | eCommandProcessMustBePaused |
+ eCommandProcessMustBeLaunched | eCommandRequiresFrame |
+ eCommandRequiresThread | eCommandRequiresProcess |
+ eCommandRequiresRegContext) &&
+ "GetSelectedTarget called from object that may have no target");
+ return *m_interpreter.GetDebugger().GetSelectedTarget();
}
Thread *CommandObject::GetDefaultThread() {
@@ -958,7 +967,7 @@ bool CommandObjectParsed::Execute(const char *args_string,
}
if (!handled) {
for (auto entry : llvm::enumerate(cmd_args.entries())) {
- if (!entry.value().ref.empty() && entry.value().ref.front() == '`') {
+ if (!entry.value().ref().empty() && entry.value().ref().front() == '`') {
cmd_args.ReplaceArgumentAtIndex(
entry.index(),
m_interpreter.ProcessEmbeddedScriptCommands(entry.value().c_str()));
@@ -1064,7 +1073,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
{ eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." },
{ eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr },
- { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." },
+ { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A POSIX-compliant extended regular expression." },
{ eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." },
{ eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp
index 19335b95ca3a..693d18ce7bdf 100644
--- a/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -30,15 +30,14 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
CommandReturnObject &result) {
EntryCollection::const_iterator pos, end = m_entries.end();
for (pos = m_entries.begin(); pos != end; ++pos) {
- RegularExpression::Match regex_match(m_max_matches);
-
- if (pos->regex.Execute(command, &regex_match)) {
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (pos->regex.Execute(command, &matches)) {
std::string new_command(pos->command);
- std::string match_str;
char percent_var[8];
size_t idx, percent_var_idx;
for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
- if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
+ if (match_idx < matches.size()) {
+ const std::string match_str = matches[match_idx].str();
const int percent_var_len =
::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
for (idx = 0; (percent_var_idx = new_command.find(
@@ -74,8 +73,9 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
const char *command_cstr) {
m_entries.resize(m_entries.size() + 1);
// Only add the regular expression if it compiles
- if (m_entries.back().regex.Compile(
- llvm::StringRef::withNullAsEmpty(re_cstr))) {
+ m_entries.back().regex =
+ RegularExpression(llvm::StringRef::withNullAsEmpty(re_cstr));
+ if (m_entries.back().regex.IsValid()) {
m_entries.back().command.assign(command_cstr);
return true;
}
@@ -84,13 +84,9 @@ bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
return false;
}
-int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
+void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
if (m_completion_type_mask) {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
- return request.GetNumberOfMatches();
- } else {
- request.SetWordComplete(false);
}
- return 0;
}
diff --git a/source/Interpreter/CommandReturnObject.cpp b/source/Interpreter/CommandReturnObject.cpp
index 3a7a8755d975..c17390be7311 100644
--- a/source/Interpreter/CommandReturnObject.cpp
+++ b/source/Interpreter/CommandReturnObject.cpp
@@ -33,8 +33,7 @@ static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s,
CommandReturnObject::CommandReturnObject()
: m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted),
- m_did_change_process_state(false), m_interactive(true),
- m_abnormal_stop_was_expected(false) {}
+ m_did_change_process_state(false), m_interactive(true) {}
CommandReturnObject::~CommandReturnObject() {}
diff --git a/source/Interpreter/InterpreterProperties.td b/source/Interpreter/InterpreterProperties.td
new file mode 100644
index 000000000000..600c1e3edb9b
--- /dev/null
+++ b/source/Interpreter/InterpreterProperties.td
@@ -0,0 +1,28 @@
+include "../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "interpreter" in {
+ def ExpandRegexAliases: Property<"expand-regex-aliases", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands.">;
+ def PromptOnQuit: Property<"prompt-on-quit", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case.">;
+ def StopCmdSourceOnError: Property<"stop-command-source-on-error", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, LLDB will stop running a 'command source' script upon encountering an error.">;
+ def SpaceReplPrompts: Property<"space-repl-prompts", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, blank lines will be printed between between REPL submissions.">;
+ def EchoCommands: Property<"echo-commands", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, commands will be echoed before they are evaluated.">;
+ def EchoCommentCommands: Property<"echo-comment-commands", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, commands will be echoed even if they are pure comment lines.">;
+}
diff --git a/source/Interpreter/OptionArgParser.cpp b/source/Interpreter/OptionArgParser.cpp
index efaac0720fd0..14b81cd7b3d2 100644
--- a/source/Interpreter/OptionArgParser.cpp
+++ b/source/Interpreter/OptionArgParser.cpp
@@ -211,29 +211,21 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx,
// pointer types.
static RegularExpression g_symbol_plus_offset_regex(
"^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
- RegularExpression::Match regex_match(3);
- if (g_symbol_plus_offset_regex.Execute(sref, &regex_match)) {
+
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (g_symbol_plus_offset_regex.Execute(sref, &matches)) {
uint64_t offset = 0;
- bool add = true;
- std::string name;
- std::string str;
- if (regex_match.GetMatchAtIndex(s, 1, name)) {
- if (regex_match.GetMatchAtIndex(s, 2, str)) {
- add = str[0] == '+';
-
- if (regex_match.GetMatchAtIndex(s, 3, str)) {
- if (!llvm::StringRef(str).getAsInteger(0, offset)) {
- Status error;
- addr = ToAddress(exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS,
- &error);
- if (addr != LLDB_INVALID_ADDRESS) {
- if (add)
- return addr + offset;
- else
- return addr - offset;
- }
- }
- }
+ std::string name = matches[1].str();
+ std::string sign = matches[2].str();
+ std::string str_offset = matches[3].str();
+ if (!llvm::StringRef(str_offset).getAsInteger(0, offset)) {
+ Status error;
+ addr = ToAddress(exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
+ if (addr != LLDB_INVALID_ADDRESS) {
+ if (sign[0] == '+')
+ return addr + offset;
+ else
+ return addr - offset;
}
}
}
diff --git a/source/Interpreter/OptionGroupArchitecture.cpp b/source/Interpreter/OptionGroupArchitecture.cpp
index 2ee1a9c7cf84..11f786c52c09 100644
--- a/source/Interpreter/OptionGroupArchitecture.cpp
+++ b/source/Interpreter/OptionGroupArchitecture.cpp
@@ -46,8 +46,7 @@ OptionGroupArchitecture::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index d9acfd663dd1..c25e35f84517 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -160,8 +160,7 @@ Status OptionGroupFormat::SetOptionValue(uint32_t option_idx,
} break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupOutputFile.cpp b/source/Interpreter/OptionGroupOutputFile.cpp
index ccb99a8fce4a..3df75cf86b85 100644
--- a/source/Interpreter/OptionGroupOutputFile.cpp
+++ b/source/Interpreter/OptionGroupOutputFile.cpp
@@ -50,8 +50,7 @@ OptionGroupOutputFile::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 6dc2996bb78a..6ddbbf0e3abb 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -113,8 +113,7 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
}
diff --git a/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/source/Interpreter/OptionGroupPythonClassWithDict.cpp
new file mode 100644
index 000000000000..9a893ec53625
--- /dev/null
+++ b/source/Interpreter/OptionGroupPythonClassWithDict.cpp
@@ -0,0 +1,123 @@
+//===-- OptionGroupPythonClassWithDict.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/Interpreter/OptionGroupPythonClassWithDict.h"
+
+#include "lldb/Host/OptionParser.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
+ (const char *class_use,
+ int class_option,
+ int key_option,
+ int value_option,
+ const char *class_long_option,
+ const char *key_long_option,
+ const char *value_long_option,
+ bool required) {
+ m_key_usage_text.assign("The key for a key/value pair passed to the class"
+ " that implements a ");
+ m_key_usage_text.append(class_use);
+ m_key_usage_text.append(". Pairs can be specified more than once.");
+
+ m_value_usage_text.assign("The value for a previous key in the pair passed to"
+ " the class that implements a ");
+ m_value_usage_text.append(class_use);
+ m_value_usage_text.append(". Pairs can be specified more than once.");
+
+ m_class_usage_text.assign("The name of the class that will manage a ");
+ m_class_usage_text.append(class_use);
+ m_class_usage_text.append(".");
+
+ m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[0].required = required;
+ m_option_definition[0].long_option = class_long_option;
+ m_option_definition[0].short_option = class_option;
+ m_option_definition[0].validator = nullptr;
+ m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[0].enum_values = {};
+ m_option_definition[0].completion_type = 0;
+ m_option_definition[0].argument_type = eArgTypePythonClass;
+ m_option_definition[0].usage_text = m_class_usage_text.data();
+
+ m_option_definition[1].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[1].required = required;
+ m_option_definition[1].long_option = key_long_option;
+ m_option_definition[1].short_option = key_option;
+ m_option_definition[1].validator = nullptr;
+ m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[1].enum_values = {};
+ m_option_definition[1].completion_type = 0;
+ m_option_definition[1].argument_type = eArgTypeNone;
+ m_option_definition[1].usage_text = m_key_usage_text.data();
+
+ m_option_definition[2].usage_mask = LLDB_OPT_SET_1;
+ m_option_definition[2].required = required;
+ m_option_definition[2].long_option = value_long_option;
+ m_option_definition[2].short_option = value_option;
+ m_option_definition[2].validator = nullptr;
+ m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
+ m_option_definition[2].enum_values = {};
+ m_option_definition[2].completion_type = 0;
+ m_option_definition[2].argument_type = eArgTypeNone;
+ m_option_definition[2].usage_text = m_value_usage_text.data();
+}
+
+OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
+
+Status OptionGroupPythonClassWithDict::SetOptionValue(
+ uint32_t option_idx,
+ llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ switch (option_idx) {
+ case 0: {
+ m_class_name.assign(option_arg);
+ } break;
+ case 1: {
+ if (m_current_key.empty())
+ m_current_key.assign(option_arg);
+ else
+ error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
+ m_current_key.c_str());
+
+ } break;
+ case 2: {
+ if (!m_current_key.empty()) {
+ m_dict_sp->AddStringItem(m_current_key, option_arg);
+ m_current_key.clear();
+ }
+ else
+ error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
+ option_arg.str().c_str());
+ } break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+}
+
+void OptionGroupPythonClassWithDict::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ m_current_key.erase();
+ m_dict_sp = std::make_shared<StructuredData::Dictionary>();
+}
+
+Status OptionGroupPythonClassWithDict::OptionParsingFinished(
+ ExecutionContext *execution_context) {
+ Status error;
+ // If we get here and there's contents in the m_current_key, somebody must
+ // have provided a key but no value.
+ if (!m_current_key.empty())
+ error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
+ m_current_key.c_str());
+ return error;
+}
+
diff --git a/source/Interpreter/OptionGroupUUID.cpp b/source/Interpreter/OptionGroupUUID.cpp
index e32673bc52af..8fc330a89391 100644
--- a/source/Interpreter/OptionGroupUUID.cpp
+++ b/source/Interpreter/OptionGroupUUID.cpp
@@ -40,8 +40,7 @@ Status OptionGroupUUID::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 4e5463a4de00..81c10a6c762e 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -152,8 +152,7 @@ Status OptionGroupValueObjectDisplay::SetOptionValue(
break;
default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index d703c3dedcd9..a9004bf03cd2 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -109,9 +109,7 @@ OptionGroupVariable::SetOptionValue(uint32_t option_idx,
error = summary_string.SetCurrentValue(option_arg);
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionGroupWatchpoint.cpp b/source/Interpreter/OptionGroupWatchpoint.cpp
index 28e6b817fcc5..682f99b8c5cc 100644
--- a/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -16,16 +16,45 @@ using namespace lldb;
using namespace lldb_private;
static constexpr OptionEnumValueElement g_watch_type[] = {
- {OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"},
- {OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"},
- {OptionGroupWatchpoint::eWatchReadWrite, "read_write",
- "Watch for read/write"} };
+ {
+ OptionGroupWatchpoint::eWatchRead,
+ "read",
+ "Watch for read",
+ },
+ {
+ OptionGroupWatchpoint::eWatchWrite,
+ "write",
+ "Watch for write",
+ },
+ {
+ OptionGroupWatchpoint::eWatchReadWrite,
+ "read_write",
+ "Watch for read/write",
+ },
+};
static constexpr OptionEnumValueElement g_watch_size[] = {
- {1, "1", "Watch for byte size of 1"},
- {2, "2", "Watch for byte size of 2"},
- {4, "4", "Watch for byte size of 4"},
- {8, "8", "Watch for byte size of 8"} };
+ {
+ 1,
+ "1",
+ "Watch for byte size of 1",
+ },
+ {
+ 2,
+ "2",
+ "Watch for byte size of 2",
+ },
+ {
+ 4,
+ "4",
+ "Watch for byte size of 4",
+ },
+ {
+ 8,
+ "8",
+ "Watch for byte size of 8",
+ },
+};
static constexpr OptionDefinition g_option_table[] = {
{LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument,
@@ -72,9 +101,7 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
break;
default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'",
- short_option);
- break;
+ llvm_unreachable("Unimplemented option");
}
return error;
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
index 00c8642595b7..bc929aa9dabf 100644
--- a/source/Interpreter/OptionValue.cpp
+++ b/source/Interpreter/OptionValue.cpp
@@ -565,11 +565,8 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const {
return dumped_something;
}
-size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
- return request.GetNumberOfMatches();
-}
+void OptionValue::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {}
Status OptionValue::SetValueFromString(llvm::StringRef value,
VarSetOperationType op) {
diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp
index 92dc45d092be..7271c1471f90 100644
--- a/source/Interpreter/OptionValueArch.cpp
+++ b/source/Interpreter/OptionValueArch.cpp
@@ -68,11 +68,9 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const {
return OptionValueSP(new OptionValueArch(*this));
}
-size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, CommandCompletions::eArchitectureCompletion, request,
nullptr);
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp
index 8be8220fb306..6f893a94e863 100644
--- a/source/Interpreter/OptionValueBoolean.cpp
+++ b/source/Interpreter/OptionValueBoolean.cpp
@@ -71,21 +71,17 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
return OptionValueSP(new OptionValueBoolean(*this));
}
-size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
- static const llvm::StringRef g_autocomplete_entries[] = {
- "true", "false", "on", "off", "yes", "no", "1", "0"};
+void OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ llvm::StringRef autocomplete_entries[] = {"true", "false", "on", "off",
+ "yes", "no", "1", "0"};
- auto entries = llvm::makeArrayRef(g_autocomplete_entries);
+ auto entries = llvm::makeArrayRef(autocomplete_entries);
// only suggest "true" or "false" by default
if (request.GetCursorArgumentPrefix().empty())
entries = entries.take_front(2);
- for (auto entry : entries) {
- if (entry.startswith_lower(request.GetCursorArgumentPrefix()))
- request.AddCompletion(entry);
- }
- return request.GetNumberOfMatches();
+ for (auto entry : entries)
+ request.TryCompleteCurrentArg(entry);
}
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
index eb66c485bfd1..a4022288fccb 100644
--- a/source/Interpreter/OptionValueDictionary.cpp
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -111,18 +111,18 @@ Status OptionValueDictionary::SetArgs(const Args &args,
return error;
}
for (const auto &entry : args) {
- if (entry.ref.empty()) {
+ if (entry.ref().empty()) {
error.SetErrorString("empty argument");
return error;
}
- if (!entry.ref.contains('=')) {
+ if (!entry.ref().contains('=')) {
error.SetErrorString(
"assign operation takes one or more key=value arguments");
return error;
}
llvm::StringRef key, value;
- std::tie(key, value) = entry.ref.split('=');
+ std::tie(key, value) = entry.ref().split('=');
bool key_valid = false;
if (key.empty()) {
error.SetErrorString("empty dictionary key");
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
index 0b76bd0601aa..26933aa78240 100644
--- a/source/Interpreter/OptionValueEnumeration.cpp
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -102,21 +102,16 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
return OptionValueSP(new OptionValueEnumeration(*this));
}
-size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
-
+void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
const uint32_t num_enumerators = m_enumerations.GetSize();
if (!request.GetCursorArgumentPrefix().empty()) {
for (size_t i = 0; i < num_enumerators; ++i) {
llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
- if (name.startswith(request.GetCursorArgumentPrefix()))
- request.AddCompletion(name);
+ request.TryCompleteCurrentArg(name);
}
- } else {
- // only suggest "true" or "false" by default
+ return;
+ }
for (size_t i = 0; i < num_enumerators; ++i)
request.AddCompletion(m_enumerations.GetCStringAtIndex(i).GetStringRef());
- }
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp
index 062d7ccdf2aa..20d3d4e68e33 100644
--- a/source/Interpreter/OptionValueFileSpec.cpp
+++ b/source/Interpreter/OptionValueFileSpec.cpp
@@ -99,12 +99,10 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
return OptionValueSP(new OptionValueFileSpec(*this));
}
-size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, m_completion_mask, request, nullptr);
- return request.GetNumberOfMatches();
}
const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecList.cpp
index a95188870f0b..1a9d3c9ecb87 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecList.cpp
@@ -1,4 +1,4 @@
-//===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===//
+//===-- OptionValueFileSpecList.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/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp
index 1bb8c9f6955a..8dc52650a331 100644
--- a/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/source/Interpreter/OptionValueFormatEntity.cpp
@@ -116,7 +116,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
return OptionValueSP(new OptionValueFormatEntity(*this));
}
-size_t OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- return FormatEntity::AutoComplete(request);
+void OptionValueFormatEntity::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ FormatEntity::AutoComplete(request);
}
diff --git a/source/Interpreter/OptionValueLanguage.cpp b/source/Interpreter/OptionValueLanguage.cpp
index d935d5e23496..1d7e18868b6f 100644
--- a/source/Interpreter/OptionValueLanguage.cpp
+++ b/source/Interpreter/OptionValueLanguage.cpp
@@ -10,6 +10,7 @@
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Target/Language.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Stream.h"
@@ -39,23 +40,20 @@ Status OptionValueLanguage::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign: {
ConstString lang_name(value.trim());
- std::set<lldb::LanguageType> languages_for_types;
- std::set<lldb::LanguageType> languages_for_expressions;
- Language::GetLanguagesSupportingTypeSystems(languages_for_types,
- languages_for_expressions);
-
+ LanguageSet languages_for_types = Language::GetLanguagesSupportingTypeSystems();
LanguageType new_type =
Language::GetLanguageTypeFromString(lang_name.GetStringRef());
- if (new_type && languages_for_types.count(new_type)) {
+ if (new_type && languages_for_types[new_type]) {
m_value_was_set = true;
m_current_value = new_type;
} else {
StreamString error_strm;
error_strm.Printf("invalid language type '%s', ", value.str().c_str());
error_strm.Printf("valid values are:\n");
- for (lldb::LanguageType language : languages_for_types) {
- error_strm.Printf("%s%s%s", " ",
- Language::GetNameForLanguageType(language), "\n");
+ for (int bit : languages_for_types.bitvector.set_bits()) {
+ auto language = (LanguageType)bit;
+ error_strm.Printf(" %s\n",
+ Language::GetNameForLanguageType(language));
}
error.SetErrorString(error_strm.GetString());
}
diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp
index bbe3fa715019..cf806fb550f9 100644
--- a/source/Interpreter/OptionValueRegex.cpp
+++ b/source/Interpreter/OptionValueRegex.cpp
@@ -46,16 +46,14 @@ Status OptionValueRegex::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (m_regex.Compile(value)) {
+ m_regex = RegularExpression(value);
+ if (m_regex.IsValid()) {
m_value_was_set = true;
NotifyValueChanged();
+ } else if (llvm::Error err = m_regex.GetError()) {
+ error.SetErrorString(llvm::toString(std::move(err)));
} else {
- char regex_error[1024];
- if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
- error.SetErrorString(regex_error);
- else
- error.SetErrorStringWithFormat("regex error %u",
- m_regex.GetErrorCode());
+ error.SetErrorString("regex error");
}
break;
}
diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp
index f39b66b77bb0..7a6bc65b25a4 100644
--- a/source/Interpreter/OptionValueUUID.cpp
+++ b/source/Interpreter/OptionValueUUID.cpp
@@ -62,30 +62,24 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const {
return OptionValueSP(new OptionValueUUID(*this));
}
-size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
- CompletionRequest &request) {
- request.SetWordComplete(false);
+void OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
ExecutionContext exe_ctx(interpreter.GetExecutionContext());
Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- auto prefix = request.GetCursorArgumentPrefix();
- llvm::SmallVector<uint8_t, 20> uuid_bytes;
- if (UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty()) {
- const size_t num_modules = target->GetImages().GetSize();
- for (size_t i = 0; i < num_modules; ++i) {
- ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
- if (module_sp) {
- const UUID &module_uuid = module_sp->GetUUID();
- if (module_uuid.IsValid()) {
- llvm::ArrayRef<uint8_t> module_bytes = module_uuid.GetBytes();
- if (module_bytes.size() >= uuid_bytes.size() &&
- module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) {
- request.AddCompletion(module_uuid.GetAsString());
- }
- }
- }
- }
- }
+ if (!target)
+ return;
+ auto prefix = request.GetCursorArgumentPrefix();
+ llvm::SmallVector<uint8_t, 20> uuid_bytes;
+ if (!UUID::DecodeUUIDBytesFromString(prefix, uuid_bytes).empty())
+ return;
+ const size_t num_modules = target->GetImages().GetSize();
+ for (size_t i = 0; i < num_modules; ++i) {
+ ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
+ if (!module_sp)
+ continue;
+ const UUID &module_uuid = module_sp->GetUUID();
+ if (!module_uuid.IsValid())
+ continue;
+ request.TryCompleteCurrentArg(module_uuid.GetAsString());
}
- return request.GetNumberOfMatches();
}
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index ba15c020f2da..0bceea14269d 100644
--- a/source/Interpreter/Options.cpp
+++ b/source/Interpreter/Options.cpp
@@ -645,8 +645,6 @@ bool Options::VerifyPartialOptions(CommandReturnObject &result) {
bool Options::HandleOptionCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector,
CommandInterpreter &interpreter) {
- request.SetWordComplete(true);
-
// For now we just scan the completions to see if the cursor position is in
// an option or its argument. Otherwise we'll call HandleArgumentCompletion.
// In the future we can use completion to validate options as well if we
@@ -654,12 +652,11 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
auto opt_defs = GetDefinitions();
- std::string cur_opt_std_str = request.GetCursorArgumentPrefix().str();
- const char *cur_opt_str = cur_opt_std_str.c_str();
+ llvm::StringRef cur_opt_str = request.GetCursorArgumentPrefix();
for (size_t i = 0; i < opt_element_vector.size(); i++) {
- int opt_pos = opt_element_vector[i].opt_pos;
- int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
+ size_t opt_pos = static_cast<size_t>(opt_element_vector[i].opt_pos);
+ size_t opt_arg_pos = static_cast<size_t>(opt_element_vector[i].opt_arg_pos);
int opt_defs_index = opt_element_vector[i].opt_defs_index;
if (opt_pos == request.GetCursorIndex()) {
// We're completing the option itself.
@@ -669,13 +666,13 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// FIXME: We should scan the other options provided and only complete
// options
// within the option group they belong to.
- char opt_str[3] = {'-', 'a', '\0'};
+ std::string opt_str = "-a";
for (auto &def : opt_defs) {
if (!def.short_option)
continue;
opt_str[1] = def.short_option;
- request.AddCompletion(opt_str);
+ request.AddCompletion(opt_str, def.usage_text);
}
return true;
@@ -687,7 +684,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
full_name.erase(full_name.begin() + 2, full_name.end());
full_name.append(def.long_option);
- request.AddCompletion(full_name.c_str());
+ request.AddCompletion(full_name, def.usage_text);
}
return true;
} else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
@@ -695,17 +692,14 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// anyway (getopt_long_only is happy with shortest unique string, but
// it's still a nice thing to do.) Otherwise return The string so the
// upper level code will know this is a full match and add the " ".
- if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
- cur_opt_str[1] == '-' &&
- strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) {
- std::string full_name("--");
- full_name.append(opt_defs[opt_defs_index].long_option);
- request.AddCompletion(full_name.c_str());
- return true;
- } else {
- request.AddCompletion(request.GetCursorArgument());
+ const OptionDefinition &opt = opt_defs[opt_defs_index];
+ llvm::StringRef long_option = opt.long_option;
+ if (cur_opt_str.startswith("--") && cur_opt_str != long_option) {
+ request.AddCompletion("--" + long_option.str(), opt.usage_text);
return true;
- }
+ } else
+ request.AddCompletion(request.GetCursorArgumentPrefix());
+ return true;
} else {
// FIXME - not handling wrong options yet:
// Check to see if they are writing a long option & complete it.
@@ -713,18 +707,11 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
// elements
// that are not unique up to this point. getopt_long_only does
// shortest unique match for long options already.
-
- if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
- cur_opt_str[1] == '-') {
+ if (cur_opt_str.consume_front("--")) {
for (auto &def : opt_defs) {
- if (!def.long_option)
- continue;
-
- if (strstr(def.long_option, cur_opt_str + 2) == def.long_option) {
- std::string full_name("--");
- full_name.append(def.long_option);
- request.AddCompletion(full_name.c_str());
- }
+ llvm::StringRef long_option(def.long_option);
+ if (long_option.startswith(cur_opt_str))
+ request.AddCompletion("--" + long_option.str(), def.usage_text);
}
}
return true;
@@ -733,13 +720,9 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
} else if (opt_arg_pos == request.GetCursorIndex()) {
// Okay the cursor is on the completion of an argument. See if it has a
// completion, otherwise return no matches.
-
- CompletionRequest subrequest = request;
- subrequest.SetCursorCharPosition(subrequest.GetCursorArgument().size());
if (opt_defs_index != -1) {
- HandleOptionArgumentCompletion(subrequest, opt_element_vector, i,
+ HandleOptionArgumentCompletion(request, opt_element_vector, i,
interpreter);
- request.SetWordComplete(subrequest.GetWordComplete());
return true;
} else {
// No completion callback means no completions...
@@ -754,34 +737,20 @@ bool Options::HandleOptionCompletion(CompletionRequest &request,
return false;
}
-bool Options::HandleOptionArgumentCompletion(
+void Options::HandleOptionArgumentCompletion(
CompletionRequest &request, OptionElementVector &opt_element_vector,
int opt_element_index, CommandInterpreter &interpreter) {
auto opt_defs = GetDefinitions();
std::unique_ptr<SearchFilter> filter_up;
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
// See if this is an enumeration type option, and if so complete it here:
const auto &enum_values = opt_defs[opt_defs_index].enum_values;
- if (!enum_values.empty()) {
- bool return_value = false;
- std::string match_string(
- request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos),
- request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) +
- request.GetCursorCharPosition());
-
- for (const auto &enum_value : enum_values) {
- if (strstr(enum_value.string_value, match_string.c_str()) ==
- enum_value.string_value) {
- request.AddCompletion(enum_value.string_value);
- return_value = true;
- }
- }
- return return_value;
- }
+ if (!enum_values.empty())
+ for (const auto &enum_value : enum_values)
+ request.TryCompleteCurrentArg(enum_value.string_value);
// If this is a source file or symbol type completion, and there is a -shlib
// option somewhere in the supplied arguments, then make a search filter for
@@ -836,7 +805,7 @@ bool Options::HandleOptionArgumentCompletion(
}
}
- return CommandCompletions::InvokeCommonCompletionCallbacks(
+ CommandCompletions::InvokeCommonCompletionCallbacks(
interpreter, completion_mask, request, filter_up.get());
}
@@ -954,7 +923,7 @@ static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
for (const char *arg : parsed) {
auto pos = FindOriginalIter(arg, original);
assert(pos != original.end());
- result.AppendArgument(pos->ref, pos->quote);
+ result.AppendArgument(pos->ref(), pos->GetQuoteChar());
}
return result;
}
@@ -965,8 +934,8 @@ static size_t FindArgumentIndexForOption(const Args &args,
std::string long_opt =
llvm::formatv("--{0}", long_option.definition->long_option);
for (const auto &entry : llvm::enumerate(args)) {
- if (entry.value().ref.startswith(short_opt) ||
- entry.value().ref.startswith(long_opt))
+ if (entry.value().ref().startswith(short_opt) ||
+ entry.value().ref().startswith(long_opt))
return entry.index();
}
@@ -1105,7 +1074,7 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
continue;
if (!input_line.empty()) {
- auto tmp_arg = args_copy[idx].ref;
+ auto tmp_arg = args_copy[idx].ref();
size_t pos = input_line.find(tmp_arg);
if (pos != std::string::npos)
input_line.erase(pos, tmp_arg.size());
@@ -1115,9 +1084,9 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
OptionParser::eNoArgument) &&
(OptionParser::GetOptionArgument() != nullptr) &&
(idx < args_copy.GetArgumentCount()) &&
- (args_copy[idx].ref == OptionParser::GetOptionArgument())) {
+ (args_copy[idx].ref() == OptionParser::GetOptionArgument())) {
if (input_line.size() > 0) {
- auto tmp_arg = args_copy[idx].ref;
+ auto tmp_arg = args_copy[idx].ref();
size_t pos = input_line.find(tmp_arg);
if (pos != std::string::npos)
input_line.erase(pos, tmp_arg.size());
@@ -1308,7 +1277,7 @@ OptionElementVector Options::ParseForCompletion(const Args &args,
const Args::ArgEntry &cursor = args[cursor_index];
if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
cursor_index < dash_dash_pos) &&
- !cursor.IsQuoted() && cursor.ref == "-") {
+ !cursor.IsQuoted() && cursor.ref() == "-") {
option_element_vector.push_back(
OptionArgElement(OptionArgElement::eBareDash, cursor_index,
OptionArgElement::eBareDash));
@@ -1411,6 +1380,10 @@ llvm::Expected<Args> Options::Parse(const Args &args,
? nullptr
: OptionParser::GetOptionArgument(),
execution_context);
+ // If the Option setting returned an error, we should stop parsing
+ // and return the error.
+ if (error.Fail())
+ break;
} else {
error.SetErrorStringWithFormat("invalid option with value '%i'", val);
}
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 362a80be4b0d..9dff12bcc748 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -1326,7 +1326,8 @@ ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
if (vendor_type == llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- return ABISP(new ABIMacOSX_arm(process_sp));
+ return ABISP(
+ new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1846,6 +1847,7 @@ bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
index ac9ba00b9d91..e512651f86e5 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -85,7 +85,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 368e37213249..6473ccf9a19a 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -1665,8 +1665,10 @@ ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type == llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64) {
- return ABISP(new ABIMacOSX_arm64(process_sp));
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABIMacOSX_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1710,9 +1712,8 @@ bool ABIMacOSX_arm64::PrepareTrivialCall(
for (size_t i = 0; i < args.size(); ++i) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
+ 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;
}
@@ -2011,6 +2012,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64-apple-darwin default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
index bfacbcd54a94..c7a91ba9c468 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
@@ -93,7 +93,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABIMacOSX_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 67371b432ff8..76ebd6476ffd 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -710,7 +710,8 @@ ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch)
if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
(arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() ||
arch.GetTriple().isWatchOS())) {
- return ABISP(new ABIMacOSX_i386(process_sp));
+ return ABISP(
+ new ABIMacOSX_i386(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1055,6 +1056,7 @@ bool ABIMacOSX_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index 57def683283f..50062b84d878 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -92,7 +92,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABIMacOSX_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
new file mode 100644
index 000000000000..715b5e5d2b95
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.cpp
@@ -0,0 +1,614 @@
+//===-- ABISysV_arc.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_arc.h"
+
+// C Includes
+// C++ Includes
+#include <array>
+#include <limits>
+#include <type_traits>
+
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/Support/MathExtras.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
+#define DEFINE_REG_NAME_STR(reg_name) ConstString(reg_name).GetCString()
+
+// The ABI is not a source of such information as size, offset, encoding, etc.
+// of a register. Just provides correct dwarf and eh_frame numbers.
+
+#define DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, generic_num) \
+ { \
+ DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \
+ 0, 0, eEncodingInvalid, eFormatDefault, \
+ { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_REGISTER_STUB(dwarf_num, str_name) \
+ DEFINE_GENERIC_REGISTER_STUB(dwarf_num, str_name, LLDB_INVALID_REGNUM)
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+namespace dwarf {
+enum regnums {
+ r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16,
+ r17, r18, r19, r20, r21, r22, r23, r24, r25, r26,
+ r27, fp = r27, r28, sp = r28, r29, r30, r31, blink = r31,
+ r32, r33, r34, r35, r36, r37, r38, r39, r40, r41, r42, r43, r44, r45, r46,
+ r47, r48, r49, r50, r51, r52, r53, r54, r55, r56, r57, r58, r59, r60,
+ /*reserved,*/ /*limm indicator,*/ r63 = 63, pc = 70, status32 = 74
+};
+
+static const std::array<RegisterInfo, 64> g_register_infos = { {
+ DEFINE_GENERIC_REGISTER_STUB(r0, nullptr, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GENERIC_REGISTER_STUB(r1, nullptr, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GENERIC_REGISTER_STUB(r2, nullptr, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GENERIC_REGISTER_STUB(r3, nullptr, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GENERIC_REGISTER_STUB(r4, nullptr, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GENERIC_REGISTER_STUB(r5, nullptr, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GENERIC_REGISTER_STUB(r6, nullptr, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GENERIC_REGISTER_STUB(r7, nullptr, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_REGISTER_STUB(r8, nullptr),
+ DEFINE_REGISTER_STUB(r9, nullptr),
+ DEFINE_REGISTER_STUB(r10, nullptr),
+ DEFINE_REGISTER_STUB(r11, nullptr),
+ DEFINE_REGISTER_STUB(r12, nullptr),
+ DEFINE_REGISTER_STUB(r13, nullptr),
+ DEFINE_REGISTER_STUB(r14, nullptr),
+ DEFINE_REGISTER_STUB(r15, nullptr),
+ DEFINE_REGISTER_STUB(r16, nullptr),
+ DEFINE_REGISTER_STUB(r17, nullptr),
+ DEFINE_REGISTER_STUB(r18, nullptr),
+ DEFINE_REGISTER_STUB(r19, nullptr),
+ DEFINE_REGISTER_STUB(r20, nullptr),
+ DEFINE_REGISTER_STUB(r21, nullptr),
+ DEFINE_REGISTER_STUB(r22, nullptr),
+ DEFINE_REGISTER_STUB(r23, nullptr),
+ DEFINE_REGISTER_STUB(r24, nullptr),
+ DEFINE_REGISTER_STUB(r25, nullptr),
+ DEFINE_REGISTER_STUB(r26, "gp"),
+ DEFINE_GENERIC_REGISTER_STUB(r27, "fp", LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GENERIC_REGISTER_STUB(r28, "sp", LLDB_REGNUM_GENERIC_SP),
+ DEFINE_REGISTER_STUB(r29, "ilink"),
+ DEFINE_REGISTER_STUB(r30, nullptr),
+ DEFINE_GENERIC_REGISTER_STUB(r31, "blink", LLDB_REGNUM_GENERIC_RA),
+ DEFINE_REGISTER_STUB(r32, nullptr),
+ DEFINE_REGISTER_STUB(r33, nullptr),
+ DEFINE_REGISTER_STUB(r34, nullptr),
+ DEFINE_REGISTER_STUB(r35, nullptr),
+ DEFINE_REGISTER_STUB(r36, nullptr),
+ DEFINE_REGISTER_STUB(r37, nullptr),
+ DEFINE_REGISTER_STUB(r38, nullptr),
+ DEFINE_REGISTER_STUB(r39, nullptr),
+ DEFINE_REGISTER_STUB(r40, nullptr),
+ DEFINE_REGISTER_STUB(r41, nullptr),
+ DEFINE_REGISTER_STUB(r42, nullptr),
+ DEFINE_REGISTER_STUB(r43, nullptr),
+ DEFINE_REGISTER_STUB(r44, nullptr),
+ DEFINE_REGISTER_STUB(r45, nullptr),
+ DEFINE_REGISTER_STUB(r46, nullptr),
+ DEFINE_REGISTER_STUB(r47, nullptr),
+ DEFINE_REGISTER_STUB(r48, nullptr),
+ DEFINE_REGISTER_STUB(r49, nullptr),
+ DEFINE_REGISTER_STUB(r50, nullptr),
+ DEFINE_REGISTER_STUB(r51, nullptr),
+ DEFINE_REGISTER_STUB(r52, nullptr),
+ DEFINE_REGISTER_STUB(r53, nullptr),
+ DEFINE_REGISTER_STUB(r54, nullptr),
+ DEFINE_REGISTER_STUB(r55, nullptr),
+ DEFINE_REGISTER_STUB(r56, nullptr),
+ DEFINE_REGISTER_STUB(r57, nullptr),
+ DEFINE_REGISTER_STUB(r58, "accl"),
+ DEFINE_REGISTER_STUB(r59, "acch"),
+ DEFINE_REGISTER_STUB(r60, "lp_count"),
+ DEFINE_REGISTER_STUB(r63, "pcl"),
+ DEFINE_GENERIC_REGISTER_STUB(pc, nullptr, LLDB_REGNUM_GENERIC_PC),
+ DEFINE_GENERIC_REGISTER_STUB(status32, nullptr, LLDB_REGNUM_GENERIC_FLAGS)} };
+} // namespace dwarf
+} // namespace
+
+const RegisterInfo *ABISysV_arc::GetRegisterInfoArray(uint32_t &count) {
+ count = dwarf::g_register_infos.size();
+ return dwarf::g_register_infos.data();
+}
+
+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.
+ const uint32_t rf_entries_bit = 1U << 9U;
+ m_is_reg_file_reduced = (reg_value | rf_entries_bit) != 0;
+ }
+
+ return m_is_reg_file_reduced.getValueOr(false);
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+
+ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
+ return llvm::Triple::arc == arch.GetTriple().getArch() ?
+ ABISP(new ABISysV_arc(std::move(process_sp), MakeMCRegisterInfo(arch))) :
+ ABISP();
+}
+
+namespace {
+const size_t word_size = 4U;
+const size_t reg_size = word_size;
+
+inline size_t AugmentArgSize(size_t size_in_bytes) {
+ return llvm::alignTo(size_in_bytes, word_size);
+}
+
+size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) {
+ size_t total_size = 0;
+ for (const auto &arg : args)
+ total_size +=
+ (ABI::CallArgument::TargetValue == arg.type ? AugmentArgSize(arg.size)
+ : reg_size) /
+ word_size;
+
+ return total_size;
+}
+} // namespace
+
+bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp,
+ addr_t func_addr, addr_t return_addr,
+ llvm::ArrayRef<addr_t> args) const {
+ // We don't use the traditional trivial call specialized for jit.
+ return false;
+}
+
+bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc,
+ addr_t ra, llvm::Type &prototype,
+ llvm::ArrayRef<ABI::CallArgument> args) const {
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return false;
+
+ uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ if (pc_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+ if (ra_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+ if (sp_reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ Status error;
+ ProcessSP process = thread.GetProcess();
+ if (!process)
+ return false;
+
+ // Push host data onto target.
+ for (const auto &arg : args) {
+ // Skip over target values.
+ if (arg.type == ABI::CallArgument::TargetValue)
+ continue;
+
+ // Create space on the stack for this data 4-byte aligned.
+ sp -= AugmentArgSize(arg.size);
+
+ if (process->WriteMemory(sp, arg.data_up.get(), arg.size, error) < arg.size
+ || error.Fail())
+ return false;
+
+ // Update the argument with the target pointer.
+ *const_cast<addr_t *>(&arg.value) = sp;
+ }
+
+ // 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.
+ auto args_size = TotalArgsSizeInWords(args);
+ auto on_stack =
+ args_size <= regs_for_args_count ? 0 : args_size - regs_for_args_count;
+ auto offset = on_stack * word_size;
+
+ uint8_t reg_value[reg_size];
+ size_t reg_index = LLDB_REGNUM_GENERIC_ARG1;
+
+ for (const auto &arg : args) {
+ auto value = reinterpret_cast<const uint8_t *>(&arg.value);
+ auto size =
+ ABI::CallArgument::TargetValue == arg.type ? arg.size : reg_size;
+
+ // Pass arguments via registers.
+ while (size > 0 && reg_index < regs_for_args_count) {
+ size_t byte_index = 0;
+ auto end = size < reg_size ? size : reg_size;
+
+ while (byte_index < end) {
+ reg_value[byte_index++] = *(value++);
+ --size;
+ }
+
+ while (byte_index < reg_size) {
+ reg_value[byte_index++] = 0;
+ }
+
+ RegisterValue reg_val_obj(reg_value, reg_size, eByteOrderLittle);
+ if (!reg_ctx->WriteRegister(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index),
+ reg_val_obj))
+ return false;
+
+ // NOTE: It's unsafe to iterate through LLDB_REGNUM_GENERICs.
+ ++reg_index;
+ }
+
+ if (reg_index < regs_for_args_count || size == 0)
+ continue;
+
+ // Remaining arguments are passed on the stack.
+ if (process->WriteMemory(sp - offset, value, size, error) < size ||
+ !error.Success())
+ return false;
+
+ offset -= AugmentArgSize(size);
+ }
+
+ // Set stack pointer immediately below arguments.
+ sp -= on_stack * word_size;
+
+ // Update registers with current function call state.
+ reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
+ reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
+ reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
+
+ return true;
+}
+
+bool ABISysV_arc::GetArgumentValues(Thread &thread, ValueList &values) const {
+ return false;
+}
+
+Status ABISysV_arc::SetReturnValueObject(StackFrameSP &frame_sp,
+ ValueObjectSP &new_value_sp) {
+ Status result;
+ if (!new_value_sp) {
+ result.SetErrorString("Empty value object for return value.");
+ return result;
+ }
+
+ CompilerType compiler_type = new_value_sp->GetCompilerType();
+ if (!compiler_type) {
+ result.SetErrorString("Null clang type for return value.");
+ return result;
+ }
+
+ auto &reg_ctx = *frame_sp->GetThread()->GetRegisterContext();
+
+ bool is_signed = false;
+ if (!compiler_type.IsIntegerOrEnumerationType(is_signed) &&
+ !compiler_type.IsPointerType()) {
+ result.SetErrorString("We don't support returning other types at present");
+ return result;
+ }
+
+ DataExtractor data;
+ size_t num_bytes = new_value_sp->GetData(data, result);
+
+ if (result.Fail()) {
+ result.SetErrorStringWithFormat(
+ "Couldn't convert return value to raw data: %s", result.AsCString());
+ return result;
+ }
+
+ if (num_bytes <= 2 * reg_size) {
+ offset_t offset = 0;
+ uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+ auto reg_info =
+ reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+ if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
+ result.SetErrorStringWithFormat("Couldn't write value to register %s",
+ reg_info->name);
+ return result;
+ }
+
+ if (num_bytes <= reg_size)
+ return result; // Successfully written.
+
+ raw_value >>= 32;
+ reg_info =
+ reg_ctx.GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
+ if (!reg_ctx.WriteRegisterFromUnsigned(reg_info, raw_value)) {
+ result.SetErrorStringWithFormat("Couldn't write value to register %s",
+ reg_info->name);
+ }
+
+ return result;
+ }
+
+ result.SetErrorString(
+ "We don't support returning large integer values at present.");
+ return result;
+}
+
+namespace {
+template <typename T>
+void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) {
+ raw_value &= std::numeric_limits<T>::max();
+ if (is_signed)
+ scalar = static_cast<typename std::make_signed<T>::type>(raw_value);
+ else
+ scalar = static_cast<T>(raw_value);
+}
+
+bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes,
+ bool is_signed) {
+ switch (size_in_bytes) {
+ default:
+ return false;
+
+ case sizeof(uint64_t):
+ SetInteger<uint64_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint32_t):
+ SetInteger<uint32_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint16_t):
+ SetInteger<uint16_t>(scalar, raw_value, is_signed);
+ break;
+
+ case sizeof(uint8_t):
+ SetInteger<uint8_t>(scalar, raw_value, is_signed);
+ break;
+ }
+
+ return true;
+}
+
+bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) {
+ switch (size_in_bytes) {
+ default:
+ return false;
+
+ case sizeof(uint64_t):
+ scalar = *reinterpret_cast<double *>(&raw_value);
+ break;
+
+ case sizeof(uint32_t):
+ scalar = *reinterpret_cast<float *>(&raw_value);
+ break;
+ }
+
+ return true;
+}
+
+uint64_t ReadRawValue(const RegisterContextSP &reg_ctx, uint8_t size_in_bytes) {
+ auto reg_info_r0 =
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
+
+ // Extract the register context so we can read arguments from registers.
+ uint64_t raw_value =
+ reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0) & UINT32_MAX;
+
+ if (sizeof(uint64_t) == size_in_bytes)
+ raw_value |= (reg_ctx->ReadRegisterAsUnsigned(
+ reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG2), 0) &
+ UINT64_MAX) << 32U;
+
+ return raw_value;
+}
+} // namespace
+
+ValueObjectSP
+ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
+ CompilerType &compiler_type) const {
+ if (!compiler_type)
+ return ValueObjectSP();
+
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return ValueObjectSP();
+
+ Value value;
+ value.SetCompilerType(compiler_type);
+
+ const uint32_t type_flags = compiler_type.GetTypeInfo();
+ // Integer return type.
+ if (type_flags & eTypeIsInteger) {
+ const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+ if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
+ return ValueObjectSP();
+
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // Pointer return type.
+ else if (type_flags & eTypeIsPointer) {
+ auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
+
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // Floating point return type.
+ else if (type_flags & eTypeIsFloat) {
+ uint32_t float_count = 0;
+ bool is_complex = false;
+
+ if (compiler_type.IsFloatingPointType(float_count, is_complex) &&
+ 1 == float_count && !is_complex) {
+ const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return ValueObjectSP();
+ }
+ }
+ // Unsupported return type.
+ else
+ return ValueObjectSP();
+
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+}
+
+ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(
+ Thread &thread, CompilerType &return_compiler_type) const {
+ ValueObjectSP return_valobj_sp;
+
+ if (!return_compiler_type)
+ return return_valobj_sp;
+
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ return GetReturnValueObjectSimple(thread, return_compiler_type);
+}
+
+ValueObjectSP ABISysV_arc::GetReturnValueObjectImpl(Thread &thread,
+ llvm::Type &retType) const {
+ auto reg_ctx = thread.GetRegisterContext();
+ if (!reg_ctx)
+ return ValueObjectSP();
+
+ Value value;
+ // Void return type.
+ if (retType.isVoidTy()) {
+ value.GetScalar() = 0;
+ }
+ // Integer return type.
+ else if (retType.isIntegerTy()) {
+ size_t byte_size = retType.getPrimitiveSizeInBits();
+ if (1 != byte_size) // For boolian type.
+ byte_size /= CHAR_BIT;
+
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ const bool is_signed = false; // IR Type doesn't provide this info.
+ if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
+ return ValueObjectSP();
+ }
+ // Pointer return type.
+ else if (retType.isPointerTy()) {
+ auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_ARG1);
+ value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ }
+ // Floating point return type.
+ else if (retType.isFloatingPointTy()) {
+ const size_t byte_size = retType.getPrimitiveSizeInBits() / CHAR_BIT;
+ auto raw_value = ReadRawValue(reg_ctx, byte_size);
+
+ if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
+ return ValueObjectSP();
+ }
+ // Unsupported return type.
+ else
+ return ValueObjectSP();
+
+ return ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
+ value, ConstString(""));
+}
+
+bool ABISysV_arc::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Our Call Frame Address is the stack pointer value.
+ row->GetCFAValue().SetIsRegisterPlusOffset(dwarf::sp, 0);
+
+ // The previous PC is in the BLINK.
+ row->SetRegisterLocationToRegister(dwarf::pc, dwarf::blink, true);
+ unwind_plan.AppendRow(row);
+
+ // All other registers are the same.
+ unwind_plan.SetSourceName("arc at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+
+ return true;
+}
+
+bool ABISysV_arc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ return false;
+}
+
+bool ABISysV_arc::RegisterIsVolatile(const RegisterInfo *reg_info) {
+ if (nullptr == reg_info)
+ return false;
+
+ // Volatile registers are: r0..r12.
+ uint32_t regnum = reg_info->kinds[eRegisterKindDWARF];
+ if (regnum <= 12)
+ return true;
+
+ static const std::string ra_reg_name = "blink";
+ return ra_reg_name == reg_info->name;
+}
+
+void ABISysV_arc::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "System V ABI for ARC targets", CreateInstance);
+}
+
+void ABISysV_arc::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString ABISysV_arc::GetPluginNameStatic() {
+ static ConstString g_name("sysv-arc");
+ return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+ConstString ABISysV_arc::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ABISysV_arc::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/ABI/SysV-arc/ABISysV_arc.h b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h
new file mode 100644
index 000000000000..c4b26a54158c
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/ABISysV_arc.h
@@ -0,0 +1,106 @@
+//===-- ArchitectureArc.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_ABISysV_arc_h_
+#define liblldb_ABISysV_arc_h_
+
+// Other libraries and framework includes
+#include <llvm/ADT/Optional.h>
+
+// Project includes
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABISysV_arc : public lldb_private::ABI {
+public:
+ ~ABISysV_arc() override = default;
+
+ size_t GetRedZoneSize() const override;
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override;
+
+ // Special thread plan for GDB style non-jit function calls.
+ bool
+ PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress, lldb::addr_t returnAddress,
+ llvm::Type &prototype,
+ llvm::ArrayRef<ABI::CallArgument> args) const override;
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override;
+
+ lldb_private::Status
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override;
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override;
+
+ // Specialized to work with llvm IR types.
+ lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ llvm::Type &type) const override;
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Stack call frame address must be 4 byte aligned.
+ return (cfa & 0x3ull) == 0;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Code addresse must be 2 byte aligned.
+ return (pc & 1ull) == 0;
+ }
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoArray(uint32_t &count) override;
+
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp,
+ const lldb_private::ArchSpec &arch);
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+private:
+ lldb::ValueObjectSP
+ GetReturnValueObjectSimple(lldb_private::Thread &thread,
+ lldb_private::CompilerType &ast_type) const;
+
+ bool IsRegisterFileReduced(lldb_private::RegisterContext &reg_ctx) const;
+
+ using lldb_private::ABI::ABI; // Call CreateInstance instead.
+
+ using RegisterFileFlag = llvm::Optional<bool>;
+ mutable RegisterFileFlag m_is_reg_file_reduced;
+};
+
+#endif // liblldb_ABISysV_arc_h_
diff --git a/source/Plugins/ABI/SysV-arc/CMakeLists.txt b/source/Plugins/ABI/SysV-arc/CMakeLists.txt
new file mode 100644
index 000000000000..3dc0d1c65b46
--- /dev/null
+++ b/source/Plugins/ABI/SysV-arc/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginABISysV_arc PLUGIN
+ ABISysV_arc.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbPluginProcessUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index dd47ac7cbe3c..b6e8f8806829 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -1327,7 +1327,8 @@ ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (vendor_type != llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- return ABISP(new ABISysV_arm(process_sp));
+ return ABISP(
+ new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1960,6 +1961,7 @@ bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index a0f00c8f227d..60fb14be5f7b 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -85,7 +85,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index 1d547121e231..89a1f2b3cf04 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -1668,8 +1668,10 @@ ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch)
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type != llvm::Triple::Apple) {
- if (arch_type == llvm::Triple::aarch64) {
- return ABISP(new ABISysV_arm64(process_sp));
+ if (arch_type == llvm::Triple::aarch64 ||
+ arch_type == llvm::Triple::aarch64_32) {
+ return ABISP(
+ new ABISysV_arm64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
@@ -1706,9 +1708,8 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
- static_cast<int>(i + 1), args[i], reg_info->name);
+ 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;
}
@@ -1958,6 +1959,7 @@ bool ABISysV_arm64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
@@ -1982,6 +1984,7 @@ bool ABISysV_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("arm64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
index 1fbdc793ed6e..1bf5773e2db3 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
@@ -92,7 +92,9 @@ protected:
lldb_private::CompilerType &ast_type) const override;
private:
- ABISysV_arm64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index 93647564fe25..34d9258ccb92 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -1014,7 +1014,8 @@ size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
- return ABISP(new ABISysV_hexagon(process_sp));
+ return ABISP(
+ new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1247,6 +1248,7 @@ bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("hexagon default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
index 459b6315dba2..bef64a22d95f 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
@@ -97,7 +97,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_hexagon(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index 05f5dba90687..69e4cff90ebf 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -198,7 +198,8 @@ ABISP
ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getVendor() != llvm::Triple::Apple) {
if (arch.GetTriple().getArch() == llvm::Triple::x86) {
- return ABISP(new ABISysV_i386(process_sp));
+ return ABISP(
+ new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
}
return ABISP();
@@ -785,6 +786,7 @@ bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("i386 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
index 982bdd676b74..2362e9adda98 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
@@ -100,7 +100,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_i386(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 121c7300b968..416db9f5ae87 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -556,7 +556,8 @@ ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
if ((arch_type == llvm::Triple::mips) ||
(arch_type == llvm::Triple::mipsel)) {
- return ABISP(new ABISysV_mips(process_sp));
+ return ABISP(
+ new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -600,9 +601,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
- args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
@@ -630,9 +630,8 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
size_t i = 4;
for (; ai != ae; ++ai) {
reg_value.SetUInt32(*ai);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
- i + 1, args[i], arg_pos);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
+ i + 1, args[i], arg_pos);
if (reg_ctx
->WriteRegisterValueToMemory(reg_info, arg_pos,
@@ -654,8 +653,7 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
- if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+ LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
/* Write r0 with 0, in case we are stopped in syscall,
* such setting prevents automatic decrement of the PC.
@@ -664,29 +662,25 @@ bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
// Set pc to the address of the called function.
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
// All callers of position independent functions must place the address of
// the called function in t9 (r25)
@@ -997,6 +991,7 @@ bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("mips default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
index 6cd9c19c22ac..8143f552fc4d 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
@@ -87,7 +87,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index 18011cfb6b9e..72ec0715b6cd 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -554,7 +554,8 @@ size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().isMIPS64())
- return ABISP(new ABISysV_mips64(process_sp));
+ return ABISP(
+ new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch)));
return ABISP();
}
@@ -589,18 +590,16 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
- args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
+ args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -614,8 +613,7 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
- if (log)
- log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+ LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
/* Write r0 with 0, in case we are stopped in syscall,
* such setting prevents automatic decrement of the PC.
@@ -624,29 +622,25 @@ bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp,
if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
return false;
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
// Set pc to the address of the called function.
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
- if (log)
- log->Printf("Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
// All callers of position independent functions must place the address of
// the called function in t9 (r25)
@@ -1168,6 +1162,7 @@ bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("mips64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
index 7da71b36b4b7..76c3c5413b92 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
@@ -100,7 +100,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_mips64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index faa995033ac2..857b7fee10e3 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -218,7 +218,8 @@ size_t ABISysV_ppc::GetRedZoneSize() const { return 224; }
ABISP
ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::ppc) {
- return ABISP(new ABISysV_ppc(process_sp));
+ return ABISP(
+ new ABISysV_ppc(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -255,18 +256,16 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -281,10 +280,10 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -292,16 +291,14 @@ bool ABISysV_ppc::PrepareTrivialCall(Thread &thread, addr_t sp,
// %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -910,6 +907,7 @@ bool ABISysV_ppc::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("ppc default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
index 3b199852c30d..59907c4648ba 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
@@ -96,7 +96,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index aa7907550f29..935353c38ca4 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -70,7 +70,8 @@ ABISP
ABISysV_ppc64::CreateInstance(lldb::ProcessSP process_sp,
const ArchSpec &arch) {
if (arch.GetTriple().isPPC64())
- return ABISP(new ABISysV_ppc64(process_sp));
+ return ABISP(
+ new ABISysV_ppc64(std::move(process_sp), MakeMCRegisterInfo(arch)));
return ABISP();
}
@@ -106,18 +107,16 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -136,22 +135,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
const RegisterInfo *r12_reg_info = reg_ctx->GetRegisterInfoAtIndex(12);
// Save return address onto the stack.
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- "(+16): 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ "(+16): 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
if (!process_sp->WritePointerToMemory(sp + 16, return_addr, error))
return false;
// Write the return address to link register.
- if (log)
- log->Printf("Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing LR: 0x%" PRIx64, (uint64_t)return_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(lr_reg_info, return_addr))
return false;
// Write target address to %r12 register.
- if (log)
- log->Printf("Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing R12: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(r12_reg_info, func_addr))
return false;
@@ -165,10 +162,9 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
else
stack_offset = 40;
- if (log)
- log->Printf("Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
- (uint64_t)(sp + stack_offset), (int)stack_offset,
- (uint64_t)reg_value);
+ LLDB_LOGF(log, "Writing R2 (TOC) at SP(0x%" PRIx64 ")+%d: 0x%" PRIx64,
+ (uint64_t)(sp + stack_offset), (int)stack_offset,
+ (uint64_t)reg_value);
if (!process_sp->WritePointerToMemory(sp + stack_offset, reg_value, error))
return false;
@@ -176,23 +172,20 @@ bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
reg_value = reg_ctx->ReadRegisterAsUnsigned(sp_reg_info, 0);
// Save current SP onto the stack.
- if (log)
- log->Printf("Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
- (uint64_t)reg_value);
+ LLDB_LOGF(log, "Writing SP at SP(0x%" PRIx64 ")+0: 0x%" PRIx64, (uint64_t)sp,
+ (uint64_t)reg_value);
if (!process_sp->WritePointerToMemory(sp, reg_value, error))
return false;
// %r1 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -1017,6 +1010,7 @@ bool ABISysV_ppc64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("ppc64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(pc_reg_num);
return true;
}
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
index d5fb09eec0d0..1b58975dd9d9 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
@@ -96,7 +96,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_ppc64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
index abe847b386a8..f4f803a8277d 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -200,7 +200,7 @@ size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::systemz) {
- return ABISP(new ABISysV_s390x(process_sp));
+ return ABISP(new ABISysV_s390x(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -252,16 +252,14 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
if (i < 5) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
} else {
Status error;
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
- static_cast<uint64_t>(i + 1), args[i]);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
+ static_cast<uint64_t>(i + 1), args[i]);
if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
return false;
arg_pos += 8;
@@ -270,24 +268,21 @@ bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
// %r14 is set to the return address
- if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
return false;
// %r15 is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %pc is set to the address of the called function.
- if (log)
- log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
index 13df477e84bc..671d6a18260e 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
@@ -88,7 +88,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_s390x(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 6c7b45f63399..bf1c48f778e1 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -222,17 +222,35 @@ ABISP
ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::OSType os_type = arch.GetTriple().getOS();
+ const llvm::Triple::EnvironmentType os_env =
+ arch.GetTriple().getEnvironment();
if (arch_type == llvm::Triple::x86_64) {
switch(os_type) {
- case llvm::Triple::OSType::MacOSX:
- case llvm::Triple::OSType::Linux:
- case llvm::Triple::OSType::FreeBSD:
- case llvm::Triple::OSType::NetBSD:
- case llvm::Triple::OSType::Solaris:
- case llvm::Triple::OSType::UnknownOS:
- return ABISP(new ABISysV_x86_64(process_sp));
- default:
+ case llvm::Triple::OSType::IOS:
+ case llvm::Triple::OSType::TvOS:
+ case llvm::Triple::OSType::WatchOS:
+ switch (os_env) {
+ case llvm::Triple::EnvironmentType::MacABI:
+ case llvm::Triple::EnvironmentType::Simulator:
+ case llvm::Triple::EnvironmentType::UnknownEnvironment:
+ // UnknownEnvironment is needed for older compilers that don't
+ // support the simulator environment.
+ return ABISP(new ABISysV_x86_64(std::move(process_sp),
+ MakeMCRegisterInfo(arch)));
+ default:
return ABISP();
+ }
+ case llvm::Triple::OSType::Darwin:
+ case llvm::Triple::OSType::FreeBSD:
+ case llvm::Triple::OSType::Linux:
+ case llvm::Triple::OSType::MacOSX:
+ case llvm::Triple::OSType::NetBSD:
+ case llvm::Triple::OSType::Solaris:
+ case llvm::Triple::OSType::UnknownOS:
+ return ABISP(
+ new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
+ default:
+ return ABISP();
}
}
return ABISP();
@@ -270,18 +288,16 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -295,10 +311,10 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -306,16 +322,14 @@ bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
// %rsp is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %rip is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
@@ -1034,6 +1048,7 @@ bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("x86_64 default unwind plan");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
index f6704aff348c..d445d8f4142a 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -98,7 +98,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABISysV_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
index 5dc7717d865d..ac24426914e1 100644
--- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
+++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.cpp
@@ -1092,7 +1092,8 @@ ABISP
ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
arch.GetTriple().isOSWindows()) {
- return ABISP(new ABIWindows_x86_64(process_sp));
+ return ABISP(
+ new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
}
return ABISP();
}
@@ -1129,18 +1130,16 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
for (size_t i = 0; i < args.size(); ++i) {
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1 + i);
- if (log)
- log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
- static_cast<uint64_t>(i + 1), args[i], reg_info->name);
+ LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
+ static_cast<uint64_t>(i + 1), args[i], reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
return false;
}
// First, align the SP
- if (log)
- log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -1154,10 +1153,10 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
ProcessSP process_sp(thread.GetProcess());
RegisterValue reg_value;
- if (log)
- log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
- ": 0x%" PRIx64,
- (uint64_t)sp, (uint64_t)return_addr);
+ LLDB_LOGF(log,
+ "Pushing the return address onto the stack: 0x%" PRIx64
+ ": 0x%" PRIx64,
+ (uint64_t)sp, (uint64_t)return_addr);
// Save return address onto the stack
if (!process_sp->WritePointerToMemory(sp, return_addr, error))
@@ -1165,16 +1164,14 @@ bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
// %rsp is set to the actual stack value.
- if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
return false;
// %rip is set to the address of the called function.
- if (log)
- log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+ LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
return false;
diff --git a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
index 9f6b2ceef299..2366566d7809 100644
--- a/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
+++ b/source/Plugins/ABI/Windows-x86_64/ABIWindows_x86_64.h
@@ -91,7 +91,9 @@ protected:
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
private:
- ABIWindows_x86_64(lldb::ProcessSP process_sp) : lldb_private::ABI(process_sp) {
+ 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.
}
};
diff --git a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
index 60f1a2eb7572..5f2f6eeb8261 100644
--- a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
+++ b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -127,10 +127,10 @@ lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr,
// Adjust the breakable address
uint64_t breakable_addr = addr - insn->GetOpcode().GetByteSize();
- if (log)
- log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64
- " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
- __FUNCTION__, addr, breakable_addr);
+ LLDB_LOGF(log,
+ "Target::%s Breakpoint at 0x%8.8" PRIx64
+ " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
+ __FUNCTION__, addr, breakable_addr);
return breakable_addr;
}
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 44c75fc953c8..28c9de2c1e96 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -381,11 +381,10 @@ public:
static RegularExpression s_regex(
llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));
- RegularExpression::Match matches(3);
-
+ llvm::SmallVector<llvm::StringRef, 4> matches;
if (s_regex.Execute(out_string, &matches)) {
- matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
- matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ m_opcode_name = matches[1].str();
+ m_mnemonics = matches[2].str();
}
}
}
@@ -1190,10 +1189,12 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
// If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we
// can disassemble newer instructions.
- if (triple.getArch() == llvm::Triple::aarch64)
+ if (triple.getArch() == llvm::Triple::aarch64 ||
+ triple.getArch() == llvm::Triple::aarch64_32)
features_str += "+v8.5a,+sve2";
- if (triple.getArch() == llvm::Triple::aarch64
+ if ((triple.getArch() == llvm::Triple::aarch64 ||
+ triple.getArch() == llvm::Triple::aarch64_32)
&& triple.getVendor() == llvm::Triple::Apple) {
cpu = "apple-latest";
}
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 23c8416f4986..5b19647a27ba 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -277,8 +277,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
// Do not try to set the breakpoint if we don't know where to put it
if (break_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Unable to locate _rtld_debug_state breakpoint address");
+ LLDB_LOGF(log, "Unable to locate _rtld_debug_state breakpoint address");
return false;
}
@@ -301,7 +300,7 @@ bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
.GetID() == m_dyld_bid);
if (log && dyld_break == nullptr)
- log->Printf("Failed to create _rtld_debug_state breakpoint");
+ LLDB_LOGF(log, "Failed to create _rtld_debug_state breakpoint");
// check we have successfully set bp
return (dyld_break != nullptr);
@@ -316,8 +315,7 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
user_id_t break_loc_id) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Rendezvous breakpoint hit!");
+ LLDB_LOGF(log, "Rendezvous breakpoint hit!");
DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
@@ -333,11 +331,9 @@ bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
if (structAddr != LLDB_INVALID_ADDRESS) {
dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr);
- if (log)
- log->Printf("Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
+ LLDB_LOGF(log, "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
} else {
- if (log)
- log->Printf("Unable to resolve the _rtld_debug structure");
+ LLDB_LOGF(log, "Unable to resolve the _rtld_debug structure");
}
}
@@ -375,11 +371,11 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
}
if (log) {
- log->Printf("Target is loading '%s'", I->path.c_str());
+ LLDB_LOGF(log, "Target is loading '%s'", I->path.c_str());
if (!module_sp.get())
- log->Printf("LLDB failed to load '%s'", I->path.c_str());
+ LLDB_LOGF(log, "LLDB failed to load '%s'", I->path.c_str());
else
- log->Printf("LLDB successfully loaded '%s'", I->path.c_str());
+ LLDB_LOGF(log, "LLDB successfully loaded '%s'", I->path.c_str());
}
}
m_process->GetTarget().ModulesDidLoad(new_modules);
@@ -400,8 +396,7 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
UnloadSections(module_sp);
}
- if (log)
- log->Printf("Target is unloading '%s'", I->path.c_str());
+ LLDB_LOGF(log, "Target is unloading '%s'", I->path.c_str());
}
loaded_modules.Remove(old_modules);
m_process->GetTarget().ModulesDidUnload(old_modules, false);
@@ -472,10 +467,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
if (!m_rendezvous.Resolve()) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf(
- "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
+ __FUNCTION__);
return;
}
@@ -493,10 +488,10 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at "
- "0x%" PRIx64,
- __FUNCTION__, module_path, I->base_addr);
+ LLDB_LOGF(log,
+ "DynamicLoaderHexagonDYLD::%s failed loading module %s at "
+ "0x%" PRIx64,
+ __FUNCTION__, module_path, I->base_addr);
}
}
@@ -604,12 +599,11 @@ DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module,
Module *mod = module.get();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
- ", modid=%i, tls_block=0x%" PRIx64,
- mod->GetObjectName().AsCString(""), link_map, tp, modid,
- tls_block);
+ LLDB_LOGF(log,
+ "DynamicLoaderHexagonDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%i, tls_block=0x%" PRIx64,
+ mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
if (tls_block == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 844a06c2b37d..f4788816d4ea 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -290,8 +290,9 @@ bool HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field,
Target &target = m_process->GetTarget();
SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
- eSymbolTypeAny, list))
+ target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list);
+ if (list.IsEmpty())
return false;
Address address = list[0].symbol->GetAddress();
@@ -339,16 +340,16 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
return;
log->PutCString("HexagonDYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent)
- ? "consistent"
- : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
- : "unknown");
+ LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress());
+ LLDB_LOGF(log, " Version: %" PRIu64, GetVersion());
+ LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress());
+ LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress());
+ LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase());
+ LLDB_LOGF(log, " State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add"
+ : (state == eDelete) ? "delete" : "unknown");
iterator I = begin();
iterator E = end();
@@ -357,11 +358,11 @@ void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
log->PutCString("HexagonDYLDRendezvous SOEntries:");
for (int i = 1; I != E; ++I, ++i) {
- log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
+ LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->path.c_str());
+ LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr);
+ LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr);
+ LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr);
+ LLDB_LOGF(log, " Next : %" PRIx64, I->next);
+ LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
}
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 0d736738ebb5..737599303a60 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -33,16 +33,14 @@ static addr_t ResolveRendezvousAddress(Process *process) {
Status error;
if (!process) {
- if (log)
- log->Printf("%s null process provided", __FUNCTION__);
+ LLDB_LOGF(log, "%s null process provided", __FUNCTION__);
return LLDB_INVALID_ADDRESS;
}
// Try to get it from our process. This might be a remote process and might
// grab it via some remote-specific mechanism.
info_location = process->GetImageInfoAddress();
- if (log)
- log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
+ LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
// If the process fails to return an address, fall back to seeing if the
// local object file can help us find it.
@@ -54,42 +52,38 @@ static addr_t ResolveRendezvousAddress(Process *process) {
if (addr.IsValid()) {
info_location = addr.GetLoadAddress(target);
- if (log)
- log->Printf(
- "%s resolved via direct object file approach to 0x%" PRIx64,
- __FUNCTION__, info_location);
+ LLDB_LOGF(log,
+ "%s resolved via direct object file approach to 0x%" PRIx64,
+ __FUNCTION__, info_location);
} else {
- if (log)
- log->Printf("%s FAILED - direct object file approach did not yield a "
- "valid address",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "%s FAILED - direct object file approach did not yield a "
+ "valid address",
+ __FUNCTION__);
}
}
}
if (info_location == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("%s FAILED - invalid info address", __FUNCTION__);
+ LLDB_LOGF(log, "%s FAILED - invalid info address", __FUNCTION__);
return LLDB_INVALID_ADDRESS;
}
- if (log)
- log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
- __FUNCTION__, process->GetAddressByteSize(), info_location);
+ LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
+ __FUNCTION__, process->GetAddressByteSize(), info_location);
info_addr = process->ReadPointerFromMemory(info_location, error);
if (error.Fail()) {
- if (log)
- log->Printf("%s FAILED - could not read from the info location: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s",
+ __FUNCTION__, error.AsCString());
return LLDB_INVALID_ADDRESS;
}
if (info_addr == 0) {
- if (log)
- log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
- " returned a null value",
- __FUNCTION__, info_location);
+ LLDB_LOGF(log,
+ "%s FAILED - the rendezvous address contained at 0x%" PRIx64
+ " returned a null value",
+ __FUNCTION__, info_location);
return LLDB_INVALID_ADDRESS;
}
@@ -109,14 +103,13 @@ DYLDRendezvous::DYLDRendezvous(Process *process)
Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
if (exe_mod) {
m_exe_file_spec = exe_mod->GetPlatformFileSpec();
- if (log)
- log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'",
- __FUNCTION__, m_exe_file_spec.GetCString());
+ LLDB_LOGF(log, "DYLDRendezvous::%s exe module executable path set: '%s'",
+ __FUNCTION__, m_exe_file_spec.GetCString());
} else {
- if (log)
- log->Printf("DYLDRendezvous::%s cannot cache exe module path: null "
- "executable module pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DYLDRendezvous::%s cannot cache exe module path: null "
+ "executable module pointer",
+ __FUNCTION__);
}
}
}
@@ -133,17 +126,16 @@ bool DYLDRendezvous::Resolve() {
address_size = m_process->GetAddressByteSize();
padding = address_size - word_size;
- if (log)
- log->Printf("DYLDRendezvous::%s address size: %" PRIu64
- ", padding %" PRIu64,
- __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+ LLDB_LOGF(log,
+ "DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64,
+ __FUNCTION__, uint64_t(address_size), uint64_t(padding));
if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
cursor = info_addr = ResolveRendezvousAddress(m_process);
else
cursor = info_addr = m_rendezvous_addr;
- if (log)
- log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+ LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__,
+ cursor);
if (cursor == LLDB_INVALID_ADDRESS)
return false;
@@ -168,7 +160,10 @@ bool DYLDRendezvous::Resolve() {
m_previous = m_current;
m_current = info;
- if (UpdateSOEntries(true))
+ if (m_current.map_addr == 0)
+ return false;
+
+ if (UpdateSOEntriesFromRemote())
return true;
return UpdateSOEntries();
@@ -178,53 +173,91 @@ bool DYLDRendezvous::IsValid() {
return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
}
-bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
- SOEntry entry;
- LoadedModuleInfoList module_list;
+DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
+ switch (m_current.state) {
+
+ case eConsistent:
+ switch (m_previous.state) {
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the
+ // currently loaded modules.
+ case eConsistent:
+ return eTakeSnapshot;
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ case eAdd:
+ return eAddModules;
+ case eDelete:
+ return eRemoveModules;
+ }
+ break;
- // If we can't get the SO info from the remote, return failure.
- if (fromRemote && m_process->LoadModules(module_list) == 0)
- return false;
+ case eAdd:
+ case eDelete:
+ // Some versions of the android dynamic linker might send two
+ // notifications with state == eAdd back to back. Ignore them until we
+ // get an eConsistent notification.
+ if (!(m_previous.state == eConsistent ||
+ (m_previous.state == eAdd && m_current.state == eDelete)))
+ return eNoAction;
+
+ return eTakeSnapshot;
+ }
+
+ return eNoAction;
+}
+
+bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
+ auto action = GetAction();
- if (!fromRemote && m_current.map_addr == 0)
+ if (action == eNoAction)
return false;
- // When the previous and current states are consistent this is the first time
- // we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return fromRemote ? SaveSOEntriesFromRemote(module_list)
- : TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete) {
- // Some versions of the android dynamic linker might send two notifications
- // with state == eAdd back to back. Ignore them until we get an eConsistent
- // notification.
- if (!(m_previous.state == eConsistent ||
- (m_previous.state == eAdd && m_current.state == eDelete)))
- return false;
+ if (action == eTakeSnapshot) {
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ // We already have the loaded list from the previous update so no need to
+ // find all the modules again.
+ if (!m_loaded_modules.m_list.empty())
+ return true;
+ }
+
+ llvm::Expected<LoadedModuleInfoList> module_list =
+ m_process->GetLoadedModuleList();
+ if (!module_list) {
+ llvm::consumeError(module_list.takeError());
+ return false;
+ }
+ switch (action) {
+ case eTakeSnapshot:
m_soentries.clear();
- if (fromRemote)
- return SaveSOEntriesFromRemote(module_list);
+ return SaveSOEntriesFromRemote(*module_list);
+ case eAddModules:
+ return AddSOEntriesFromRemote(*module_list);
+ case eRemoveModules:
+ return RemoveSOEntriesFromRemote(*module_list);
+ case eNoAction:
+ return false;
+ }
+ llvm_unreachable("Fully covered switch above!");
+}
+bool DYLDRendezvous::UpdateSOEntries() {
+ switch (GetAction()) {
+ case eTakeSnapshot:
+ m_soentries.clear();
m_added_soentries.clear();
m_removed_soentries.clear();
return TakeSnapshot(m_soentries);
+ case eAddModules:
+ return AddSOEntries();
+ case eRemoveModules:
+ return RemoveSOEntries();
+ case eNoAction:
+ return false;
}
- assert(m_current.state == eConsistent);
-
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
- else if (m_previous.state == eDelete)
- return fromRemote ? RemoveSOEntriesFromRemote(module_list)
- : RemoveSOEntries();
-
- return false;
+ llvm_unreachable("Fully covered switch above!");
}
bool DYLDRendezvous::FillSOEntryFromModuleInfo(
@@ -255,7 +288,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo(
}
bool DYLDRendezvous::SaveSOEntriesFromRemote(
- LoadedModuleInfoList &module_list) {
+ const LoadedModuleInfoList &module_list) {
for (auto const &modInfo : module_list.m_list) {
SOEntry entry;
if (!FillSOEntryFromModuleInfo(modInfo, entry))
@@ -270,7 +303,8 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote(
return true;
}
-bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
+bool DYLDRendezvous::AddSOEntriesFromRemote(
+ const LoadedModuleInfoList &module_list) {
for (auto const &modInfo : module_list.m_list) {
bool found = false;
for (auto const &existing : m_loaded_modules.m_list) {
@@ -288,8 +322,10 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
return false;
// Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
+ if (!SOEntryIsMainExecutable(entry)) {
m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
+ }
}
m_loaded_modules = module_list;
@@ -297,7 +333,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
}
bool DYLDRendezvous::RemoveSOEntriesFromRemote(
- LoadedModuleInfoList &module_list) {
+ const LoadedModuleInfoList &module_list) {
for (auto const &existing : m_loaded_modules.m_list) {
bool found = false;
for (auto const &modInfo : module_list.m_list) {
@@ -321,6 +357,7 @@ bool DYLDRendezvous::RemoveSOEntriesFromRemote(
return false;
m_soentries.erase(pos);
+ m_removed_soentries.push_back(entry);
}
}
@@ -521,9 +558,10 @@ bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
Target &target = m_process->GetTarget();
SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
- eSymbolTypeAny, list))
- return false;
+ target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list);
+ if (list.IsEmpty())
+ return false;
Address address = list[0].symbol->GetAddress();
addr_t addr = address.GetLoadAddress(&target);
@@ -569,16 +607,16 @@ void DYLDRendezvous::DumpToLog(Log *log) const {
return;
log->PutCString("DYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent)
- ? "consistent"
- : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
- : "unknown");
+ LLDB_LOGF(log, " Address: %" PRIx64, GetRendezvousAddress());
+ LLDB_LOGF(log, " Version: %" PRIu64, GetVersion());
+ LLDB_LOGF(log, " Link : %" PRIx64, GetLinkMapAddress());
+ LLDB_LOGF(log, " Break : %" PRIx64, GetBreakAddress());
+ LLDB_LOGF(log, " LDBase : %" PRIx64, GetLDBase());
+ LLDB_LOGF(log, " State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add"
+ : (state == eDelete) ? "delete" : "unknown");
iterator I = begin();
iterator E = end();
@@ -587,11 +625,11 @@ void DYLDRendezvous::DumpToLog(Log *log) const {
log->PutCString("DYLDRendezvous SOEntries:");
for (int i = 1; I != E; ++I, ++i) {
- log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
+ LLDB_LOGF(log, "\n SOEntry [%d] %s", i, I->file_spec.GetCString());
+ LLDB_LOGF(log, " Base : %" PRIx64, I->base_addr);
+ LLDB_LOGF(log, " Path : %" PRIx64, I->path_addr);
+ LLDB_LOGF(log, " Dyn : %" PRIx64, I->dyn_addr);
+ LLDB_LOGF(log, " Next : %" PRIx64, I->next);
+ LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
}
}
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 993e62f5e9f9..536eeeaaf334 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -222,16 +222,20 @@ protected:
/// Updates the current set of SOEntries, the set of added entries, and the
/// set of removed entries.
- bool UpdateSOEntries(bool fromRemote = false);
+ bool UpdateSOEntries();
+
+ /// Same as UpdateSOEntries but it gets the list of loaded modules from the
+ /// remote debug server (faster when supported).
+ bool UpdateSOEntriesFromRemote();
bool FillSOEntryFromModuleInfo(
LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
- bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
- bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
- bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
bool AddSOEntries();
@@ -248,6 +252,17 @@ protected:
enum PThreadField { eSize, eNElem, eOffset };
bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
+
+ enum RendezvousAction {
+ eNoAction,
+ eTakeSnapshot,
+ eAddModules,
+ eRemoveModules
+ };
+
+ /// Returns the current action to be taken given the current and previous
+ /// state
+ RendezvousAction GetAction() const;
};
#endif
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index b55660899d0d..9d61c8feb923 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -85,32 +85,31 @@ DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
void DynamicLoaderPOSIXDYLD::DidAttach() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
- m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData());
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(
+ log, "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
+ __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
// ask the process if it can load any of its own modules
- m_process->LoadModules();
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
ModuleSP executable_sp = GetTargetExecutable();
ResolveExecutableModule(executable_sp);
// find the main process load offset
addr_t load_offset = ComputeLoadOffset();
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " executable '%s', load_offset 0x%" PRIx64,
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
- : "<null executable>",
- load_offset);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " executable '%s', load_offset 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
+ : "<null executable>",
+ load_offset);
EvalSpecialModulesStatus();
@@ -137,12 +136,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
ModuleList module_list;
module_list.Append(executable_sp);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " added executable '%s' to module load list",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- executable_sp->GetFileSpec().GetPath().c_str());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " added executable '%s' to module load list",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp->GetFileSpec().GetPath().c_str());
UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
true);
@@ -151,14 +150,15 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
m_process->GetTarget().ModulesDidLoad(module_list);
if (log) {
- log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
- "modules that loaded:",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s told the target about the "
+ "modules that loaded:",
+ __FUNCTION__);
for (auto module_sp : module_list.Modules()) {
- log->Printf("-- [module] %s (pid %" PRIu64 ")",
- module_sp ? module_sp->GetFileSpec().GetPath().c_str()
- : "<null>",
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "-- [module] %s (pid %" PRIu64 ")",
+ module_sp ? module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
}
}
}
@@ -174,13 +174,12 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
void DynamicLoaderPOSIXDYLD::DidLaunch() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
ModuleSP executable;
addr_t load_offset;
- m_auxv = llvm::make_unique<AuxVector>(m_process->GetAuxvData());
+ m_auxv = std::make_unique<AuxVector>(m_process->GetAuxvData());
executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
@@ -191,9 +190,8 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() {
module_list.Append(executable);
UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
- __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
+ __FUNCTION__);
if (!SetRendezvousBreakpoint()) {
// If we cannot establish rendezvous breakpoint right now we'll try again
@@ -227,22 +225,20 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() {
const addr_t entry = GetEntryPoint();
if (entry == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf(
- "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " GetEntryPoint() returned no address, not setting entry breakpoint",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned no address, not setting entry breakpoint",
+ __FUNCTION__, m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
return;
}
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " GetEntryPoint() returned address 0x%" PRIx64
- ", setting entry breakpoint",
- __FUNCTION__,
- m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
- entry);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned address 0x%" PRIx64
+ ", setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, entry);
if (m_process) {
Breakpoint *const entry_break =
@@ -271,11 +267,10 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
DynamicLoaderPOSIXDYLD *const dyld_instance =
static_cast<DynamicLoaderPOSIXDYLD *>(baton);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
// Disable the breakpoint --- if a stop happens right after this, which we've
// seen on occasion, we don't want the breakpoint stepping thread-plan logic
@@ -287,22 +282,22 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
BreakpointSP breakpoint_sp =
dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
if (breakpoint_sp) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " disabling breakpoint id %" PRIu64,
- __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " disabling breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
breakpoint_sp->SetEnabled(false);
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " failed to find breakpoint for breakpoint id %" PRIu64,
- __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " failed to find breakpoint for breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
}
} else {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
- " no Process instance! Cannot disable breakpoint",
- __FUNCTION__, break_id);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
+ " no Process instance! Cannot disable breakpoint",
+ __FUNCTION__, break_id);
}
dyld_instance->LoadAllCurrentModules();
@@ -393,23 +388,22 @@ bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
DynamicLoaderPOSIXDYLD *const dyld_instance =
static_cast<DynamicLoaderPOSIXDYLD *>(baton);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID);
+ LLDB_LOGF(log, "DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
dyld_instance->RefreshModules();
// Return true to stop the target, false to just let the target run.
const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
- " stop_when_images_change=%s",
- __FUNCTION__,
- dyld_instance->m_process ? dyld_instance->m_process->GetID()
- : LLDB_INVALID_PROCESS_ID,
- stop_when_images_change ? "true" : "false");
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " stop_when_images_change=%s",
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID,
+ stop_when_images_change ? "true" : "false");
return stop_when_images_change;
}
@@ -562,10 +556,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
LoadVDSO();
if (!m_rendezvous.Resolve()) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
- "rendezvous address",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
+ "rendezvous address",
+ __FUNCTION__);
return;
}
@@ -589,10 +583,10 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
module_list.Append(module_sp);
} else {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf(
- "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
+ __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
}
}
@@ -697,12 +691,12 @@ DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
- ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
- module_sp->GetObjectName().AsCString(""), link_map, tp,
- (int64_t)modid, tls_block);
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
+ module_sp->GetObjectName().AsCString(""), link_map, tp,
+ (int64_t)modid, tls_block);
if (tls_block == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
@@ -722,18 +716,17 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
ProcessInstanceInfo process_info;
if (!m_process->GetProcessInfo(process_info)) {
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
- "pid %" PRIu64,
- __FUNCTION__, m_process->GetID());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
+ "pid %" PRIu64,
+ __FUNCTION__, m_process->GetID());
return;
}
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
- ": %s",
- __FUNCTION__, m_process->GetID(),
- process_info.GetExecutableFile().GetPath().c_str());
+ LLDB_LOGF(
+ log, "DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
+ __FUNCTION__, m_process->GetID(),
+ process_info.GetExecutableFile().GetPath().c_str());
ModuleSpec module_spec(process_info.GetExecutableFile(),
process_info.GetArchitecture());
@@ -748,10 +741,10 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
StreamString stream;
module_spec.Dump(stream);
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
- "with module spec \"%s\": %s",
- __FUNCTION__, stream.GetData(), error.AsCString());
+ LLDB_LOGF(log,
+ "DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
+ "with module spec \"%s\": %s",
+ __FUNCTION__, stream.GetData(), error.AsCString());
return;
}
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index fa3fbe0d9fa6..25ab30e9db9c 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -122,38 +122,37 @@ lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
void DynamicLoaderWindowsDYLD::DidAttach() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
- ModuleSP executable = GetTargetExecutable();
+ ModuleSP executable = GetTargetExecutable();
- if (!executable.get())
- return;
+ if (!executable.get())
+ return;
- // Try to fetch the load address of the file from the process, since there
- // could be randomization of the load address.
- lldb::addr_t load_addr = GetLoadAddress(executable);
- if (load_addr == LLDB_INVALID_ADDRESS)
- return;
+ // Try to fetch the load address of the file from the process, since there
+ // could be randomization of the load address.
+ lldb::addr_t load_addr = GetLoadAddress(executable);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
- // Request the process base address.
- lldb::addr_t image_base = m_process->GetImageInfoAddress();
- if (image_base == load_addr)
- return;
+ // Request the process base address.
+ lldb::addr_t image_base = m_process->GetImageInfoAddress();
+ if (image_base == load_addr)
+ return;
- // Rebase the process's modules if there is a mismatch.
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
+ // Rebase the process's modules if there is a mismatch.
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_addr, false);
- ModuleList module_list;
- module_list.Append(executable);
- m_process->GetTarget().ModulesDidLoad(module_list);
- m_process->LoadModules();
+ ModuleList module_list;
+ module_list.Append(executable);
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}
void DynamicLoaderWindowsDYLD::DidLaunch() {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
ModuleSP executable = GetTargetExecutable();
if (!executable.get())
@@ -167,7 +166,8 @@ void DynamicLoaderWindowsDYLD::DidLaunch() {
ModuleList module_list;
module_list.Append(executable);
m_process->GetTarget().ModulesDidLoad(module_list);
- m_process->LoadModules();
+ auto error = m_process->LoadModules();
+ LLDB_LOG_ERROR(log, std::move(error), "failed to load modules: {0}");
}
}
diff --git a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
index 369f88327dd9..f33a713cc0b2 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTDumper.cpp
@@ -75,8 +75,6 @@ ASTDumper::ASTDumper(const CompilerType &compiler_type) {
const char *ASTDumper::GetCString() { return m_dump.c_str(); }
-void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); }
-
void ASTDumper::ToLog(Log *log, const char *prefix) {
size_t len = m_dump.length() + 1;
@@ -92,7 +90,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) {
while (end) {
*end = '\0';
- log->Printf("%s%s", prefix, str);
+ LLDB_LOGF(log, "%s%s", prefix, str);
*end = '\n';
@@ -100,9 +98,7 @@ void ASTDumper::ToLog(Log *log, const char *prefix) {
end = strchr(str, '\n');
}
- log->Printf("%s%s", prefix, str);
+ LLDB_LOGF(log, "%s%s", prefix, str);
free(alloc);
}
-
-void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); }
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 526ef90782ef..68eaad33f51c 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -58,13 +58,13 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) {
if (log && log->GetVerbose()) {
if (named_decl->getIdentifier())
- log->Printf("TransformTopLevelDecl(%s)",
- named_decl->getIdentifier()->getNameStart());
+ LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
+ named_decl->getIdentifier()->getNameStart());
else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
- log->Printf("TransformTopLevelDecl(%s)",
- method_decl->getSelector().getAsString().c_str());
+ LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
+ method_decl->getSelector().getAsString().c_str());
else
- log->Printf("TransformTopLevelDecl(<complex>)");
+ LLDB_LOGF(log, "TransformTopLevelDecl(<complex>)");
}
if (m_top_level) {
@@ -130,7 +130,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
os.flush();
- log->Printf("Untransformed function AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Untransformed function AST:\n%s", s.c_str());
}
Stmt *function_body = function_decl->getBody();
@@ -146,7 +146,7 @@ bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
os.flush();
- log->Printf("Transformed function AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Transformed function AST:\n%s", s.c_str());
}
return ret;
@@ -170,7 +170,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
os.flush();
- log->Printf("Untransformed method AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Untransformed method AST:\n%s", s.c_str());
}
Stmt *method_body = MethodDecl->getBody();
@@ -190,7 +190,7 @@ bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
os.flush();
- log->Printf("Transformed method AST:\n%s", s.c_str());
+ LLDB_LOGF(log, "Transformed method AST:\n%s", s.c_str());
}
return ret;
@@ -308,8 +308,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
if (log) {
std::string s = expr_qual_type.getAsString();
- log->Printf("Last statement is an %s with type: %s",
- (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
+ LLDB_LOGF(log, "Last statement is an %s with type: %s",
+ (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
}
clang::VarDecl *result_decl = nullptr;
@@ -422,8 +422,7 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) {
ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent type %s\n", name_cs.GetCString());
+ LLDB_LOGF(log, "Recording persistent type %s\n", name_cs.GetCString());
m_decls.push_back(D);
}
@@ -443,8 +442,7 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) {
ConstString name_cs(name.str().c_str());
- if (log)
- log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
+ LLDB_LOGF(log, "Recording persistent decl %s\n", name_cs.GetCString());
m_decls.push_back(D);
}
@@ -467,7 +465,7 @@ void ASTResultSynthesizer::CommitPersistentDecls() {
decl->dump(ss);
ss.flush();
- log->Printf("Couldn't commit persistent decl: %s\n", s.c_str());
+ LLDB_LOGF(log, "Couldn't commit persistent decl: %s\n", s.c_str());
}
continue;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index c5778f86bb62..372c2439ebf0 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -9,6 +9,7 @@
#include "ClangASTSource.h"
#include "ASTDumper.h"
+#include "ClangDeclVendor.h"
#include "ClangModulesDeclVendor.h"
#include "lldb/Core/Module.h"
@@ -18,7 +19,6 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
@@ -74,14 +74,19 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
file_manager};
std::vector<clang::ExternalASTMerger::ImporterSource> sources;
for (lldb::ModuleSP module_sp : m_target->GetImages().Modules()) {
- if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
- module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC))) {
+ auto type_system_or_err =
+ module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS),
+ std::move(err), "Failed to get ClangASTContext");
+ } else if (auto *module_ast_ctx = llvm::cast_or_null<ClangASTContext>(
+ &type_system_or_err.get())) {
lldbassert(module_ast_ctx->getASTContext());
lldbassert(module_ast_ctx->getFileManager());
- sources.push_back({*module_ast_ctx->getASTContext(),
- *module_ast_ctx->getFileManager(),
- module_ast_ctx->GetOriginMap()
- });
+ sources.emplace_back(*module_ast_ctx->getASTContext(),
+ *module_ast_ctx->getFileManager(),
+ module_ast_ctx->GetOriginMap());
}
}
@@ -96,17 +101,14 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
if (!language_runtime)
break;
- DeclVendor *runtime_decl_vendor = language_runtime->GetDeclVendor();
-
- if (!runtime_decl_vendor)
- break;
-
- sources.push_back(runtime_decl_vendor->GetImporterSource());
+ if (auto *runtime_decl_vendor = llvm::dyn_cast_or_null<ClangDeclVendor>(
+ language_runtime->GetDeclVendor())) {
+ sources.push_back(runtime_decl_vendor->GetImporterSource());
+ }
} while (false);
do {
- DeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor();
+ auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
if (!modules_decl_vendor)
break;
@@ -127,11 +129,9 @@ void ClangASTSource::InstallASTContext(clang::ASTContext &ast_context,
*scratch_ast_context->getFileManager(),
scratch_ast_context->GetOriginMap()});
}
- while (false)
- ;
m_merger_up =
- llvm::make_unique<clang::ExternalASTMerger>(target, sources);
+ std::make_unique<clang::ExternalASTMerger>(target, sources);
} else {
m_ast_importer_sp->InstallMapCompleter(&ast_context, *this);
}
@@ -273,13 +273,13 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
unsigned int current_id = invocation_id++;
if (log) {
- log->Printf(" 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_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());
- log->Printf(" CTD[%u] Before:", current_id);
+ LLDB_LOGF(log, " CTD[%u] Before:", current_id);
ASTDumper dumper((Decl *)tag_decl);
dumper.ToLog(log, " [CTD] ");
}
@@ -301,10 +301,10 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
// We couldn't complete the type. Maybe there's a definition somewhere
// else that can be completed.
- if (log)
- log->Printf(" CTD[%u] Type could not be completed in the module in "
- "which it was first found.",
- current_id);
+ LLDB_LOGF(log,
+ " CTD[%u] Type could not be completed in the module in "
+ "which it was first found.",
+ current_id);
bool found = false;
@@ -316,9 +316,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (log && log->GetVerbose())
- log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ 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()));
if (!namespace_map)
return;
@@ -326,10 +326,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e && !found; ++i) {
- if (log)
- log->Printf(" CTD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s",
+ current_id, i->second.GetName().AsCString(),
+ i->first->GetFileSpec().GetFilename().GetCString());
TypeList types;
@@ -409,7 +408,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
}
if (log) {
- log->Printf(" [CTD] After:");
+ LLDB_LOGF(log, " [CTD] After:");
ASTDumper dumper((Decl *)tag_decl);
dumper.ToLog(log, " [CTD] ");
}
@@ -419,11 +418,12 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
- log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
- "an ObjCInterfaceDecl named %s",
- static_cast<void *>(m_ast_context),
- interface_decl->getName().str().c_str());
- log->Printf(" [COID] Before:");
+ 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_LOGF(log, " [COID] Before:");
ASTDumper dumper((Decl *)interface_decl);
dumper.ToLog(log, " [COID] ");
}
@@ -467,7 +467,7 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
CompleteType(interface_decl->getSuperClass());
if (log) {
- log->Printf(" [COID] After:");
+ LLDB_LOGF(log, " [COID] After:");
ASTDumper dumper((Decl *)interface_decl);
dumper.ToLog(log, " [COID] ");
}
@@ -554,20 +554,22 @@ void ClangASTSource::FindExternalLexicalDecls(
if (log) {
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- log->Printf(
+ 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));
else if (context_decl)
- log->Printf(
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
+ 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));
else
- log->Printf(
+ LLDB_LOGF(
+ log,
"FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
current_id, static_cast<const void *>(m_ast_context));
}
@@ -580,9 +582,9 @@ void ClangASTSource::FindExternalLexicalDecls(
return;
if (log) {
- log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:",
- current_id, static_cast<void *>(original_ctx),
- static_cast<void *>(original_decl));
+ LLDB_LOGF(
+ log, " FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id,
+ static_cast<void *>(original_ctx), static_cast<void *>(original_decl));
ASTDumper(original_decl).ToLog(log, " ");
}
@@ -626,13 +628,13 @@ void ClangASTSource::FindExternalLexicalDecls(
ASTDumper ast_dumper(decl);
if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context_decl))
- log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
- current_id, context_named_decl->getDeclKindName(),
- context_named_decl->getNameAsString().c_str(),
- decl->getDeclKindName(), ast_dumper.GetCString());
+ 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_dumper.GetCString());
else
- log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id,
- decl->getDeclKindName(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id,
+ decl->getDeclKindName(), ast_dumper.GetCString());
}
Decl *copied_decl = CopyDecl(decl);
@@ -645,6 +647,20 @@ void ClangASTSource::FindExternalLexicalDecls(
m_ast_importer_sp->RequireCompleteType(copied_field_type);
}
+ auto decl_context_non_const = const_cast<DeclContext *>(decl_context);
+
+ // The decl ended up in the wrong DeclContext. Let's fix that so
+ // the decl we copied will actually be found.
+ // FIXME: This is a horrible hack that shouldn't be necessary. However
+ // it seems our current setup sometimes fails to copy decls to the right
+ // place. See rdar://55129537.
+ if (copied_decl->getDeclContext() != decl_context) {
+ assert(copied_decl->getDeclContext()->containsDecl(copied_decl));
+ copied_decl->getDeclContext()->removeDecl(copied_decl);
+ copied_decl->setDeclContext(decl_context_non_const);
+ assert(!decl_context_non_const->containsDecl(copied_decl));
+ decl_context_non_const->addDeclInternal(copied_decl);
+ }
} else {
SkippedDecls = true;
}
@@ -678,22 +694,25 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
if (log) {
if (!context.m_decl_context)
- log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a NULL DeclContext",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ 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());
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("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_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());
else
- log->Printf("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_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());
}
if (HasMerger() && !isa<TranslationUnitDecl>(context.m_decl_context)
@@ -723,9 +742,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
if (log && log->GetVerbose())
- log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ 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;
@@ -733,10 +752,9 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ 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);
}
@@ -748,8 +766,7 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
} else {
CompilerDeclContext namespace_decl;
- if (log)
- log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id);
FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
current_id);
@@ -757,10 +774,10 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
if (!context.m_namespace_map->empty()) {
if (log && log->GetVerbose())
- log->Printf(" 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_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()));
NamespaceDecl *clang_namespace_decl =
AddNamespace(context, context.m_namespace_map);
@@ -807,21 +824,17 @@ void ClangASTSource::FindExternalVisibleDecls(
if (module_sp && namespace_decl) {
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
-
- if (symbol_vendor) {
- found_namespace_decl =
- symbol_vendor->FindNamespace(name, &namespace_decl);
+ if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
+ found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
}
} else if (!HasMerger()) {
@@ -836,23 +849,21 @@ void ClangASTSource::FindExternalVisibleDecls(
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ SymbolFile *symbol_file = image->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
- found_namespace_decl =
- symbol_vendor->FindNamespace(name, &namespace_decl);
+ found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- if (log)
- log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
+ current_id, name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
}
}
@@ -878,9 +889,9 @@ void ClangASTSource::FindExternalVisibleDecls(
if (log) {
const char *name_string = type_sp->GetName().GetCString();
- log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id, name.GetCString(),
- (name_string ? name_string : "<anonymous>"));
+ LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s",
+ current_id, name.GetCString(),
+ (name_string ? name_string : "<anonymous>"));
}
CompilerType full_type = type_sp->GetFullCompilerType();
@@ -888,8 +899,8 @@ void ClangASTSource::FindExternalVisibleDecls(
CompilerType copied_clang_type(GuardedCopyType(full_type));
if (!copied_clang_type) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id);
+ LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type",
+ current_id);
continue;
}
@@ -915,9 +926,10 @@ void ClangASTSource::FindExternalVisibleDecls(
break;
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in "
- "the modules",
- current_id, name.GetCString());
+ 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];
@@ -930,10 +942,10 @@ void ClangASTSource::FindExternalVisibleDecls(
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl) {
- if (log)
- log->Printf(
- " CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
+ LLDB_LOGF(
+ log,
+ " CAS::FEVD[%u] - Couldn't export a type from the modules",
+ current_id);
break;
}
@@ -971,11 +983,13 @@ void ClangASTSource::FindExternalVisibleDecls(
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
break;
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
current_id, name.GetCString());
}
@@ -985,10 +999,9 @@ void ClangASTSource::FindExternalVisibleDecls(
copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
if (!copied_named_decl) {
- if (log)
- log->Printf(
- " CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a type from the runtime",
+ current_id);
break;
}
@@ -1126,8 +1139,8 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
if (log) {
ASTDumper dumper((Decl *)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOMD[%d] found (%s) %s", current_id, log_info,
+ dumper.GetCString());
}
context.AddNamedDecl(copied_method_decl);
@@ -1205,17 +1218,16 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString selector_name(ss.GetString());
- if (log)
- log->Printf("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_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());
SymbolContextList sc_list;
const bool include_symbols = false;
const bool include_inlines = false;
- const bool append = false;
std::string interface_name = interface_decl->getNameAsString();
@@ -1225,9 +1237,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ms.Flush();
ConstString instance_method_name(ms.GetString());
+ sc_list.Clear();
m_target->GetImages().FindFunctions(
instance_method_name, lldb::eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
if (sc_list.GetSize())
break;
@@ -1237,9 +1250,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ms.Flush();
ConstString class_method_name(ms.GetString());
+ sc_list.Clear();
m_target->GetImages().FindFunctions(
class_method_name, lldb::eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
if (sc_list.GetSize())
break;
@@ -1252,7 +1266,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
m_target->GetImages().FindFunctions(
selector_name, lldb::eFunctionNameTypeSelector, include_symbols,
- include_inlines, append, candidate_sc_list);
+ include_inlines, candidate_sc_list);
for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
SymbolContext candidate_sc;
@@ -1331,8 +1345,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (log) {
ASTDumper dumper((Decl *)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOMD[%d] found (in symbols) %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(copied_method_decl);
@@ -1360,11 +1374,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (complete_interface_decl == interface_decl)
break; // already checked this one
- if (log)
- log->Printf("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_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()));
FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
"in debug info");
@@ -1423,7 +1437,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches,
+ decls))
break;
ObjCInterfaceDecl *runtime_interface_decl =
@@ -1462,8 +1478,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (parser_property_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_property_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(parser_property_decl.decl);
@@ -1480,8 +1496,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
if (parser_ivar_decl.IsValid()) {
if (log) {
ASTDumper dumper((Decl *)parser_ivar_decl.decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id,
- dumper.GetCString());
+ LLDB_LOGF(log, " CAS::FOPD[%d] found %s", current_id,
+ dumper.GetCString());
}
context.AddNamedDecl(parser_ivar_decl.decl);
@@ -1505,23 +1521,23 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- if (log)
- log->Printf("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_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());
if (FindObjCPropertyAndIvarDeclsWithOrigin(
current_id, context, *this, origin_iface_decl))
return;
- if (log)
- log->Printf("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_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()));
SymbolContext null_sc;
TypeList type_list;
@@ -1542,12 +1558,11 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (complete_iface_decl.decl == origin_iface_decl.decl)
break; // already checked this one
- if (log)
- log->Printf("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_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()));
FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
complete_iface_decl);
@@ -1578,13 +1593,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_modules.IsValid())
break;
- if (log)
- log->Printf(
- "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_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()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
interface_decl_from_modules))
@@ -1614,7 +1628,8 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
uint32_t max_matches = 1;
std::vector<clang::NamedDecl *> decls;
- if (!decl_vendor->FindDecls(class_name, append, max_matches, decls))
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls))
break;
DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
@@ -1623,13 +1638,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_runtime.IsValid())
break;
- if (log)
- log->Printf(
- "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_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()));
if (FindObjCPropertyAndIvarDeclsWithOrigin(
current_id, context, *this, interface_decl_from_runtime))
@@ -1729,12 +1743,12 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("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_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());
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
@@ -1798,24 +1812,25 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
m_ast_context->getCharWidth();
if (log) {
- log->Printf("LRT[%u] returned:", current_id);
- log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id,
- static_cast<const void *>(origin_record.decl));
- log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
- log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
- log->Printf("LRT[%u] Fields:", current_id);
+ 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);
for (RecordDecl::field_iterator fi = record->field_begin(),
fe = record->field_end();
fi != fe; ++fi) {
- log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
- " bits",
- current_id, static_cast<void *>(*fi),
- fi->getNameAsString().c_str(), field_offsets[*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]);
}
DeclFromParser<const CXXRecordDecl> parser_cxx_record =
DynCast<const CXXRecordDecl>(parser_record);
if (parser_cxx_record.IsValid()) {
- log->Printf("LRT[%u] Bases:", current_id);
+ LLDB_LOGF(log, "LRT[%u] Bases:", current_id);
for (CXXRecordDecl::base_class_const_iterator
bi = parser_cxx_record->bases_begin(),
be = parser_cxx_record->bases_end();
@@ -1828,7 +1843,8 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
DeclFromParser<CXXRecordDecl> base_cxx_record =
DynCast<CXXRecordDecl>(base_record);
- log->Printf(
+ LLDB_LOGF(
+ log,
"LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64
" chars",
current_id, (is_virtual ? "Virtual " : ""),
@@ -1839,7 +1855,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
: base_offsets[base_cxx_record.decl].getQuantity()));
}
} else {
- log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
+ LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id);
}
}
@@ -1856,16 +1872,18 @@ void ClangASTSource::CompleteNamespaceMap(
if (log) {
if (parent_map && parent_map->size())
- log->Printf("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_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());
else
- log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOGF(log,
+ "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
+ "namespace %s",
+ current_id, static_cast<void *>(m_ast_context),
+ name.GetCString());
}
if (parent_map) {
@@ -1877,13 +1895,13 @@ void ClangASTSource::CompleteNamespaceMap(
lldb::ModuleSP module_sp = i->first;
CompilerDeclContext module_parent_namespace_decl = i->second;
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
+ SymbolFile *symbol_file = module_sp->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
found_namespace_decl =
- symbol_vendor->FindNamespace(name, &module_parent_namespace_decl);
+ symbol_file->FindNamespace(name, &module_parent_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1891,10 +1909,9 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
}
} else {
const ModuleList &target_images = m_target->GetImages();
@@ -1910,13 +1927,13 @@ void ClangASTSource::CompleteNamespaceMap(
CompilerDeclContext found_namespace_decl;
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+ SymbolFile *symbol_file = image->GetSymbolFile();
- if (!symbol_vendor)
+ if (!symbol_file)
continue;
found_namespace_decl =
- symbol_vendor->FindNamespace(name, &null_namespace_decl);
+ symbol_file->FindNamespace(name, &null_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1924,10 +1941,9 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- if (log)
- log->Printf(" CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
+ name.GetCString(),
+ image->GetFileSpec().GetFilename().GetCString());
}
}
}
@@ -2065,7 +2081,8 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
// seems to be generating bad types on occasion.
return CompilerType();
- return CompilerType(m_ast_context, copied_qual_type);
+ return CompilerType(ClangASTContext::GetASTContext(m_ast_context),
+ copied_qual_type.getAsOpaquePtr());
}
clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
@@ -2162,8 +2179,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Function type wasn't a FunctionProtoType");
+ LLDB_LOGF(log, "Function type wasn't a FunctionProtoType");
}
// If this is an operator (e.g. operator new or operator==), only insert the
@@ -2194,7 +2210,9 @@ clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
proto_info));
return AddFunDecl(
- CompilerType(m_ast_source.m_ast_context, generic_function_type), true);
+ CompilerType(ClangASTContext::GetASTContext(m_ast_source.m_ast_context),
+ generic_function_type.getAsOpaquePtr()),
+ true);
}
clang::NamedDecl *
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
new file mode 100644
index 000000000000..c59722b7b4f8
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
@@ -0,0 +1,30 @@
+//===-- ClangDeclVendor.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 "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Utility/ConstString.h"
+
+using namespace lldb_private;
+
+uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append,
+ uint32_t max_matches,
+ std::vector<CompilerDecl> &decls) {
+ if (!append)
+ decls.clear();
+
+ std::vector<clang::NamedDecl *> named_decls;
+ uint32_t ret = FindDecls(name, /*append*/ false, max_matches, named_decls);
+ for (auto *named_decl : named_decls) {
+ decls.push_back(CompilerDecl(
+ ClangASTContext::GetASTContext(&named_decl->getASTContext()),
+ named_decl));
+ }
+ return ret;
+}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
new file mode 100644
index 000000000000..90b715f37cba
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -0,0 +1,50 @@
+//===-- ClangDeclVendor.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_ClangDeclVendor_h_
+#define liblldb_ClangDeclVendor_h_
+
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/DeclVendor.h"
+
+#include "clang/AST/ExternalASTMerger.h"
+
+namespace lldb_private {
+
+// A clang specialized extension to DeclVendor.
+class ClangDeclVendor : public DeclVendor {
+public:
+ ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {}
+
+ virtual ~ClangDeclVendor() {}
+
+ /// Interface for ExternalASTMerger. Returns an ImporterSource allowing type
+ /// completion.
+ ///
+ /// \return
+ /// An ImporterSource for this ClangDeclVendor.
+ virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0;
+
+ uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
+ std::vector<CompilerDecl> &decls) override;
+
+ virtual uint32_t FindDecls(ConstString name, bool append,
+ uint32_t max_matches,
+ std::vector<clang::NamedDecl *> &decls) = 0;
+
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() >= eClangDeclVendor &&
+ vendor->GetKind() < eLastClangDeclVendor;
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor);
+};
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index db50c2aa3e90..48cd1c4b99fa 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -29,7 +29,7 @@ public:
return diag->getKind() == eDiagnosticOriginClang;
}
- ClangDiagnostic(const char *message, DiagnosticSeverity severity,
+ ClangDiagnostic(llvm::StringRef message, DiagnosticSeverity severity,
uint32_t compiler_id)
: Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id) {}
@@ -42,6 +42,7 @@ public:
}
const FixItList &FixIts() const { return m_fixit_vec; }
+private:
FixItList m_fixit_vec;
};
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index a49a7029e0d2..f4457fc1b740 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -180,98 +180,20 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
return ret;
}
-namespace {
-/// This class walks an AST and ensures that all DeclContexts defined inside the
-/// current source file are properly complete.
-///
-/// This is used to ensure that persistent types defined in the current source
-/// file migrate completely to the persistent AST context before they are
-/// reused. If that didn't happen, it would be impoossible to complete them
-/// because their origin would be gone.
-///
-/// The stragtegy used by this class is to check the SourceLocation (to be
-/// specific, the FileID) and see if it's the FileID for the current expression.
-/// Alternate strategies could include checking whether an ExternalASTMerger,
-/// set up to not have the current context as a source, can find an original for
-/// the type.
-class Completer : public clang::RecursiveASTVisitor<Completer> {
-private:
- clang::ASTImporter &m_exporter; /// Used to import Decl contents
- clang::FileID m_file; /// The file that's going away
- llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
-
- bool ImportAndCheckCompletable(clang::Decl *decl) {
- (void)m_exporter.Import(decl);
- if (m_completed.count(decl))
- return false;
- if (!llvm::isa<DeclContext>(decl))
- return false;
- const clang::SourceLocation loc = decl->getLocation();
- if (!loc.isValid())
- return false;
- const clang::FileID file =
- m_exporter.getFromContext().getSourceManager().getFileID(loc);
- if (file != m_file)
- return false;
- // We are assuming the Decl was parsed in this very expression, so it
- // should not have external storage.
- lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
- return true;
- }
-
- void Complete(clang::Decl *decl) {
- m_completed.insert(decl);
- auto *decl_context = llvm::cast<DeclContext>(decl);
- (void)m_exporter.Import(decl);
- m_exporter.CompleteDecl(decl);
- for (Decl *child : decl_context->decls())
- if (ImportAndCheckCompletable(child))
- Complete(child);
- }
-
- void MaybeComplete(clang::Decl *decl) {
- if (ImportAndCheckCompletable(decl))
- Complete(decl);
- }
-
-public:
- Completer(clang::ASTImporter &exporter, clang::FileID file)
- : m_exporter(exporter), m_file(file) {}
-
- // Implements the RecursiveASTVisitor's core API. It is called on each Decl
- // that the RecursiveASTVisitor encounters, and returns true if the traversal
- // should continue.
- bool VisitDecl(clang::Decl *decl) {
- MaybeComplete(decl);
- return true;
- }
-};
-}
-
-static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
- clang::FileID file,
- clang::QualType root) {
- clang::QualType canonical_type = root.getCanonicalType();
- if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
- Completer(exporter, file).TraverseDecl(tag_decl);
- } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
- canonical_type.getTypePtr())) {
- Completer(exporter, file).TraverseDecl(interface_type->getDecl());
- } else {
- Completer(exporter, file).TraverseType(canonical_type);
- }
-}
-
static clang::QualType ExportAllDeclaredTypes(
- clang::ExternalASTMerger &merger,
+ clang::ExternalASTMerger &parent_merger, clang::ExternalASTMerger &merger,
clang::ASTContext &source, clang::FileManager &source_file_manager,
const clang::ExternalASTMerger::OriginMap &source_origin_map,
clang::FileID file, clang::QualType root) {
- clang::ExternalASTMerger::ImporterSource importer_source =
- { source, source_file_manager, source_origin_map };
+ // Mark the source as temporary to make sure all declarations from the
+ // AST are exported. Also add the parent_merger as the merger into the
+ // source AST so that the merger can track back any declarations from
+ // the persistent ASTs we used as sources.
+ clang::ExternalASTMerger::ImporterSource importer_source(
+ source, source_file_manager, source_origin_map, /*Temporary*/ true,
+ &parent_merger);
merger.AddSources(importer_source);
clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
- CompleteAllDeclContexts(exporter, file, root);
llvm::Expected<clang::QualType> ret_or_error = exporter.Import(root);
merger.RemoveSources(importer_source);
if (ret_or_error) {
@@ -286,10 +208,10 @@ static clang::QualType ExportAllDeclaredTypes(
TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
ClangASTContext &source,
TypeFromParser parser_type) {
- assert (&target == m_target->GetScratchClangASTContext());
- assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
- assert (source.getASTContext() == m_ast_context);
-
+ assert(&target == m_target->GetScratchClangASTContext());
+ 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.getASTContext(), source.getASTContext(),
@@ -299,13 +221,12 @@ TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
clang::FileID source_file =
source.getASTContext()->getSourceManager().getFileID(
source.getASTContext()->getTranslationUnitDecl()->getLocation());
- auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
+ auto scratch_ast_context = static_cast<ClangASTContextForExpressions *>(
m_target->GetScratchClangASTContext());
clang::QualType exported_type = ExportAllDeclaredTypes(
- scratch_ast_context->GetMergerUnchecked(),
+ *m_merger_up.get(), scratch_ast_context->GetMergerUnchecked(),
*source.getASTContext(), *source.getFileManager(),
- m_merger_up->GetOrigins(),
- source_file,
+ m_merger_up->GetOrigins(), source_file,
clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
} else {
@@ -375,8 +296,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
- if (log)
- log->Printf("Persistent variable's type wasn't copied successfully");
+ LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully");
return false;
}
@@ -415,8 +335,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
- if (log)
- log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
+ LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags);
var->EnableParserVars(GetParserID());
@@ -458,10 +377,9 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!var)
return false;
- if (log)
- log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void *>(decl), name.GetCString(),
- var->GetName().GetCString());
+ LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ static_cast<const void *>(decl), name.GetCString(),
+ var->GetName().GetCString());
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
@@ -475,9 +393,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
// We already laid this out; do not touch
- if (log)
- log->Printf("Already placed at 0x%llx",
- (unsigned long long)jit_vars->m_offset);
+ LLDB_LOGF(log, "Already placed at 0x%llx",
+ (unsigned long long)jit_vars->m_offset);
}
llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
@@ -512,8 +429,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!err.Success())
return false;
- if (log)
- log->Printf("Placed at 0x%llx", (unsigned long long)offset);
+ LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset);
jit_vars->m_offset =
offset; // TODO DoStructLayout() should not change this.
@@ -779,7 +695,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (GetImportInProgress()) {
if (log && log->GetVerbose())
- log->Printf("Ignoring a query during an import");
+ LLDB_LOGF(log, "Ignoring a query during an import");
return;
}
@@ -788,20 +704,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
if (!context.m_decl_context)
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a NULL DeclContext",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a NULL DeclContext",
+ current_id, name.GetCString());
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in '%s'",
- current_id, name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in '%s'",
+ current_id, name.GetCString(),
+ context_named_decl->getNameAsString().c_str());
else
- log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a '%s'",
- current_id, name.GetCString(),
- context.m_decl_context->getDeclKindName());
+ LLDB_LOGF(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
+ "'%s' in a '%s'",
+ current_id, name.GetCString(),
+ context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context =
@@ -828,7 +747,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
current_id, static_cast<void *>(namespace_map.get()),
(int)namespace_map->size());
-
+
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
e = namespace_map->end();
i != e; ++i) {
@@ -848,7 +767,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
current_id);
}
-
+
ClangASTSource::FindExternalVisibleDecls(context);
}
@@ -922,9 +841,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
MaybeRegisterFunctionBody(parser_function_decl);
}
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
- name.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id,
+ name.GetCString());
context.AddNamedDecl(parser_named_decl);
} while (false);
@@ -979,8 +897,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(class_qual_type);
- log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddThisType(context, class_user_type, current_id);
@@ -1024,8 +942,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (pointee_type.IsValid()) {
if (log) {
ASTDumper ast_dumper(pointee_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddThisType(context, pointee_type, current_id);
@@ -1048,7 +966,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
return;
AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
- current_id);
+ current_id);
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -1096,8 +1014,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(interface_type);
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log, " FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
}
AddOneType(context, class_user_type, current_id);
@@ -1157,8 +1075,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (log) {
ASTDumper ast_dumper(self_type->GetFullCompilerType());
- log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
- current_id, ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " FEVD[%u] Adding type for $__lldb_objc_class: %s",
+ current_id, ast_dumper.GetCString());
}
TypeFromUser class_user_type(self_clang_type);
@@ -1222,9 +1141,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
reg_name));
if (reg_info) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
- reg_info->name);
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id,
+ reg_info->name);
AddOneRegister(context, reg_info, current_id);
}
@@ -1298,14 +1216,12 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
const bool include_inlines = false;
- const bool append = false;
-
+ sc_list.Clear();
if (namespace_decl && module_sp) {
const bool include_symbols = false;
module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
- include_symbols, include_inlines, append,
- sc_list);
+ include_symbols, include_inlines, sc_list);
} else if (target && !namespace_decl) {
const bool include_symbols = true;
@@ -1314,7 +1230,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
include_symbols, include_inlines,
- append, sc_list);
+ sc_list);
}
// If we found more than one function, see if we can use the frame's decl
@@ -1511,9 +1427,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching function found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Matching function found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
}
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
@@ -1522,10 +1439,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
: nullptr;
if (!copied_function_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
- "declaration from the modules",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a function "
+ "declaration from the modules",
+ current_id);
break;
}
@@ -1538,9 +1455,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
context.m_found.function = true;
} else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
if (log) {
- log->Printf(" CAS::FEVD[%u] Matching variable found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] Matching variable found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
}
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
@@ -1549,10 +1467,10 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
: nullptr;
if (!copied_var_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
- "declaration from the modules",
- current_id);
+ LLDB_LOGF(log,
+ " CAS::FEVD[%u] - Couldn't export a variable "
+ "declaration from the modules",
+ current_id);
break;
}
@@ -1647,8 +1565,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
const_value_extractor.GetByteSize());
var_location.SetValueType(Value::eValueTypeHostAddress);
} else {
- if (log)
- log->Printf("Error evaluating constant variable: %s", err.AsCString());
+ LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString());
return false;
}
}
@@ -1656,9 +1573,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
CompilerType type_to_use = GuardedCopyType(var_clang_type);
if (!type_to_use) {
- if (log)
- log->Printf(
- "Couldn't copy a variable's type into the parser's AST context");
+ LLDB_LOGF(log,
+ "Couldn't copy a variable's type into the parser's AST context");
return false;
}
@@ -1751,9 +1667,10 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (log) {
ASTDumper orig_dumper(ut.GetOpaqueQualType());
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
- current_id, decl_name.c_str(), ast_dumper.GetCString(),
- orig_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
+ current_id, decl_name.c_str(), ast_dumper.GetCString(),
+ orig_dumper.GetCString());
}
}
@@ -1768,9 +1685,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
TypeFromParser parser_type(GuardedCopyType(user_type));
if (!parser_type.GetOpaqueQualType()) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
- current_id, pvar_sp->GetName().GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s",
+ current_id, pvar_sp->GetName().GetCString());
return;
}
@@ -1789,8 +1705,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
- pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
+ pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
}
}
@@ -1848,8 +1764,8 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
- decl_name.c_str(), ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%u] Found variable %s, returned %s",
+ current_id, decl_name.c_str(), ast_dumper.GetCString());
}
}
@@ -1858,7 +1774,7 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
ClangASTContextForExpressions *scratch_ast_context =
- static_cast<ClangASTContextForExpressions*>(
+ static_cast<ClangASTContextForExpressions *>(
target->GetScratchClangASTContext());
for (size_t index = 0, num_entities = m_found_entities.GetSize();
@@ -1874,15 +1790,14 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
if (!var_decl) {
- if (log)
- log->Printf("Entity of unknown type does not have a VarDecl");
+ LLDB_LOGF(log, "Entity of unknown type does not have a VarDecl");
return false;
}
if (log) {
ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
- log->Printf("Variable of unknown type now has Decl %s",
- ast_dumper.GetCString());
+ LLDB_LOGF(log, "Variable of unknown type now has Decl %s",
+ ast_dumper.GetCString());
}
QualType var_type = var_decl->getType();
@@ -1897,18 +1812,17 @@ bool ClangExpressionDeclMap::ResolveUnknownTypes() {
var_type.getAsOpaquePtr());
} else if (HasMerger()) {
copied_type = CopyTypeWithMerger(
- var_decl->getASTContext(),
- scratch_ast_context->GetMergerUnchecked(),
- var_type).getAsOpaquePtr();
+ var_decl->getASTContext(),
+ scratch_ast_context->GetMergerUnchecked(), var_type)
+ .getAsOpaquePtr();
} else {
lldbassert(0 && "No mechanism to copy a resolved unknown type!");
return false;
}
if (!copied_type) {
- if (log)
- log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
- "import the type for a variable");
+ LLDB_LOGF(log, "ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
+ "import the type for a variable");
return (bool)lldb::ExpressionVariableSP();
}
@@ -1939,9 +1853,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
if (!clang_type) {
- if (log)
- log->Printf(" Tried to add a type for %s, but couldn't get one",
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one",
+ context.m_decl_name.getAsString().c_str());
return;
}
@@ -1969,9 +1882,9 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
if (log) {
ASTDumper ast_dumper(var_decl);
- log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
- context.m_decl_name.getAsString().c_str(),
- ast_dumper.GetCString());
+ LLDB_LOGF(log, " CEDM::FEVD[%d] Added register %s, returned %s",
+ current_id, context.m_decl_name.getAsString().c_str(),
+ ast_dumper.GetCString());
}
}
@@ -2016,24 +1929,24 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (copied_function_template) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_template);
-
+
StreamString ss;
-
+
function->DumpSymbolContext(&ss);
-
+
log->Printf(" CEDM::FEVD[%u] Imported decl for function template"
" %s (description %s), returned %s",
current_id,
copied_function_template->getNameAsString().c_str(),
ss.GetData(), ast_dumper.GetCString());
}
-
+
context.AddNamedDecl(copied_function_template);
}
} else if (src_function_decl) {
if (clang::FunctionDecl *copied_function_decl =
llvm::dyn_cast_or_null<clang::FunctionDecl>(
- CopyDecl(src_function_decl))) {
+ CopyDecl(src_function_decl))) {
if (log) {
ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
@@ -2041,19 +1954,20 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
- log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
- "(description %s), returned %s",
- current_id,
- copied_function_decl->getNameAsString().c_str(),
- ss.GetData(), ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::FEVD[%u] Imported decl for function %s "
+ "(description %s), returned %s",
+ current_id,
+ copied_function_decl->getNameAsString().c_str(),
+ ss.GetData(), ast_dumper.GetCString());
}
context.AddNamedDecl(copied_function_decl);
return;
} else {
if (log) {
- log->Printf(" Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
+ LLDB_LOGF(log, " Failed to import the function decl for '%s'",
+ src_function_decl->getName().str().c_str());
}
}
}
@@ -2082,7 +1996,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (!function_decl) {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
" Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
function_type->GetName().GetCString(), function_type->GetID());
}
@@ -2092,10 +2007,11 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
} else {
// We failed to copy the type we found
if (log) {
- log->Printf(" 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_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());
}
return;
@@ -2154,7 +2070,8 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
Address::DumpStyleResolvedDescription);
- log->Printf(
+ LLDB_LOGF(
+ log,
" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
current_id, (function ? "specific" : "generic"), decl_name.c_str(),
ss.GetData(), function_str.c_str());
@@ -2170,7 +2087,8 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
if (!copied_clang_type) {
if (log)
- log->Printf(
+ LLDB_LOGF(
+ log,
"ClangExpressionDeclMap::AddThisType - Couldn't import the type");
return;
@@ -2203,9 +2121,10 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
ASTDumper method_ast_dumper((clang::Decl *)method_decl);
ASTDumper type_ast_dumper(copied_clang_type);
- log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
- "(description %s) for this type %s",
- method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
+ LLDB_LOGF(log,
+ " CEDM::AddThisType Added function $__lldb_expr "
+ "(description %s) for this type %s",
+ method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
}
}
@@ -2244,8 +2163,8 @@ void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log)
- log->Printf(
- "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ LLDB_LOGF(
+ log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
return;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 03b73e6be391..2711e90726e7 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -356,7 +356,7 @@ private:
/// Activate parser-specific variables
void EnableParserVars() {
if (!m_parser_vars.get())
- m_parser_vars = llvm::make_unique<ParserVars>();
+ m_parser_vars = std::make_unique<ParserVars>();
}
/// Deallocate parser-specific variables
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7d13891ded8d..1422911d6546 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -105,16 +105,26 @@ using namespace lldb_private;
class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
ClangModulesDeclVendor &m_decl_vendor;
ClangPersistentVariables &m_persistent_vars;
+ clang::SourceManager &m_source_mgr;
StreamString m_error_stream;
bool m_has_errors = false;
public:
LLDBPreprocessorCallbacks(ClangModulesDeclVendor &decl_vendor,
- ClangPersistentVariables &persistent_vars)
- : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars) {}
+ ClangPersistentVariables &persistent_vars,
+ clang::SourceManager &source_mgr)
+ : m_decl_vendor(decl_vendor), m_persistent_vars(persistent_vars),
+ m_source_mgr(source_mgr) {}
void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
const clang::Module * /*null*/) override {
+ // Ignore modules that are imported in the wrapper code as these are not
+ // loaded by the user.
+ llvm::StringRef filename =
+ m_source_mgr.getPresumedLoc(import_location).getFilename();
+ if (filename == ClangExpressionSourceCode::g_prefix_file_name)
+ return;
+
SourceModule module;
for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
@@ -137,12 +147,14 @@ public:
class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
public:
- ClangDiagnosticManagerAdapter()
- : m_passthrough(new clang::TextDiagnosticBuffer) {}
-
- ClangDiagnosticManagerAdapter(
- const std::shared_ptr<clang::TextDiagnosticBuffer> &passthrough)
- : m_passthrough(passthrough) {}
+ 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));
+ }
void ResetManager(DiagnosticManager *manager = nullptr) {
m_manager = manager;
@@ -150,79 +162,92 @@ public:
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) override {
- if (m_manager) {
- llvm::SmallVector<char, 32> diag_str;
- Info.FormatDiagnostic(diag_str);
- diag_str.push_back('\0');
- const char *data = diag_str.data();
-
- lldb_private::DiagnosticSeverity severity;
- bool make_new_diagnostic = true;
-
- switch (DiagLevel) {
- case DiagnosticsEngine::Level::Fatal:
- case DiagnosticsEngine::Level::Error:
- severity = eDiagnosticSeverityError;
- break;
- case DiagnosticsEngine::Level::Warning:
- severity = eDiagnosticSeverityWarning;
- break;
- case DiagnosticsEngine::Level::Remark:
- case DiagnosticsEngine::Level::Ignored:
- severity = eDiagnosticSeverityRemark;
- break;
- case DiagnosticsEngine::Level::Note:
- m_manager->AppendMessageToDiagnostic(data);
- make_new_diagnostic = false;
- }
- if (make_new_diagnostic) {
- ClangDiagnostic *new_diagnostic =
- new ClangDiagnostic(data, severity, Info.getID());
- m_manager->AddDiagnostic(new_diagnostic);
-
- // Don't store away warning fixits, since the compiler doesn't have
- // 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 (!m_manager) {
+ // We have no DiagnosticManager before/after parsing but we still could
+ // receive diagnostics (e.g., by the ASTImporter failing to copy decls
+ // when we move the expression result ot the ScratchASTContext). Let's at
+ // least log these diagnostics until we find a way to properly render
+ // them and display them to the user.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ if (log) {
+ llvm::SmallVector<char, 32> diag_str;
+ Info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ const char *plain_diag = diag_str.data();
+ LLDB_LOG(log, "Received diagnostic outside parsing: {0}", plain_diag);
}
+ return;
}
+ // Render diagnostic message to m_output.
+ m_output.clear();
m_passthrough->HandleDiagnostic(DiagLevel, Info);
- }
+ m_os->flush();
- void FlushDiagnostics(DiagnosticsEngine &Diags) {
- m_passthrough->FlushDiagnostics(Diags);
- }
+ lldb_private::DiagnosticSeverity severity;
+ bool make_new_diagnostic = true;
+
+ switch (DiagLevel) {
+ case DiagnosticsEngine::Level::Fatal:
+ case DiagnosticsEngine::Level::Error:
+ severity = eDiagnosticSeverityError;
+ break;
+ case DiagnosticsEngine::Level::Warning:
+ severity = eDiagnosticSeverityWarning;
+ break;
+ case DiagnosticsEngine::Level::Remark:
+ case DiagnosticsEngine::Level::Ignored:
+ severity = eDiagnosticSeverityRemark;
+ break;
+ case DiagnosticsEngine::Level::Note:
+ m_manager->AppendMessageToDiagnostic(m_output);
+ make_new_diagnostic = false;
+ }
+ if (make_new_diagnostic) {
+ // ClangDiagnostic messages are expected to have no whitespace/newlines
+ // around them.
+ std::string stripped_output = llvm::StringRef(m_output).trim();
+
+ auto new_diagnostic = std::make_unique<ClangDiagnostic>(
+ stripped_output, severity, Info.getID());
+
+ // Don't store away warning fixits, since the compiler doesn't have
+ // 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);
+ }
+ }
- DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
- return new ClangDiagnosticManagerAdapter(m_passthrough);
+ m_manager->AddDiagnostic(std::move(new_diagnostic));
+ }
}
- clang::TextDiagnosticBuffer *GetPassthrough() { return m_passthrough.get(); }
+ clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); }
private:
DiagnosticManager *m_manager = nullptr;
- std::shared_ptr<clang::TextDiagnosticBuffer> m_passthrough;
+ std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough;
+ /// Output stream of m_passthrough.
+ std::shared_ptr<llvm::raw_string_ostream> m_os;
+ /// Output string filled by m_os.
+ std::string m_output;
};
-static void
-SetupModuleHeaderPaths(CompilerInstance *compiler,
- std::vector<ConstString> include_directories,
- lldb::TargetSP target_sp) {
+static void SetupModuleHeaderPaths(CompilerInstance *compiler,
+ std::vector<std::string> include_directories,
+ lldb::TargetSP target_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
HeaderSearchOptions &search_opts = compiler->getHeaderSearchOpts();
- for (ConstString dir : include_directories) {
- search_opts.AddPath(dir.AsCString(), frontend::System, false, true);
+ for (const std::string &dir : include_directories) {
+ search_opts.AddPath(dir, frontend::System, false, true);
LLDB_LOG(log, "Added user include dir: {0}", dir);
}
@@ -232,27 +257,9 @@ SetupModuleHeaderPaths(CompilerInstance *compiler,
search_opts.ModuleCachePath = module_cache.str();
LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str());
- FileSpec clang_resource_dir = GetClangResourceDir();
- std::string resource_dir = clang_resource_dir.GetPath();
- if (FileSystem::Instance().IsDirectory(resource_dir)) {
- search_opts.ResourceDir = resource_dir;
- std::string resource_include = resource_dir + "/include";
- search_opts.AddPath(resource_include, frontend::System, false, true);
-
- LLDB_LOG(log, "Added resource include dir: {0}", resource_include);
- }
+ search_opts.ResourceDir = GetClangResourceDir().GetPath();
search_opts.ImplicitModuleMaps = true;
-
- std::vector<std::string> system_include_directories =
- target_sp->GetPlatform()->GetSystemIncludeDirectories(
- lldb::eLanguageTypeC_plus_plus);
-
- for (const std::string &include_dir : system_include_directories) {
- search_opts.AddPath(include_dir, frontend::System, false, true);
-
- LLDB_LOG(log, "Added system include dir: {0}", include_dir);
- }
}
//===----------------------------------------------------------------------===//
@@ -261,10 +268,12 @@ SetupModuleHeaderPaths(CompilerInstance *compiler,
ClangExpressionParser::ClangExpressionParser(
ExecutionContextScope *exe_scope, Expression &expr,
- bool generate_debug_info, std::vector<ConstString> include_directories)
+ bool generate_debug_info, std::vector<std::string> include_directories,
+ std::string filename)
: ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(),
m_pp_callbacks(nullptr),
- m_include_directories(std::move(include_directories)) {
+ m_include_directories(std::move(include_directories)),
+ m_filename(std::move(filename)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
// We can't compile expressions without a target. So if the exe_scope is
@@ -331,9 +340,8 @@ ClangExpressionParser::ClangExpressionParser(
if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) {
lang_rt = process_sp->GetLanguageRuntime(frame_lang);
- if (log)
- log->Printf("Frame has language of type %s",
- Language::GetNameForLanguageType(frame_lang));
+ LLDB_LOGF(log, "Frame has language of type %s",
+ Language::GetNameForLanguageType(frame_lang));
}
// 2. Configure the compiler with a set of default options that are
@@ -341,9 +349,8 @@ ClangExpressionParser::ClangExpressionParser(
if (target_arch.IsValid()) {
std::string triple = target_arch.GetTriple().str();
m_compiler->getTargetOpts().Triple = triple;
- if (log)
- log->Printf("Using %s as the target triple",
- m_compiler->getTargetOpts().Triple.c_str());
+ LLDB_LOGF(log, "Using %s as the target triple",
+ m_compiler->getTargetOpts().Triple.c_str());
} else {
// If we get here we don't have a valid target and just have to guess.
// Sometimes this will be ok to just use the host target triple (when we
@@ -352,9 +359,8 @@ ClangExpressionParser::ClangExpressionParser(
// the host triple. In such a case the language runtime should expose an
// overridden options set (3), below.
m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
- if (log)
- log->Printf("Using default target triple of %s",
- m_compiler->getTargetOpts().Triple.c_str());
+ LLDB_LOGF(log, "Using default target triple of %s",
+ m_compiler->getTargetOpts().Triple.c_str());
}
// Now add some special fixes for known architectures: Any arm32 iOS
// environment, but not on arm64
@@ -408,12 +414,13 @@ ClangExpressionParser::ClangExpressionParser(
auto target_info = TargetInfo::CreateTargetInfo(
m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
if (log) {
- log->Printf("Using SIMD alignment: %d", target_info->getSimdDefaultAlign());
- log->Printf("Target datalayout string: '%s'",
- target_info->getDataLayout().getStringRepresentation().c_str());
- log->Printf("Target ABI: '%s'", target_info->getABI().str().c_str());
- log->Printf("Target vector alignment: %d",
- target_info->getMaxVectorAlign());
+ LLDB_LOGF(log, "Using SIMD alignment: %d",
+ target_info->getSimdDefaultAlign());
+ LLDB_LOGF(log, "Target datalayout string: '%s'",
+ target_info->getDataLayout().getStringRepresentation().c_str());
+ LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str());
+ LLDB_LOGF(log, "Target vector alignment: %d",
+ target_info->getMaxVectorAlign());
}
m_compiler->setTarget(target_info);
@@ -508,6 +515,9 @@ ClangExpressionParser::ClangExpressionParser(
lang_opts.DoubleSquareBracketAttributes = true;
lang_opts.CPlusPlus11 = true;
+ // The Darwin libc expects this macro to be set.
+ lang_opts.GNUCVersion = 40201;
+
SetupModuleHeaderPaths(m_compiler.get(), m_include_directories,
target_sp);
}
@@ -537,8 +547,8 @@ ClangExpressionParser::ClangExpressionParser(
// Set CodeGen options
m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
m_compiler->getCodeGenOpts().InstrumentFunctions = false;
- m_compiler->getCodeGenOpts().DisableFPElim = true;
- m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
+ m_compiler->getCodeGenOpts().setFramePointer(
+ CodeGenOptions::FramePointerKind::All);
if (generate_debug_info)
m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
else
@@ -560,7 +570,9 @@ ClangExpressionParser::ClangExpressionParser(
// 6. Set up the diagnostic buffer for reporting errors
- m_compiler->getDiagnostics().setClient(new ClangDiagnosticManagerAdapter);
+ auto diag_mgr = new ClangDiagnosticManagerAdapter(
+ m_compiler->getDiagnostics().getDiagnosticOptions());
+ m_compiler->getDiagnostics().setClient(diag_mgr);
// 7. Set up the source management objects inside the compiler
m_compiler->createFileManager();
@@ -574,8 +586,8 @@ ClangExpressionParser::ClangExpressionParser(
llvm::cast<ClangPersistentVariables>(
target_sp->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC));
- std::unique_ptr<PPCallbacks> pp_callbacks(
- new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars));
+ std::unique_ptr<PPCallbacks> pp_callbacks(new LLDBPreprocessorCallbacks(
+ *decl_vendor, *clang_persistent_vars, m_compiler->getSourceManager()));
m_pp_callbacks =
static_cast<LLDBPreprocessorCallbacks *>(pp_callbacks.get());
m_compiler->getPreprocessor().addPPCallbacks(std::move(pp_callbacks));
@@ -592,9 +604,7 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->createASTContext();
clang::ASTContext &ast_context = m_compiler->getASTContext();
- m_ast_context.reset(
- new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str()));
- m_ast_context->setASTContext(&ast_context);
+ m_ast_context.reset(new ClangASTContext(ast_context));
std::string module_name("$__lldb_module");
@@ -872,8 +882,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
ClangDiagnosticManagerAdapter *adapter =
static_cast<ClangDiagnosticManagerAdapter *>(
m_compiler->getDiagnostics().getClient());
- clang::TextDiagnosticBuffer *diag_buf = adapter->GetPassthrough();
- diag_buf->FlushDiagnostics(m_compiler->getDiagnostics());
+ auto diag_buf = adapter->GetPassthrough();
adapter->ResetManager(&diagnostic_manager);
@@ -904,16 +913,19 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
}
if (temp_fd != -1) {
- lldb_private::File file(temp_fd, true);
+ lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true);
const size_t expr_text_len = strlen(expr_text);
size_t bytes_written = expr_text_len;
if (file.Write(expr_text, bytes_written).Success()) {
if (bytes_written == expr_text_len) {
file.Close();
- source_mgr.setMainFileID(source_mgr.createFileID(
- m_compiler->getFileManager().getFile(result_path),
- SourceLocation(), SrcMgr::C_User));
- created_main_file = true;
+ if (auto fileEntry =
+ m_compiler->getFileManager().getFile(result_path)) {
+ source_mgr.setMainFileID(source_mgr.createFileID(
+ *fileEntry,
+ SourceLocation(), SrcMgr::C_User));
+ created_main_file = true;
+ }
}
}
}
@@ -921,7 +933,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
if (!created_main_file) {
std::unique_ptr<MemoryBuffer> memory_buffer =
- MemoryBuffer::getMemBufferCopy(expr_text, "<lldb-expr>");
+ MemoryBuffer::getMemBufferCopy(expr_text, m_filename);
source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
}
@@ -1092,8 +1104,8 @@ bool ClangExpressionParser::RewriteExpression(
if (num_diags == 0)
return false;
- for (const Diagnostic *diag : diagnostic_manager.Diagnostics()) {
- const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
+ 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.
@@ -1181,9 +1193,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
m_expr.FunctionName());
return err;
} else {
- if (log)
- log->Printf("Found function %s for %s", function_name.AsCString(),
- m_expr.FunctionName());
+ LLDB_LOGF(log, "Found function %s for %s", function_name.AsCString(),
+ m_expr.FunctionName());
}
}
@@ -1198,9 +1209,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
LLVMUserExpression::IRPasses custom_passes;
{
auto lang = m_expr.Language();
- if (log)
- log->Printf("%s - Current expression language is %s\n", __FUNCTION__,
- Language::GetNameForLanguageType(lang));
+ LLDB_LOGF(log, "%s - Current expression language is %s\n", __FUNCTION__,
+ Language::GetNameForLanguageType(lang));
lldb::ProcessSP process_sp = exe_ctx.GetProcessSP();
if (process_sp && lang != lldb::eLanguageTypeUnknown) {
auto runtime = process_sp->GetLanguageRuntime(lang);
@@ -1210,10 +1220,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
}
if (custom_passes.EarlyPasses) {
- if (log)
- log->Printf("%s - Running Early IR Passes from LanguageRuntime on "
- "expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
+ LLDB_LOGF(log,
+ "%s - Running Early IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
custom_passes.EarlyPasses->run(*llvm_module_up);
}
@@ -1230,12 +1240,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
type_system_helper->DeclMap(); // result can be NULL
if (decl_map) {
- Stream *error_stream = nullptr;
Target *target = exe_ctx.GetTargetPtr();
- error_stream = target->GetDebugger().GetErrorFile().get();
-
+ auto &error_stream = target->GetDebugger().GetErrorStream();
IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
- *execution_unit_sp, *error_stream,
+ *execution_unit_sp, error_stream,
function_name.AsCString());
bool ir_can_run =
@@ -1298,9 +1306,8 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
process->SetDynamicCheckers(dynamic_checkers);
- if (log)
- log->Printf("== [ClangExpressionParser::PrepareForExecution] "
- "Finished installing dynamic checkers ==");
+ LLDB_LOGF(log, "== [ClangExpressionParser::PrepareForExecution] "
+ "Finished installing dynamic checkers ==");
}
if (auto *checker_funcs = llvm::dyn_cast<ClangDynamicCheckerFunctions>(
@@ -1316,10 +1323,10 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
}
if (custom_passes.LatePasses) {
- if (log)
- log->Printf("%s - Running Late IR Passes from LanguageRuntime on "
- "expression module '%s'",
- __FUNCTION__, m_expr.FunctionName());
+ LLDB_LOGF(log,
+ "%s - Running Late IR Passes from LanguageRuntime on "
+ "expression module '%s'",
+ __FUNCTION__, m_expr.FunctionName());
custom_passes.LatePasses->run(*module);
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index a42c2190ffb8..79ad5728bf74 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -53,9 +53,14 @@ public:
/// @param[in] include_directories
/// List of include directories that should be used when parsing the
/// expression.
+ ///
+ /// @param[in] filename
+ /// Name of the source file that should be used when rendering
+ /// diagnostics (i.e. errors, warnings or notes from Clang).
ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr,
bool generate_debug_info,
- std::vector<ConstString> include_directories = {});
+ std::vector<std::string> include_directories = {},
+ std::string filename = "<clang expression>");
/// Destructor
~ClangExpressionParser() override;
@@ -177,7 +182,9 @@ private:
///encounters module imports
std::unique_ptr<ClangASTContext> m_ast_context;
- std::vector<ConstString> m_include_directories;
+ std::vector<std::string> m_include_directories;
+ /// File name used for the user expression.
+ std::string m_filename;
};
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index f513b1eea360..21cb33402e7f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -29,7 +29,15 @@
using namespace lldb_private;
-const char *ClangExpressionSourceCode::g_expression_prefix = R"(
+#define PREFIX_NAME "<lldb wrapper prefix>"
+
+const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME;
+
+const char *ClangExpressionSourceCode::g_expression_prefix =
+"#line 1 \"" PREFIX_NAME R"("
+#ifndef offsetof
+#define offsetof(t, d) __builtin_offsetof(t, d)
+#endif
#ifndef NULL
#define NULL (__null)
#endif
@@ -64,9 +72,6 @@ extern "C"
}
)";
-static const char *c_start_marker = " /*LLDB_BODY_START*/\n ";
-static const char *c_end_marker = ";\n /*LLDB_BODY_END*/\n";
-
namespace {
class AddMacroState {
@@ -166,6 +171,17 @@ 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) {
+ // 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.
+ m_start_marker = "#line 1 \"" + filename.str() + "\"\n";
+ m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n";
+}
+
namespace {
/// Allows checking if a token is contained in a given expression.
class TokenVerifier {
@@ -286,7 +302,8 @@ bool ClangExpressionSourceCode::GetText(
Target *target = exe_ctx.GetTargetPtr();
if (target) {
- if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64) {
+ if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 ||
+ target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) {
target_specific_defines = "typedef bool BOOL;\n";
}
if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) {
@@ -398,9 +415,9 @@ bool ClangExpressionSourceCode::GetText(
case lldb::eLanguageTypeC:
case lldb::eLanguageTypeC_plus_plus:
case lldb::eLanguageTypeObjC:
- tagged_body.append(c_start_marker);
+ tagged_body.append(m_start_marker);
tagged_body.append(m_body);
- tagged_body.append(c_end_marker);
+ tagged_body.append(m_end_marker);
break;
}
switch (wrapping_language) {
@@ -474,24 +491,19 @@ bool ClangExpressionSourceCode::GetText(
bool ClangExpressionSourceCode::GetOriginalBodyBounds(
std::string transformed_text, lldb::LanguageType wrapping_language,
size_t &start_loc, size_t &end_loc) {
- const char *start_marker;
- const char *end_marker;
-
switch (wrapping_language) {
default:
return false;
case lldb::eLanguageTypeC:
case lldb::eLanguageTypeC_plus_plus:
case lldb::eLanguageTypeObjC:
- start_marker = c_start_marker;
- end_marker = c_end_marker;
break;
}
- start_loc = transformed_text.find(start_marker);
+ start_loc = transformed_text.find(m_start_marker);
if (start_loc == std::string::npos)
return false;
- start_loc += strlen(start_marker);
- end_loc = transformed_text.find(end_marker);
+ start_loc += m_start_marker.size();
+ end_loc = transformed_text.find(m_end_marker);
return end_loc != std::string::npos;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 894290295837..1d159670b962 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -23,15 +23,18 @@ class ExecutionContext;
class ClangExpressionSourceCode : public ExpressionSourceCode {
public:
+ /// The file name we use for the wrapper code that we inject before
+ /// the user expression.
+ static const llvm::StringRef g_prefix_file_name;
static const char *g_expression_prefix;
- static ClangExpressionSourceCode *CreateWrapped(const char *prefix,
- const char *body) {
- return new ClangExpressionSourceCode("$__lldb_expr", prefix, body, true);
+ static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename,
+ llvm::StringRef prefix,
+ llvm::StringRef body) {
+ return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body,
+ Wrap);
}
- uint32_t GetNumBodyLines();
-
/// Generates the source code that will evaluate the expression.
///
/// \param text output parameter containing the source code string.
@@ -56,14 +59,20 @@ public:
// Given a string returned by GetText, find the beginning and end of the body
// passed to CreateWrapped. Return true if the bounds could be found. This
// will also work on text with FixItHints applied.
- static bool GetOriginalBodyBounds(std::string transformed_text,
- lldb::LanguageType wrapping_language,
- size_t &start_loc, size_t &end_loc);
+ bool GetOriginalBodyBounds(std::string transformed_text,
+ lldb::LanguageType wrapping_language,
+ size_t &start_loc, size_t &end_loc);
protected:
- ClangExpressionSourceCode(const char *name, const char *prefix, const char *body,
- bool wrap) :
- ExpressionSourceCode(name, prefix, body, wrap) {}
+ ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name,
+ llvm::StringRef prefix, llvm::StringRef body,
+ Wrapping wrap);
+
+private:
+ /// 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;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index eabc96aa8e51..8fbfa6e47578 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -179,8 +179,7 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
m_wrapper_function_text.append(");\n}\n");
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
+ LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
// Okay, now compile this expression
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 65c547391831..42d3f22014dd 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -30,10 +30,10 @@ static bool VerifyClangPath(const llvm::Twine &clang_path) {
if (FileSystem::Instance().IsDirectory(clang_path))
return true;
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("VerifyClangPath(): "
- "failed to stat clang resource directory at \"%s\"",
- clang_path.str().c_str());
+ LLDB_LOGF(log,
+ "VerifyClangPath(): "
+ "failed to stat clang resource directory at \"%s\"",
+ clang_path.str().c_str());
return false;
}
@@ -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)) {
- if (log)
- log->Printf("DefaultComputeClangResourceDir: Setting ClangResourceDir "
- "to \"%s\", verify = %s",
- clang_dir.str().str().c_str(), verify ? "true" : "false");
+ LLDB_LOGF(log,
+ "DefaultComputeClangResourceDir: Setting ClangResourceDir "
+ "to \"%s\", verify = %s",
+ clang_dir.str().str().c_str(), verify ? "true" : "false");
file_spec.GetDirectory().SetString(clang_dir);
FileSystem::Instance().Resolve(file_spec);
return true;
@@ -160,9 +160,8 @@ FileSpec lldb_private::GetClangResourceDir() {
ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir,
true);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("GetClangResourceDir() => '%s'",
- g_cached_resource_dir.GetPath().c_str());
+ LLDB_LOGF(log, "GetClangResourceDir() => '%s'",
+ g_cached_resource_dir.GetPath().c_str());
});
return g_cached_resource_dir;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 4a220790e50d..f3df589d7311 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -27,6 +27,7 @@
#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"
@@ -110,6 +111,9 @@ private:
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
const clang::ExternalASTMerger::OriginMap m_origin_map;
+ // 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;
};
} // anonymous namespace
@@ -143,7 +147,8 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
}
}
-ClangModulesDeclVendor::ClangModulesDeclVendor() {}
+ClangModulesDeclVendor::ClangModulesDeclVendor()
+ : ClangDeclVendor(eClangModuleDeclVendor) {}
ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
@@ -155,7 +160,11 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
: m_diagnostics_engine(std::move(diagnostics_engine)),
m_compiler_invocation(std::move(compiler_invocation)),
m_compiler_instance(std::move(compiler_instance)),
- m_parser(std::move(parser)), m_origin_map() {}
+ m_parser(std::move(parser)), m_origin_map() {
+
+ // Initialize our ClangASTContext.
+ m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext()));
+}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -237,11 +246,11 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
bool is_system = true;
bool is_framework = false;
- auto *dir =
+ auto dir =
HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
if (!dir)
return error();
- auto *file = HS.lookupModuleMapFile(dir, is_framework);
+ auto *file = HS.lookupModuleMapFile(*dir, is_framework);
if (!file)
return error();
if (!HS.loadModuleMapFile(file, is_system))
@@ -562,8 +571,9 @@ ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,
clang::ExternalASTMerger::ImporterSource
ClangModulesDeclVendorImpl::GetImporterSource() {
- return {m_compiler_instance->getASTContext(),
- m_compiler_instance->getFileManager(), m_origin_map};
+ return clang::ExternalASTMerger::ImporterSource(
+ m_compiler_instance->getASTContext(),
+ m_compiler_instance->getFileManager(), m_origin_map);
}
static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index d5c8757bdcd0..e099b59041d8 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -10,22 +10,27 @@
#define liblldb_ClangModulesDeclVendor_h
#include "lldb/Core/ClangForward.h"
-#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Platform.h"
+#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+
#include <set>
#include <vector>
namespace lldb_private {
-class ClangModulesDeclVendor : public DeclVendor {
+class ClangModulesDeclVendor : public ClangDeclVendor {
public:
// Constructors and Destructors
ClangModulesDeclVendor();
~ClangModulesDeclVendor() override;
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() == eClangModuleDeclVendor;
+ }
+
static ClangModulesDeclVendor *Create(Target &target);
typedef std::vector<ConstString> ModulePath;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 742a14992dc9..24dd705e37b1 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -23,8 +23,7 @@ using namespace lldb;
using namespace lldb_private;
ClangPersistentVariables::ClangPersistentVariables()
- : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
- m_next_persistent_variable_id(0) {}
+ : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {}
ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
const lldb::ValueObjectSP &valobj_sp) {
@@ -43,13 +42,25 @@ void ClangPersistentVariables::RemovePersistentVariable(
lldb::ExpressionVariableSP variable) {
RemoveVariable(variable);
- const char *name = variable->GetName().AsCString();
+ // Check if the removed variable was the last one that was created. If yes,
+ // reuse the variable id for the next variable.
- if (*name != '$')
+ // Nothing to do if we have not assigned a variable id so far.
+ if (m_next_persistent_variable_id == 0)
return;
- name++;
- if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
+ llvm::StringRef name = variable->GetName().GetStringRef();
+ // Remove the prefix from the variable that only the indes is left.
+ if (!name.consume_front(GetPersistentVariablePrefix(false)))
+ return;
+
+ // Check if the variable contained a variable id.
+ uint32_t variable_id;
+ if (name.getAsInteger(10, variable_id))
+ return;
+ // If it's the most recent variable id that was assigned, make sure that this
+ // variable id will be used for the next persistent variable.
+ if (variable_id == m_next_persistent_variable_id - 1)
m_next_persistent_variable_id--;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index b39f89ad7eef..95e6c3ac963d 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -45,11 +45,20 @@ public:
uint32_t addr_byte_size) override;
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- llvm::StringRef
- GetPersistentVariablePrefix(bool is_error) const override {
+
+ llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override {
return "$";
}
+ /// Returns the next file name that should be used for user expressions.
+ std::string GetNextExprFileName() {
+ std::string name;
+ name.append("<user expression ");
+ name.append(std::to_string(m_next_user_file_id++));
+ name.append(">");
+ return name;
+ }
+
llvm::Optional<CompilerType>
GetCompilerTypeFromPersistentDecl(ConstString type_name) override;
@@ -66,8 +75,10 @@ public:
}
private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by
- ///GetNextResultName().
+ /// The counter used by GetNextExprFileName.
+ uint32_t m_next_user_file_id = 0;
+ // The counter used by GetNextPersistentVariableName
+ uint32_t m_next_persistent_variable_id = 0;
typedef llvm::DenseMap<const char *, clang::NamedDecl *> PersistentDeclMap;
PersistentDeclMap
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2dae5b7022f3..da1ca785635c 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -21,9 +23,9 @@
#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
-#include "ClangExpressionSourceCode.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
+#include "CppModuleConfiguration.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -90,21 +92,18 @@ ClangUserExpression::~ClangUserExpression() {}
void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("ClangUserExpression::ScanContext()");
+ LLDB_LOGF(log, "ClangUserExpression::ScanContext()");
m_target = exe_ctx.GetTargetPtr();
if (!(m_allow_cxx || m_allow_objc)) {
- if (log)
- log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
+ LLDB_LOGF(log, " [CUE::SC] Settings inhibit C++ and Objective-C");
return;
}
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == nullptr) {
- if (log)
- log->Printf(" [CUE::SC] Null stack frame");
+ LLDB_LOGF(log, " [CUE::SC] Null stack frame");
return;
}
@@ -112,8 +111,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
lldb::eSymbolContextBlock);
if (!sym_ctx.function) {
- if (log)
- log->Printf(" [CUE::SC] Null function");
+ LLDB_LOGF(log, " [CUE::SC] Null function");
return;
}
@@ -121,16 +119,14 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Block *function_block = sym_ctx.GetFunctionBlock();
if (!function_block) {
- if (log)
- log->Printf(" [CUE::SC] Null function block");
+ LLDB_LOGF(log, " [CUE::SC] Null function block");
return;
}
CompilerDeclContext decl_context = function_block->GetDeclContext();
if (!decl_context) {
- if (log)
- log->Printf(" [CUE::SC] Null decl context");
+ LLDB_LOGF(log, " [CUE::SC] Null decl context");
return;
}
@@ -317,17 +313,13 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
// count is not available, [myArray count] returns id, which can't be directly
// cast to int without causing a clang error.
static void ApplyObjcCastHack(std::string &expr) {
-#define OBJC_CAST_HACK_FROM "(int)["
-#define OBJC_CAST_HACK_TO "(int)(long long)["
-
- size_t from_offset;
+ const std::string from = "(int)[";
+ const std::string to = "(int)(long long)[";
- while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
- expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
- OBJC_CAST_HACK_TO);
+ size_t offset;
-#undef OBJC_CAST_HACK_TO
-#undef OBJC_CAST_HACK_FROM
+ while ((offset = expr.find(from)) != expr.npos)
+ expr.replace(offset, from.size(), to);
}
bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
@@ -336,6 +328,7 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man
if (PersistentExpressionState *persistent_state =
target->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC)) {
+ m_clang_state = llvm::cast<ClangPersistentVariables>(persistent_state);
m_result_delegate.RegisterPersistentState(persistent_state);
} else {
diagnostic_manager.PutString(
@@ -384,30 +377,34 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
}
}
-void ClangUserExpression::UpdateLanguageForExpr(
+void ClangUserExpression::UpdateLanguageForExpr() {
+ m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
+ return;
+ 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;
+}
+
+void ClangUserExpression::CreateSourceCode(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
std::vector<std::string> modules_to_import, bool for_completion) {
- m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
+ m_filename = m_clang_state->GetNextExprFileName();
std::string prefix = m_expr_prefix;
if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
m_transformed_text = m_expr_text;
} else {
- std::unique_ptr<ClangExpressionSourceCode> source_code(
- ClangExpressionSourceCode::CreateWrapped(prefix.c_str(),
- m_expr_text.c_str()));
-
- 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;
-
- if (!source_code->GetText(m_transformed_text, m_expr_lang,
- m_in_static_method, exe_ctx, !m_ctx_obj,
- for_completion, modules_to_import)) {
+ m_source_code.reset(ClangExpressionSourceCode::CreateWrapped(
+ m_filename, prefix.c_str(), m_expr_text.c_str()));
+
+ if (!m_source_code->GetText(m_transformed_text, m_expr_lang,
+ m_in_static_method, exe_ctx, !m_ctx_obj,
+ for_completion, modules_to_import)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
return;
@@ -417,7 +414,7 @@ void ClangUserExpression::UpdateLanguageForExpr(
// transformed code. We need this later for the code completion.
std::size_t original_start;
std::size_t original_end;
- bool found_bounds = source_code->GetOriginalBodyBounds(
+ bool found_bounds = m_source_code->GetOriginalBodyBounds(
m_transformed_text, m_expr_lang, original_start, original_end);
if (found_bounds)
m_user_expression_start_pos = original_start;
@@ -437,48 +434,70 @@ static bool SupportsCxxModuleImport(lldb::LanguageType language) {
}
}
-std::vector<std::string>
-ClangUserExpression::GetModulesToImport(ExecutionContext &exe_ctx) {
+/// Utility method that puts a message into the expression log and
+/// returns an invalid module configuration.
+static CppModuleConfiguration LogConfigError(const std::string &msg) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ LLDB_LOG(log, "[C++ module config] {0}", msg);
+ return CppModuleConfiguration();
+}
- if (!SupportsCxxModuleImport(Language()))
- return {};
+CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
+ ExecutionContext &exe_ctx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // Don't do anything if this is not a C++ module configuration.
+ if (!SupportsCxxModuleImport(language))
+ return LogConfigError("Language doesn't support C++ modules");
Target *target = exe_ctx.GetTargetPtr();
- if (!target || !target->GetEnableImportStdModule())
- return {};
+ if (!target)
+ return LogConfigError("No target");
+
+ if (!target->GetEnableImportStdModule())
+ return LogConfigError("Importing std module not enabled in settings");
StackFrame *frame = exe_ctx.GetFramePtr();
if (!frame)
- return {};
+ return LogConfigError("No frame");
Block *block = frame->GetFrameBlock();
if (!block)
- return {};
+ return LogConfigError("No block");
SymbolContext sc;
block->CalculateSymbolContext(&sc);
if (!sc.comp_unit)
- return {};
-
- if (log) {
- for (const SourceModule &m : sc.comp_unit->GetImportedModules()) {
- LLDB_LOG(log, "Found module in compile unit: {0:$[.]} - include dir: {1}",
- llvm::make_range(m.path.begin(), m.path.end()), m.search_path);
+ return LogConfigError("Couldn't calculate symbol context");
+
+ // Build a list of files we need to analyze to build the configuration.
+ FileSpecList files;
+ for (const FileSpec &f : sc.comp_unit->GetSupportFiles())
+ files.AppendIfUnique(f);
+ // We also need to look at external modules in the case of -gmodules as they
+ // contain the support files for libc++ and the C library.
+ sc.comp_unit->ForEachExternalModule([&files](lldb::ModuleSP module) {
+ for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i) {
+ const FileSpecList &support_files =
+ module->GetCompileUnitAtIndex(i)->GetSupportFiles();
+ for (const FileSpec &f : support_files) {
+ files.AppendIfUnique(f);
+ }
}
+ });
+
+ LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze",
+ files.GetSize());
+ if (log && log->GetVerbose()) {
+ for (const FileSpec &f : files)
+ LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}",
+ f.GetPath());
}
- for (const SourceModule &m : sc.comp_unit->GetImportedModules())
- m_include_directories.push_back(m.search_path);
-
- // Check if we imported 'std' or any of its submodules.
- // We currently don't support importing any other modules in the expression
- // parser.
- for (const SourceModule &m : sc.comp_unit->GetImportedModules())
- if (!m.path.empty() && m.path.front() == "std")
- return {"std"};
-
- return {};
+ // Try to create a configuration from the files. If there is no valid
+ // configuration possible with the files, this just returns an invalid
+ // configuration.
+ return CppModuleConfiguration(files);
}
bool ClangUserExpression::PrepareForParsing(
@@ -506,14 +525,21 @@ bool ClangUserExpression::PrepareForParsing(
SetupDeclVendor(exe_ctx, m_target);
- std::vector<std::string> used_modules = GetModulesToImport(exe_ctx);
- m_imported_cpp_modules = !used_modules.empty();
+ CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
+ llvm::ArrayRef<std::string> imported_modules =
+ module_config.GetImportedModules();
+ m_imported_cpp_modules = !imported_modules.empty();
+ m_include_directories = module_config.GetIncludeDirs();
LLDB_LOG(log, "List of imported modules in expression: {0}",
- llvm::make_range(used_modules.begin(), used_modules.end()));
-
- UpdateLanguageForExpr(diagnostic_manager, exe_ctx, used_modules,
- for_completion);
+ llvm::make_range(imported_modules.begin(), imported_modules.end()));
+ LLDB_LOG(log, "List of include directories gathered for modules: {0}",
+ llvm::make_range(m_include_directories.begin(),
+ m_include_directories.end()));
+
+ UpdateLanguageForExpr();
+ CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules,
+ for_completion);
return true;
}
@@ -527,8 +553,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
return false;
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
////////////////////////////////////
// Set up the target and compiler
@@ -573,7 +598,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
// parser_sp will never be empty.
ClangExpressionParser parser(exe_scope, *this, generate_debug_info,
- m_include_directories);
+ m_include_directories, m_filename);
unsigned num_errors = parser.Parse(diagnostic_manager);
@@ -586,8 +611,11 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
size_t fixed_end;
const std::string &fixed_expression =
diagnostic_manager.GetFixedExpression();
- if (ClangExpressionSourceCode::GetOriginalBodyBounds(
- fixed_expression, m_expr_lang, fixed_start, fixed_end))
+ // 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))
m_fixed_text =
fixed_expression.substr(fixed_start, fixed_end - fixed_start);
}
@@ -648,12 +676,10 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
register_execution_unit = true;
}
- if (register_execution_unit) {
- llvm::cast<PersistentExpressionState>(
- exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
- m_language))
+ if (register_execution_unit)
+ exe_ctx.GetTargetPtr()
+ ->GetPersistentExpressionStateForLanguage(m_language)
->RegisterExecutionUnit(m_execution_unit_sp);
- }
}
if (generate_debug_info) {
@@ -726,8 +752,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true))
return false;
- if (log)
- log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+ LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
//////////////////////////
// Parse the expression
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 24c152bdb45d..d94f9cc5e066 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -15,6 +15,7 @@
#include "ASTStructExtractor.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionHelper.h"
+#include "ClangExpressionSourceCode.h"
#include "ClangExpressionVariable.h"
#include "IRForTarget.h"
@@ -105,6 +106,9 @@ public:
/// If not eResultTypeAny, the type to use for the expression
/// result.
///
+ /// \param[in] options
+ /// Additional options for the expression.
+ ///
/// \param[in] ctx_obj
/// The object (if any) in which context the expression
/// must be evaluated. For details see the comment to
@@ -175,11 +179,11 @@ private:
lldb::addr_t struct_address,
DiagnosticManager &diagnostic_manager) override;
- std::vector<std::string> GetModulesToImport(ExecutionContext &exe_ctx);
- void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx,
- std::vector<std::string> modules_to_import,
- bool for_completion);
+ void CreateSourceCode(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx,
+ std::vector<std::string> modules_to_import,
+ bool for_completion);
+ void UpdateLanguageForExpr();
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
ExecutionContext &exe_ctx);
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
@@ -205,13 +209,17 @@ private:
/// 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<ConstString> m_include_directories;
+ std::vector<std::string> m_include_directories;
/// The absolute character position in the transformed source code where the
/// user code (as typed by the user) starts. If the variable is empty, then we
/// were not able to calculate this position.
llvm::Optional<size_t> m_user_expression_start_pos;
ResultDelegate m_result_delegate;
+ ClangPersistentVariables *m_clang_state;
+ std::unique_ptr<ClangExpressionSourceCode> m_source_code;
+ /// File name used for the expression.
+ std::string m_filename;
/// The object (if any) in which context the expression is evaluated.
/// See the comment to `UserExpression::Evaluate` for details.
@@ -219,6 +227,23 @@ private:
/// True iff this expression explicitly imported C++ modules.
bool m_imported_cpp_modules = false;
+
+ /// True if the expression parser should enforce the presence of a valid class
+ /// pointer in order to generate the expression as a method.
+ bool m_enforce_valid_object = true;
+ /// True if the expression is compiled as a C++ member function (true if it
+ /// was parsed when exe_ctx was in a C++ method).
+ bool m_in_cplusplus_method = false;
+ /// True if the expression is compiled as an Objective-C method (true if it
+ /// was parsed when exe_ctx was in an Objective-C method).
+ bool m_in_objectivec_method = false;
+ /// True if the expression is compiled as a static (or class) method
+ /// (currently true if it was parsed when exe_ctx was in an Objective-C class
+ /// method).
+ bool m_in_static_method = false;
+ /// True if "this" or "self" must be looked up and passed in. False if the
+ /// expression doesn't really use them and they can be NULL.
+ bool m_needs_object_ptr = false;
};
} // namespace lldb_private
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 5eec224477fc..564c62c6a2c6 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
+
#include "ClangUtilityFunction.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
new file mode 100644
index 000000000000..51ae73285b53
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -0,0 +1,82 @@
+//===-- CppModuleConfiguration.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 "CppModuleConfiguration.h"
+
+#include "ClangHost.h"
+#include "lldb/Host/FileSystem.h"
+
+using namespace lldb_private;
+
+bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) {
+ // Setting for the first time always works.
+ if (m_first) {
+ m_path = path.str();
+ m_valid = true;
+ m_first = false;
+ return true;
+ }
+ // Changing the path to the same value is fine.
+ if (m_path == path)
+ return true;
+
+ // Changing the path after it was already set is not allowed.
+ m_valid = false;
+ return false;
+}
+
+bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
+ using namespace llvm::sys::path;
+ // Convert to slashes to make following operations simpler.
+ std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef());
+ llvm::StringRef posix_dir(dir_buffer);
+
+ // Check for /c++/vX/ that is used by libc++.
+ static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex");
+ if (libcpp_regex.match(f.GetPath())) {
+ // Strip away libc++'s /experimental directory if there is one.
+ posix_dir.consume_back("/experimental");
+ return m_std_inc.TrySet(posix_dir);
+ }
+
+ // Check for /usr/include. On Linux this might be /usr/include/bits, so
+ // we should remove that '/bits' suffix to get the actual include directory.
+ if (posix_dir.endswith("/usr/include/bits"))
+ posix_dir.consume_back("/bits");
+ if (posix_dir.endswith("/usr/include"))
+ return m_c_inc.TrySet(posix_dir);
+
+ // File wasn't interesting, continue analyzing.
+ return true;
+}
+
+bool CppModuleConfiguration::hasValidConfig() {
+ // We all these include directories to have a valid usable configuration.
+ return m_c_inc.Valid() && m_std_inc.Valid();
+}
+
+CppModuleConfiguration::CppModuleConfiguration(
+ const FileSpecList &support_files) {
+ // Analyze all files we were given to build the configuration.
+ bool error = !llvm::all_of(support_files,
+ std::bind(&CppModuleConfiguration::analyzeFile,
+ this, std::placeholders::_1));
+ // If we have a valid configuration at this point, set the
+ // include directories and module list that should be used.
+ if (!error && hasValidConfig()) {
+ // Calculate the resource directory for LLDB.
+ llvm::SmallString<256> resource_dir;
+ llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(),
+ "include");
+ m_resource_inc = 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()};
+ m_imported_modules = {"std"};
+ }
+}
diff --git a/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
new file mode 100644
index 000000000000..8e892e37d0de
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -0,0 +1,84 @@
+//===-- CppModuleConfiguration.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_CppModuleConfiguration_h_
+#define liblldb_CppModuleConfiguration_h_
+
+#include <lldb/Core/FileSpecList.h>
+#include <llvm/Support/Regex.h>
+
+namespace lldb_private {
+
+/// A Clang configuration when importing C++ modules.
+///
+/// Includes a list of include paths that should be used when importing
+/// and a list of modules that can be imported. Currently only used when
+/// importing the 'std' module and its dependencies.
+class CppModuleConfiguration {
+ /// Utility class for a path that can only be set once.
+ class SetOncePath {
+ std::string m_path;
+ bool m_valid = false;
+ /// True iff this path hasn't been set yet.
+ bool m_first = true;
+
+ public:
+ /// Try setting the path. Returns true if the path was set and false if
+ /// the path was already set.
+ LLVM_NODISCARD bool TrySet(llvm::StringRef path);
+ /// Return the path if there is one.
+ std::string Get() const {
+ assert(m_valid && "Called Get() on an invalid SetOncePath?");
+ return m_path;
+ }
+ /// Returns true iff this path was set exactly once so far.
+ bool Valid() const { return m_valid; }
+ };
+
+ /// If valid, the include path used for the std module.
+ SetOncePath m_std_inc;
+ /// If valid, the include path to the C library (e.g. /usr/include).
+ SetOncePath m_c_inc;
+ /// The Clang resource include path for this configuration.
+ std::string m_resource_inc;
+
+ std::vector<std::string> m_include_dirs;
+ std::vector<std::string> m_imported_modules;
+
+ /// Analyze a given source file to build the current configuration.
+ /// Returns false iff there was a fatal error that makes analyzing any
+ /// further files pointless as the configuration is now invalid.
+ bool analyzeFile(const FileSpec &f);
+
+public:
+ /// Creates a configuraiton 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.
+ explicit CppModuleConfiguration(const FileSpecList &support_files);
+ /// Creates an empty and invalid configuration.
+ CppModuleConfiguration() {}
+
+ /// Returns true iff this is a valid configuration that can be used to
+ /// load and compile modules.
+ bool hasValidConfig();
+
+ /// Returns a list of include directories that should be used when using this
+ /// configuration (e.g. {"/usr/include", "/usr/include/c++/v1"}).
+ llvm::ArrayRef<std::string> GetIncludeDirs() const { return m_include_dirs; }
+
+ /// Returns a list of (top level) modules that should be imported when using
+ /// this configuration (e.g. {"std"}).
+ llvm::ArrayRef<std::string> GetImportedModules() const {
+ return m_imported_modules;
+ }
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index f8e004fe7d4a..d5ffb9529f36 100644
--- a/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -320,9 +320,8 @@ protected:
bool InstrumentInstruction(llvm::Instruction *inst) override {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("Instrumenting load/store instruction: %s\n",
- PrintValue(inst).c_str());
+ LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n",
+ PrintValue(inst).c_str());
if (!m_valid_pointer_check_func)
m_valid_pointer_check_func =
@@ -483,9 +482,8 @@ protected:
std::string name_str = called_function->getName().str();
const char *name_cstr = name_str.c_str();
- if (log)
- log->Printf("Found call to %s: %s\n", name_cstr,
- PrintValue(call_inst).c_str());
+ LLDB_LOGF(log, "Found call to %s: %s\n", name_cstr,
+ PrintValue(call_inst).c_str());
if (name_str.find("objc_msgSend") == std::string::npos)
return true;
@@ -520,10 +518,9 @@ protected:
return true;
}
- if (log)
- log->Printf(
- "Function name '%s' contains 'objc_msgSend' but is not handled",
- name_str.c_str());
+ LLDB_LOGF(log,
+ "Function name '%s' contains 'objc_msgSend' but is not handled",
+ name_str.c_str());
return true;
}
@@ -548,8 +545,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) {
llvm::Function *function = M.getFunction(StringRef(m_func_name));
if (!function) {
- if (log)
- log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
+ LLDB_LOGF(log, "Couldn't find %s() in the module", m_func_name.c_str());
return false;
}
@@ -582,7 +578,7 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) {
oss.flush();
- log->Printf("Module after dynamic checks: \n%s", s.c_str());
+ LLDB_LOGF(log, "Module after dynamic checks: \n%s", s.c_str());
}
return true;
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 07acb2e1030f..4e871f7d6a44 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -43,6 +43,8 @@ using namespace llvm;
static char ID;
+typedef SmallVector<Instruction *, 2> InstrList;
+
IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
: m_maker(maker), m_values() {}
@@ -153,6 +155,15 @@ clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
return DeclForGlobal(global_val, m_module);
}
+/// Returns true iff the mangled symbol is for a static guard variable.
+static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
+ bool check_ms_abi = true) {
+ bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
+ if (check_ms_abi)
+ result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
+ return result;
+}
+
bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -164,64 +175,58 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- std::string result_name_str;
- const char *result_name = nullptr;
+ llvm::StringRef result_name;
+ bool found_result = false;
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- result_name_str = vi->first().str();
- const char *value_name = result_name_str.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ result_name = value_symbol.first();
- if (strstr(value_name, "$__lldb_expr_result_ptr") &&
- strncmp(value_name, "_ZGV", 4)) {
- result_name = value_name;
+ // Check if this is a guard variable. It seems this causes some hiccups
+ // on Windows, so let's only check for Itanium guard variables.
+ bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
+
+ if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
+ found_result = true;
m_result_is_pointer = true;
break;
}
- if (strstr(value_name, "$__lldb_expr_result") &&
- strncmp(value_name, "_ZGV", 4)) {
- result_name = value_name;
+ if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
+ found_result = true;
m_result_is_pointer = false;
break;
}
}
- if (!result_name) {
- if (log)
- log->PutCString("Couldn't find result variable");
+ if (!found_result) {
+ LLDB_LOG(log, "Couldn't find result variable");
return true;
}
- if (log)
- log->Printf("Result name: \"%s\"", result_name);
+ LLDB_LOG(log, "Result name: \"{0}\"", result_name);
Value *result_value = m_module->getNamedValue(result_name);
if (!result_value) {
- if (log)
- log->PutCString("Result variable had no data");
+ LLDB_LOG(log, "Result variable had no data");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
- "name (%s) exists, but not its definition\n",
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
+ "name ({0}) exists, but not its definition\n",
result_name);
return false;
}
- if (log)
- log->Printf("Found result in the IR: \"%s\"",
- PrintValue(result_value, false).c_str());
+ LLDB_LOG(log, "Found result in the IR: \"{0}\"",
+ PrintValue(result_value, false));
GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
if (!result_global) {
- if (log)
- log->PutCString("Result variable isn't a GlobalVariable");
+ LLDB_LOG(log, "Result variable isn't a GlobalVariable");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
"is defined, but is not a global variable\n",
result_name);
@@ -230,10 +235,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
clang::NamedDecl *result_decl = DeclForGlobal(result_global);
if (!result_decl) {
- if (log)
- log->PutCString("Result variable doesn't have a corresponding Decl");
+ LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
"does not have a corresponding Clang entity\n",
result_name);
@@ -246,16 +250,15 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
result_decl->print(decl_desc_stream);
decl_desc_stream.flush();
- log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
+ LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
}
clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
if (!result_var) {
- if (log)
- log->PutCString("Result variable Decl isn't a VarDecl");
+ LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
- "(%s)'s corresponding Clang entity isn't a "
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable "
+ "({0})'s corresponding Clang entity isn't a "
"variable\n",
result_name);
@@ -292,10 +295,9 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::ClangASTContext::GetASTContext(
&result_decl->getASTContext()));
} else {
- if (log)
- log->PutCString("Expected result to have pointer type, but it did not");
+ LLDB_LOG(log, "Expected result to have pointer type, but it did not");
- m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
+ m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
"is not a pointer variable\n",
result_name);
@@ -316,8 +318,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
- if (log)
- log->Printf("Result type has unknown size");
+ LLDB_LOG(log, "Result type has unknown size");
m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
"couldn't be determined\n",
@@ -329,15 +330,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
- log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+ LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
}
m_result_name = lldb_private::ConstString("$RESULT_NAME");
- if (log)
- log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
- m_result_name.GetCString(),
- m_result_type.GetByteSize(nullptr).getValueOr(0));
+ LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
+ m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
// Construct a new result global and set up its metadata
@@ -369,10 +368,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
m_module->getNamedMetadata("clang.global.decl.ptrs");
named_metadata->addOperand(persistent_global_md);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"",
- PrintValue(result_global).c_str(),
- PrintValue(new_result_global).c_str());
+ LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
+ PrintValue(new_result_global));
if (result_global->use_empty()) {
// We need to synthesize a store for this variable, because otherwise
@@ -385,11 +382,10 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
return false;
if (!result_global->hasInitializer()) {
- if (log)
- log->Printf("Couldn't find initializer for unused variable");
+ LLDB_LOG(log, "Couldn't find initializer for unused variable");
- m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
- "(%s) has no writes and no initializer\n",
+ m_error_stream.Format("Internal error [IRForTarget]: Result variable "
+ "({0}) has no writes and no initializer\n",
result_name);
return false;
@@ -400,9 +396,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
StoreInst *synthesized_store =
new StoreInst(initializer, new_result_global, first_entry_instruction);
- if (log)
- log->Printf("Synthesized result store \"%s\"\n",
- PrintValue(synthesized_store).c_str());
+ LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
+ PrintValue(synthesized_store));
} else {
result_global->replaceAllUsesWith(new_result_global);
}
@@ -438,7 +433,6 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
missing_weak);
if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
- if (log)
log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
@@ -448,9 +442,8 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
return false;
}
- if (log)
- log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
- CFStringCreateWithBytes_addr);
+ LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
+ CFStringCreateWithBytes_addr);
// Build the function type:
//
@@ -543,9 +536,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
m_error_stream)) {
- if (log)
- log->PutCString(
- "Couldn't replace the NSString with the result of the call");
+ LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
"Objective-C constant string with a dynamic "
@@ -565,21 +556,17 @@ bool IRForTarget::RewriteObjCConstStrings() {
ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ llvm::StringRef value_name = value_symbol.first();
- if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
- Value *nsstring_value = vi->second;
+ if (value_name.contains("_unnamed_cfstring_")) {
+ Value *nsstring_value = value_symbol.second;
GlobalVariable *nsstring_global =
dyn_cast<GlobalVariable>(nsstring_value);
if (!nsstring_global) {
- if (log)
- log->PutCString("NSString variable is not a GlobalVariable");
+ LLDB_LOG(log, "NSString variable is not a GlobalVariable");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string is not a global variable\n");
@@ -588,8 +575,7 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!nsstring_global->hasInitializer()) {
- if (log)
- log->PutCString("NSString variable does not have an initializer");
+ LLDB_LOG(log, "NSString variable does not have an initializer");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string does not have an initializer\n");
@@ -601,9 +587,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
if (!nsstring_struct) {
- if (log)
- log->PutCString(
- "NSString variable's initializer is not a ConstantStruct");
+ LLDB_LOG(log,
+ "NSString variable's initializer is not a ConstantStruct");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string is not a structure constant\n");
@@ -621,10 +606,11 @@ bool IRForTarget::RewriteObjCConstStrings() {
// };
if (nsstring_struct->getNumOperands() != 4) {
- if (log)
- log->Printf("NSString variable's initializer structure has an "
- "unexpected number of members. Should be 4, is %d",
- nsstring_struct->getNumOperands());
+
+ LLDB_LOG(log,
+ "NSString variable's initializer structure has an "
+ "unexpected number of members. Should be 4, is {0}",
+ nsstring_struct->getNumOperands());
m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
"Objective-C constant string is not as "
@@ -636,8 +622,7 @@ bool IRForTarget::RewriteObjCConstStrings() {
Constant *nsstring_member = nsstring_struct->getOperand(2);
if (!nsstring_member) {
- if (log)
- log->PutCString("NSString initializer's str element was empty");
+ LLDB_LOG(log, "NSString initializer's str element was empty");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string does not have a string "
@@ -649,9 +634,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
if (!nsstring_expr) {
- if (log)
- log->PutCString(
- "NSString initializer's str element is not a ConstantExpr");
+ LLDB_LOG(log,
+ "NSString initializer's str element is not a ConstantExpr");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string's string initializer is not "
@@ -671,9 +655,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!cstr_global) {
- if (log)
- log->PutCString(
- "NSString initializer's str element is not a GlobalVariable");
+ LLDB_LOG(log,
+ "NSString initializer's str element is not a GlobalVariable");
m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
"constant string initializer\n");
@@ -682,9 +665,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
if (!cstr_global->hasInitializer()) {
- if (log)
- log->PutCString("NSString initializer's str element does not have an "
- "initializer");
+ LLDB_LOG(log, "NSString initializer's str element does not have an "
+ "initializer");
m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
"constant string's string initializer doesn't "
@@ -726,21 +708,18 @@ bool IRForTarget::RewriteObjCConstStrings() {
ConstantDataArray *cstr_array =
dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
- if (log) {
- if (cstr_array)
- log->Printf("Found NSString constant %s, which contains \"%s\"",
- value_name_cstr, cstr_array->getAsString().str().c_str());
- else
- log->Printf("Found NSString constant %s, which contains \"\"",
- value_name_cstr);
- }
+ if (cstr_array)
+ LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
+ value_name, cstr_array->getAsString());
+ else
+ LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
+ value_name);
if (!cstr_array)
cstr_global = nullptr;
if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
- if (log)
- log->PutCString("Error rewriting the constant string");
+ LLDB_LOG(log, "Error rewriting the constant string");
// We don't print an error message here because RewriteObjCConstString
// has done so for us.
@@ -750,19 +729,15 @@ bool IRForTarget::RewriteObjCConstStrings() {
}
}
- for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
- ve = value_symbol_table.end();
- vi != ve; ++vi) {
- std::string value_name = vi->first().str();
- const char *value_name_cstr = value_name.c_str();
+ for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
+ llvm::StringRef value_name = value_symbol.first();
- if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
- GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
+ if (value_name == "__CFConstantStringClassReference") {
+ GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
if (!gv) {
- if (log)
- log->PutCString(
- "__CFConstantStringClassReference is not a global variable");
+ LLDB_LOG(log,
+ "__CFConstantStringClassReference is not a global variable");
m_error_stream.Printf("Internal error [IRForTarget]: Found a "
"CFConstantStringClassReference, but it is not a "
@@ -850,9 +825,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
std::string omvn_initializer_string = omvn_initializer_array->getAsString();
- if (log)
- log->Printf("Found Objective-C selector reference \"%s\"",
- omvn_initializer_string.c_str());
+ LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
+ omvn_initializer_string);
// Construct a call to sel_registerName
@@ -866,9 +840,7 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
return false;
- if (log)
- log->Printf("Found sel_registerName at 0x%" PRIx64,
- sel_registerName_addr);
+ LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
// Build the function type: struct objc_selector
// *sel_registerName(uint8_t*)
@@ -921,32 +893,21 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList selector_loads;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (IsObjCSelectorRef(load->getPointerOperand()))
selector_loads.push_back(&inst);
}
- InstrIterator iter;
-
- for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
- if (!RewriteObjCSelector(*iter)) {
+ for (Instruction *inst : selector_loads) {
+ if (!RewriteObjCSelector(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
"static reference to an Objective-C selector to a "
"dynamic reference\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite a reference to an Objective-C selector");
+ LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
return false;
}
@@ -1022,9 +983,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
std::string ocn_initializer_string = ocn_initializer_array->getAsString();
- if (log)
- log->Printf("Found Objective-C class reference \"%s\"",
- ocn_initializer_string.c_str());
+ LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
+ ocn_initializer_string);
// Construct a call to objc_getClass
@@ -1038,9 +998,7 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
return false;
- if (log)
- log->Printf("Found objc_getClass at 0x%" PRIx64,
- objc_getClass_addr);
+ LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
// Build the function type: %struct._objc_class *objc_getClass(i8*)
@@ -1086,32 +1044,21 @@ bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList class_loads;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (IsObjCClassReference(load->getPointerOperand()))
class_loads.push_back(&inst);
}
- InstrIterator iter;
-
- for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) {
- if (!RewriteObjCClassReference(*iter)) {
+ for (Instruction *inst : class_loads) {
+ if (!RewriteObjCClassReference(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
"static reference to an Objective-C class to a "
"dynamic reference\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite a reference to an Objective-C class");
+ LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
return false;
}
@@ -1180,9 +1127,8 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
- if (log)
- log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
- PrintValue(persistent_load).c_str());
+ LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
+ PrintValue(persistent_load));
alloc->replaceAllUsesWith(persistent_load);
alloc->eraseFromParent();
@@ -1197,23 +1143,16 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
-
InstrList pvar_allocs;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : basic_block) {
if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
llvm::StringRef alloc_name = alloc->getName();
if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
if (alloc_name.find_first_of("0123456789") == 1) {
- if (log)
- log->Printf("Rejecting a numeric persistent variable.");
+ LLDB_LOG(log, "Rejecting a numeric persistent variable.");
m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
"$1, ... are reserved for use as result "
@@ -1227,16 +1166,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
}
}
- InstrIterator iter;
-
- for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
- if (!RewritePersistentAlloc(*iter)) {
+ for (Instruction *inst : pvar_allocs) {
+ if (!RewritePersistentAlloc(inst)) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
"the creation of a persistent variable\n");
- if (log)
- log->PutCString(
- "Couldn't rewrite the creation of a persistent variable");
+ LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
return false;
}
@@ -1245,79 +1180,12 @@ bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
return true;
}
-bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
- if (!initializer)
- return true;
-
- lldb_private::Log *log(
- lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- if (log && log->GetVerbose())
- log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
- PrintValue(initializer).c_str());
-
- Type *initializer_type = initializer->getType();
-
- if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
- size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
- lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
- llvm::NextPowerOf2(constant_size) * 8);
-
- lldb_private::Status get_data_error;
- return scalar.GetAsMemoryData(data, constant_size,
- lldb_private::endian::InlHostByteOrder(),
- get_data_error) != 0;
- } else if (ConstantDataArray *array_initializer =
- dyn_cast<ConstantDataArray>(initializer)) {
- if (array_initializer->isString()) {
- std::string array_initializer_string = array_initializer->getAsString();
- memcpy(data, array_initializer_string.c_str(),
- m_target_data->getTypeStoreSize(initializer_type));
- } else {
- ArrayType *array_initializer_type = array_initializer->getType();
- Type *array_element_type = array_initializer_type->getElementType();
-
- size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
-
- for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
- Value *operand_value = array_initializer->getOperand(i);
- Constant *operand_constant = dyn_cast<Constant>(operand_value);
-
- if (!operand_constant)
- return false;
-
- if (!MaterializeInitializer(data + (i * element_size),
- operand_constant))
- return false;
- }
- }
- return true;
- } else if (ConstantStruct *struct_initializer =
- dyn_cast<ConstantStruct>(initializer)) {
- StructType *struct_initializer_type = struct_initializer->getType();
- const StructLayout *struct_layout =
- m_target_data->getStructLayout(struct_initializer_type);
-
- for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
- if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
- struct_initializer->getOperand(i)))
- return false;
- }
- return true;
- } else if (isa<ConstantAggregateZero>(initializer)) {
- memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
- return true;
- }
- return false;
-}
-
// This function does not report errors; its callers are responsible.
bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+ LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
switch (constant_expr->getOpcode()) {
@@ -1343,25 +1211,26 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
if (!global_variable->hasExternalLinkage())
return true;
- if (log)
- log->Printf("Found global variable \"%s\" without metadata",
- global_variable->getName().str().c_str());
+ LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
+ global_variable->getName());
return false;
}
- std::string name(named_decl->getName().str());
+ llvm::StringRef name(named_decl->getName());
clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
if (value_decl == nullptr)
return false;
- lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
- value_decl->getType());
+ lldb_private::CompilerType compiler_type(
+ lldb_private::ClangASTContext::GetASTContext(
+ &value_decl->getASTContext()),
+ value_decl->getType().getAsOpaquePtr());
const Type *value_type = nullptr;
- if (name[0] == '$') {
+ if (name.startswith("$")) {
// The $__lldb_expr_result name indicates the return value has allocated
// as a static variable. Per the comment at
// ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
@@ -1381,31 +1250,24 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
if (!value_size)
return false;
- lldb::offset_t value_alignment =
- (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
-
- if (log) {
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
- ", align %" PRIu64 "]",
- name.c_str(),
- lldb_private::ClangUtil::GetQualType(compiler_type)
- .getAsString()
- .c_str(),
- PrintType(value_type).c_str(), *value_size, value_alignment);
- }
-
- if (named_decl &&
- !m_decl_map->AddValueToStruct(
- named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
- *value_size, value_alignment)) {
- if (!global_variable->hasExternalLinkage())
- return true;
- else
- return true;
- }
+ llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
+ if (!opt_alignment)
+ return false;
+ lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
+
+ LLDB_LOG(log,
+ "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
+ "align {4}]",
+ name,
+ lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
+ PrintType(value_type), *value_size, value_alignment);
+
+ if (named_decl)
+ m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
+ llvm_value_ptr, *value_size,
+ value_alignment);
} else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
- if (log)
- log->Printf("Function pointers aren't handled right now");
+ LLDB_LOG(log, "Function pointers aren't handled right now");
return false;
}
@@ -1424,14 +1286,12 @@ bool IRForTarget::HandleSymbol(Value *symbol) {
m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
if (symbol_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("Symbol \"%s\" had no address", name.GetCString());
+ LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
return false;
}
- if (log)
- log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
+ LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
Type *symbol_type = symbol->getType();
@@ -1440,9 +1300,8 @@ bool IRForTarget::HandleSymbol(Value *symbol) {
Value *symbol_addr_ptr =
ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
- if (log)
- log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
- PrintValue(symbol_addr_ptr).c_str());
+ LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
+ PrintValue(symbol_addr_ptr));
symbol->replaceAllUsesWith(symbol_addr_ptr);
@@ -1453,14 +1312,12 @@ bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
+ LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
op_index < num_ops; ++op_index)
- if (!MaybeHandleVariable(Old->getArgOperand(
- op_index))) // conservatively believe that this is a store
- {
+ // conservatively believe that this is a store
+ if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
"one of the arguments of a function call.\n");
@@ -1493,9 +1350,8 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
lldb::addr_t class_ptr =
m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
- if (log)
- log->Printf("Found reference to Objective-C class %s (0x%llx)",
- name_cstr.AsCString(), (unsigned long long)class_ptr);
+ LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
+ (unsigned long long)class_ptr);
if (class_ptr == LLDB_INVALID_ADDRESS)
return false;
@@ -1528,13 +1384,9 @@ bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
}
bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
- BasicBlock::iterator ii;
-
std::vector<CallInst *> calls_to_remove;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
-
+ for (Instruction &inst : basic_block) {
CallInst *call = dyn_cast<CallInst>(&inst);
// MaybeHandleCallArguments handles error reporting; we are silent here
@@ -1557,25 +1409,16 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
calls_to_remove.push_back(call);
}
- for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
- ce = calls_to_remove.end();
- ci != ce; ++ci) {
- (*ci)->eraseFromParent();
- }
+ for (CallInst *ci : calls_to_remove)
+ ci->eraseFromParent();
return true;
}
bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
- /////////////////////////////////////////////////////////////////////////
// Prepare the current basic block for execution in the remote process
- //
-
- BasicBlock::iterator ii;
-
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : basic_block) {
CallInst *call = dyn_cast<CallInst>(&inst);
// MaybeHandleCallArguments handles error reporting; we are silent here
@@ -1591,31 +1434,27 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
for (GlobalVariable &global_var : m_module->globals()) {
- std::string global_name = global_var.getName().str();
+ llvm::StringRef global_name = global_var.getName();
- if (log)
- log->Printf("Examining %s, DeclForGlobalValue returns %p",
- global_name.c_str(),
- static_cast<void *>(DeclForGlobal(&global_var)));
+ LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
+ static_cast<void *>(DeclForGlobal(&global_var)));
- if (global_name.find("OBJC_IVAR") == 0) {
+ if (global_name.startswith("OBJC_IVAR")) {
if (!HandleSymbol(&global_var)) {
- m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
- "indirect ivar symbol %s\n",
- global_name.c_str());
+ m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
+ "indirect ivar symbol {0}\n",
+ global_name);
return false;
}
- } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
- global_name.npos) {
+ } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
if (!HandleObjCClass(&global_var)) {
m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
"for an Objective-C static method call\n");
return false;
}
- } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
- global_name.npos) {
+ } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
if (!HandleObjCClass(&global_var)) {
m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
"for an Objective-C static method call\n");
@@ -1624,9 +1463,9 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
}
} else if (DeclForGlobal(&global_var)) {
if (!MaybeHandleVariable(&global_var)) {
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
- "external variable %s\n",
- global_name.c_str());
+ m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
+ "external variable {0}\n",
+ global_name);
return false;
}
@@ -1637,14 +1476,12 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) {
}
static bool isGuardVariableRef(Value *V) {
- Constant *Old = nullptr;
+ Constant *Old = dyn_cast<Constant>(V);
- if (!(Old = dyn_cast<Constant>(V)))
+ if (!Old)
return false;
- ConstantExpr *CE = nullptr;
-
- if ((CE = dyn_cast<ConstantExpr>(V))) {
+ if (auto CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() != Instruction::BitCast)
return false;
@@ -1653,12 +1490,8 @@ static bool isGuardVariableRef(Value *V) {
GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
- if (!GV || !GV->hasName() ||
- (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
- !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
- {
+ if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
return false;
- }
return true;
}
@@ -1674,20 +1507,12 @@ static void ExciseGuardStore(Instruction *guard_store) {
}
bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
- ///////////////////////////////////////////////////////
// Eliminate any reference to guard variables found.
- //
-
- BasicBlock::iterator ii;
-
- typedef SmallVector<Instruction *, 2> InstrList;
- typedef InstrList::iterator InstrIterator;
InstrList guard_loads;
InstrList guard_stores;
- for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
- Instruction &inst = *ii;
+ for (Instruction &inst : basic_block) {
if (LoadInst *load = dyn_cast<LoadInst>(&inst))
if (isGuardVariableRef(load->getPointerOperand()))
@@ -1698,13 +1523,11 @@ bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
guard_stores.push_back(&inst);
}
- InstrIterator iter;
+ for (Instruction *inst : guard_loads)
+ TurnGuardLoadIntoZero(inst);
- for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
- TurnGuardLoadIntoZero(*iter);
-
- for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
- ExciseGuardStore(*iter);
+ for (Instruction *inst : guard_stores)
+ ExciseGuardStore(inst);
return true;
}
@@ -1837,8 +1660,7 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
m_decl_map->DoStructLayout();
- if (log)
- log->Printf("Element arrangement:");
+ LLDB_LOG(log, "Element arrangement:");
uint32_t num_elements;
uint32_t element_index;
@@ -1884,9 +1706,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
if (!iter->getName().equals("_cmd")) {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
+ m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
"after 'self' argument (should take '_cmd')",
- iter->getName().str().c_str());
+ iter->getName());
return false;
}
@@ -1905,15 +1727,14 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
if (!argument->getName().equals("$__lldb_arg")) {
- m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
- "argument named '%s' instead of the struct pointer",
- argument->getName().str().c_str());
+ m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
+ "argument named '{0}' instead of the struct pointer",
+ argument->getName());
return false;
}
- if (log)
- log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
+ LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
BasicBlock &entry_block(llvm_function.getEntryBlock());
Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
@@ -1950,13 +1771,11 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
return false;
}
- if (log)
- log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
- decl->getNameAsString().c_str(), offset);
+ LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
+ decl->getNameAsString(), offset);
if (value) {
- if (log)
- log->Printf(" Replacing [%s]", PrintValue(value).c_str());
+ LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
FunctionValueCache body_result_maker(
[this, name, offset_type, offset, argument,
@@ -2005,9 +1824,8 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
value->replaceAllUsesWith(
body_result_maker.GetValue(instruction->getParent()->getParent()));
} else {
- if (log)
- log->Printf("Unhandled non-constant type: \"%s\"",
- PrintValue(value).c_str());
+ LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
+ PrintValue(value));
return false;
}
@@ -2016,35 +1834,12 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
}
}
- if (log)
- log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
- (int64_t)alignment, (uint64_t)size);
+ LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
+ (uint64_t)size);
return true;
}
-llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
- uint64_t offset) {
- llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
-
- llvm::Constant *offset_array[1];
-
- offset_array[0] = offset_int;
-
- llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
- llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
- llvm::Type *char_pointer_type = char_type->getPointerTo();
-
- llvm::Constant *reloc_placeholder_bitcast =
- ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
- llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
- char_type, reloc_placeholder_bitcast, offsets);
- llvm::Constant *reloc_bitcast =
- ConstantExpr::getBitCast(reloc_getelementptr, type);
-
- return reloc_bitcast;
-}
-
bool IRForTarget::runOnModule(Module &llvm_module) {
lldb_private::Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -2062,7 +1857,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+ LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
}
Function *const main_function =
@@ -2070,21 +1865,18 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
: m_module->getFunction(m_func_name.GetStringRef());
if (!m_func_name.IsEmpty() && !main_function) {
- if (log)
- log->Printf("Couldn't find \"%s()\" in the module",
- m_func_name.AsCString());
+ LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
- m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
- "'%s' in the module",
- m_func_name.AsCString());
+ m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
+ "'{0}' in the module",
+ m_func_name);
return false;
}
if (main_function) {
if (!FixFunctionLinkage(*main_function)) {
- if (log)
- log->Printf("Couldn't fix the linkage for the function");
+ LLDB_LOG(log, "Couldn't fix the linkage for the function");
return false;
}
@@ -2104,8 +1896,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
if (main_function) {
if (!CreateResultVariable(*main_function)) {
- if (log)
- log->Printf("CreateResultVariable() failed");
+ LLDB_LOG(log, "CreateResultVariable() failed");
// CreateResultVariable() reports its own errors, so we don't do so here
@@ -2121,32 +1912,21 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module after creating the result variable: \n\"%s\"",
- s.c_str());
+ LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- if (function->begin() == function->end())
- continue;
-
- Function::iterator bbi;
-
- for (bbi = function->begin(); bbi != function->end(); ++bbi) {
- if (!RemoveGuards(*bbi)) {
- if (log)
- log->Printf("RemoveGuards() failed");
+ for (llvm::Function &function : *m_module) {
+ for (BasicBlock &bb : function) {
+ if (!RemoveGuards(bb)) {
+ LLDB_LOG(log, "RemoveGuards() failed");
// RemoveGuards() reports its own errors, so we don't do so here
return false;
}
- if (!RewritePersistentAllocs(*bbi)) {
- if (log)
- log->Printf("RewritePersistentAllocs() failed");
+ if (!RewritePersistentAllocs(bb)) {
+ LLDB_LOG(log, "RewritePersistentAllocs() failed");
// RewritePersistentAllocs() reports its own errors, so we don't do so
// here
@@ -2154,9 +1934,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
return false;
}
- if (!RemoveCXAAtExit(*bbi)) {
- if (log)
- log->Printf("RemoveCXAAtExit() failed");
+ if (!RemoveCXAAtExit(bb)) {
+ LLDB_LOG(log, "RemoveCXAAtExit() failed");
// RemoveCXAAtExit() reports its own errors, so we don't do so here
@@ -2170,24 +1949,17 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
//
if (!RewriteObjCConstStrings()) {
- if (log)
- log->Printf("RewriteObjCConstStrings() failed");
+ LLDB_LOG(log, "RewriteObjCConstStrings() failed");
// RewriteObjCConstStrings() reports its own errors, so we don't do so here
return false;
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- for (llvm::Function::iterator bbi = function->begin(),
- bbe = function->end();
- bbi != bbe; ++bbi) {
- if (!RewriteObjCSelectors(*bbi)) {
- if (log)
- log->Printf("RewriteObjCSelectors() failed");
+ for (llvm::Function &function : *m_module) {
+ for (llvm::BasicBlock &bb : function) {
+ if (!RewriteObjCSelectors(bb)) {
+ LLDB_LOG(log, "RewriteObjCSelectors() failed");
// RewriteObjCSelectors() reports its own errors, so we don't do so
// here
@@ -2195,9 +1967,8 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
return false;
}
- if (!RewriteObjCClassReferences(*bbi)) {
- if (log)
- log->Printf("RewriteObjCClassReferences() failed");
+ if (!RewriteObjCClassReferences(bb)) {
+ LLDB_LOG(log, "RewriteObjCClassReferences() failed");
// RewriteObjCClasses() reports its own errors, so we don't do so here
@@ -2206,16 +1977,10 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
}
}
- for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
- ++fi) {
- llvm::Function *function = &*fi;
-
- for (llvm::Function::iterator bbi = function->begin(),
- bbe = function->end();
- bbi != bbe; ++bbi) {
- if (!ResolveCalls(*bbi)) {
- if (log)
- log->Printf("ResolveCalls() failed");
+ for (llvm::Function &function : *m_module) {
+ for (BasicBlock &bb : function) {
+ if (!ResolveCalls(bb)) {
+ LLDB_LOG(log, "ResolveCalls() failed");
// ResolveCalls() reports its own errors, so we don't do so here
@@ -2230,8 +1995,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
if (main_function) {
if (!ResolveExternals(*main_function)) {
- if (log)
- log->Printf("ResolveExternals() failed");
+ LLDB_LOG(log, "ResolveExternals() failed");
// ResolveExternals() reports its own errors, so we don't do so here
@@ -2239,8 +2003,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
}
if (!ReplaceVariables(*main_function)) {
- if (log)
- log->Printf("ReplaceVariables() failed");
+ LLDB_LOG(log, "ReplaceVariables() failed");
// ReplaceVariables() reports its own errors, so we don't do so here
@@ -2256,7 +2019,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
oss.flush();
- log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
+ LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
}
return true;
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index f87fd8ac32cb..893620f7f8e0 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -10,6 +10,7 @@
#ifndef liblldb_IRForTarget_h_
#define liblldb_IRForTarget_h_
+#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -331,27 +332,6 @@ private:
/// a call to a function pointer whose value is the address of the function
/// in the target process.
- /// Write an initializer to a memory array of assumed sufficient size.
- ///
- /// \param[in] data
- /// A pointer to the data to write to.
- ///
- /// \param[in] initializer
- /// The initializer itself.
- ///
- /// \return
- /// True on success; false otherwise
- bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer);
-
- /// Move an internal variable into the static allocation section.
- ///
- /// \param[in] global_variable
- /// The variable.
- ///
- /// \return
- /// True on success; false otherwise
- bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable);
-
/// Handle a single externally-defined variable
///
/// \param[in] value
@@ -539,20 +519,6 @@ private:
FunctionValueCache &entry_instruction_finder,
lldb_private::Stream &error_stream);
- /// Construct a reference to m_reloc_placeholder with a given type and
- /// offset. This typically happens after inserting data into
- /// m_data_allocator.
- ///
- /// \param[in] type
- /// The type of the value being loaded.
- ///
- /// \param[in] offset
- /// The offset of the value from the base of m_data_allocator.
- ///
- /// \return
- /// The Constant for the reference, usually a ConstantExpr.
- llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
-
/// Commit the allocation in m_data_allocator and use its final location to
/// replace m_reloc_placeholder.
///
diff --git a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
index 0e959f86fd2a..7553860f2492 100644
--- a/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
+++ b/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
@@ -9,21 +9,23 @@
#ifndef liblldb_ModuleDependencyCollector_h_
#define liblldb_ModuleDependencyCollector_h_
-#include "lldb/Utility/FileCollector.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileCollector.h"
namespace lldb_private {
class ModuleDependencyCollectorAdaptor
: public clang::ModuleDependencyCollector {
public:
- ModuleDependencyCollectorAdaptor(FileCollector &file_collector)
+ ModuleDependencyCollectorAdaptor(
+ std::shared_ptr<llvm::FileCollector> file_collector)
: clang::ModuleDependencyCollector(""), m_file_collector(file_collector) {
}
void addFile(llvm::StringRef Filename,
llvm::StringRef FileDst = {}) override {
- m_file_collector.AddFile(Filename);
+ if (m_file_collector)
+ m_file_collector->addFile(Filename);
}
bool insertSeen(llvm::StringRef Filename) override { return false; }
@@ -31,7 +33,7 @@ public:
void writeFileMap() override {}
private:
- FileCollector &m_file_collector;
+ std::shared_ptr<llvm::FileCollector> m_file_collector;
};
} // namespace lldb_private
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 6323889c2e09..19a987b0f004 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -14507,6 +14507,7 @@ bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
unwind_plan.SetSourceName("EmulateInstructionARM");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_lr);
return true;
}
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index d7e8e0491342..3e06fca2504c 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -149,7 +149,8 @@ EmulateInstructionARM64::CreateInstance(const ArchSpec &arch,
InstructionType inst_type) {
if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(
inst_type)) {
- if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
return new EmulateInstructionARM64(arch);
}
}
@@ -479,6 +480,7 @@ bool EmulateInstructionARM64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionARM64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_arm64);
return true;
}
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index cbf3dda7896e..21b6296745bd 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -1150,6 +1150,7 @@ bool EmulateInstructionMIPS::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionMIPS");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips);
return true;
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 69f0278d1437..5fabbeb756cc 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -1042,6 +1042,7 @@ bool EmulateInstructionMIPS64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionMIPS64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(dwarf_ra_mips64);
return true;
diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index c77fa04fc7d7..4b8d8dd2228c 100644
--- a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -135,6 +135,7 @@ bool EmulateInstructionPPC64::CreateFunctionEntryUnwind(
unwind_plan.SetSourceName("EmulateInstructionPPC64");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le);
return true;
}
diff --git a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
index c8ac04641e68..2e5dd5989e77 100644
--- a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
@@ -264,7 +264,7 @@ bool AddressSanitizerRuntime::NotifyBreakpointHit(
*thread_sp, description, report));
StreamFileSP stream_sp(
- process_sp->GetTarget().GetDebugger().GetOutputFile());
+ process_sp->GetTarget().GetDebugger().GetOutputStreamSP());
if (stream_sp) {
stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
"info -s' to get extended information about the "
diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
index 89f2139db71b..45a3aeeb204e 100644
--- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
@@ -863,13 +863,11 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit(
CreateStopReasonWithInstrumentationData(
*thread_sp, stop_reason_description, report));
- StreamFileSP stream_sp(
- process_sp->GetTarget().GetDebugger().GetOutputFile());
- if (stream_sp) {
- stream_sp->Printf("ThreadSanitizer report breakpoint hit. Use 'thread "
- "info -s' to get extended information about the "
- "report.\n");
- }
+ StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream();
+ s.Printf("ThreadSanitizer report breakpoint hit. Use 'thread "
+ "info -s' to get extended information about the "
+ "report.\n");
+
return true; // Return true to stop the target
} else
return false; // Let target run
diff --git a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
index 367098bb448e..50f1d48d03e0 100644
--- a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
@@ -124,7 +124,7 @@ StructuredData::ObjectSP UndefinedBehaviorSanitizerRuntime::RetrieveReportData(
if (!frame_sp)
return StructuredData::ObjectSP();
- StreamFileSP Stream(target.GetDebugger().GetOutputFile());
+ StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP();
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 140d09ed43cf..fff44123539f 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -6,9 +6,8 @@
//
//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/MathExtras.h"
-
+#include "JITLoaderGDB.h"
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -26,8 +25,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
-
-#include "JITLoaderGDB.h"
+#include "llvm/Support/MathExtras.h"
#include <memory>
@@ -59,21 +57,33 @@ enum EnableJITLoaderGDB {
eEnableJITLoaderGDBOff,
};
-static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] = {
- {eEnableJITLoaderGDBDefault, "default", "Enable JIT compilation interface "
- "for all platforms except macOS"},
- {eEnableJITLoaderGDBOn, "on", "Enable JIT compilation interface"},
- {eEnableJITLoaderGDBOff, "off", "Disable JIT compilation interface"}
- };
+static constexpr OptionEnumValueElement g_enable_jit_loader_gdb_enumerators[] =
+ {
+ {
+ eEnableJITLoaderGDBDefault,
+ "default",
+ "Enable JIT compilation interface for all platforms except macOS",
+ },
+ {
+ eEnableJITLoaderGDBOn,
+ "on",
+ "Enable JIT compilation interface",
+ },
+ {
+ eEnableJITLoaderGDBOff,
+ "off",
+ "Disable JIT compilation interface",
+ },
+};
-static constexpr PropertyDefinition g_properties[] = {
- {"enable", OptionValue::eTypeEnum, true,
- eEnableJITLoaderGDBDefault, nullptr,
- OptionEnumValues(g_enable_jit_loader_gdb_enumerators),
- "Enable GDB's JIT compilation interface (default: enabled on "
- "all platforms except macOS)"}};
+#define LLDB_PROPERTIES_jitloadergdb
+#include "JITLoaderGDBProperties.inc"
-enum { ePropertyEnable, ePropertyEnableJITBreakpoint };
+enum {
+#define LLDB_PROPERTIES_jitloadergdb
+#include "JITLoaderGDBPropertiesEnum.inc"
+ ePropertyEnableJITBreakpoint
+};
class PluginProperties : public Properties {
public:
@@ -83,13 +93,13 @@ public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_jitloadergdb_properties);
}
EnableJITLoaderGDB GetEnable() const {
return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration(
nullptr, ePropertyEnable,
- g_properties[ePropertyEnable].default_uint_value);
+ g_jitloadergdb_properties[ePropertyEnable].default_uint_value);
}
};
@@ -177,8 +187,8 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
return;
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s looking for JIT register hook", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s looking for JIT register hook",
+ __FUNCTION__);
addr_t jit_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
@@ -188,14 +198,12 @@ void JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) {
m_jit_descriptor_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to find JIT descriptor address",
- __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to find JIT descriptor address",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s setting JIT breakpoint", __FUNCTION__);
Breakpoint *bp =
m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get();
@@ -211,8 +219,7 @@ bool JITLoaderGDB::JITDebugBreakpointHit(void *baton,
user_id_t break_id,
user_id_t break_loc_id) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
- if (log)
- log->Printf("JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s hit JIT breakpoint", __FUNCTION__);
JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton);
return instance->ReadJITDescriptor(false);
}
@@ -285,9 +292,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
jit_desc_size, error);
if (bytes_read != jit_desc_size || !error.Success()) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to read JIT descriptor",
- __FUNCTION__);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
+ __FUNCTION__);
return false;
}
@@ -301,9 +307,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
while (jit_relevant_entry != 0) {
jit_code_entry<ptr_t> jit_entry;
if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
- __FUNCTION__, jit_relevant_entry);
+ LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64,
+ __FUNCTION__, jit_relevant_entry);
return false;
}
@@ -312,10 +317,10 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
ModuleSP module_sp;
if (jit_action == JIT_REGISTER_FN) {
- if (log)
- log->Printf("JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
- " (%" PRIu64 " bytes)",
- __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
+ LLDB_LOGF(log,
+ "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64
+ " (%" PRIu64 " bytes)",
+ __FUNCTION__, symbolfile_addr, (uint64_t)symbolfile_size);
char jit_name[64];
snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
@@ -331,20 +336,16 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
module_sp->GetObjectFile()->GetSymtab();
m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
- if (module_sp->GetObjectFile()->GetPluginName() ==
- ConstString("mach-o")) {
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file) {
- const SectionList *section_list =
- image_object_file->GetSectionList();
- if (section_list) {
- uint64_t vmaddrheuristic = 0;
- uint64_t lower = (uint64_t)-1;
- uint64_t upper = 0;
- updateSectionLoadAddress(*section_list, target, symbolfile_addr,
- symbolfile_size, vmaddrheuristic, lower,
- upper);
- }
+ if (auto image_object_file =
+ llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) {
+ const SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ uint64_t vmaddrheuristic = 0;
+ uint64_t lower = (uint64_t)-1;
+ uint64_t upper = 0;
+ updateSectionLoadAddress(*section_list, target, symbolfile_addr,
+ symbolfile_size, vmaddrheuristic, lower,
+ upper);
}
} else {
bool changed = false;
@@ -357,15 +358,14 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
module_list.Append(module_sp);
target.ModulesDidLoad(module_list);
} else {
- if (log)
- log->Printf("JITLoaderGDB::%s failed to load module for "
- "JIT entry at 0x%" PRIx64,
- __FUNCTION__, symbolfile_addr);
+ LLDB_LOGF(log,
+ "JITLoaderGDB::%s failed to load module for "
+ "JIT entry at 0x%" PRIx64,
+ __FUNCTION__, symbolfile_addr);
}
} else if (jit_action == JIT_UNREGISTER_FN) {
- if (log)
- log->Printf("JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
- __FUNCTION__, symbolfile_addr);
+ LLDB_LOGF(log, "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64,
+ __FUNCTION__, symbolfile_addr);
JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr);
if (it != m_jit_objects.end()) {
@@ -458,8 +458,8 @@ addr_t JITLoaderGDB::GetSymbolAddress(ModuleList &module_list,
SymbolContextList target_symbols;
Target &target = m_process->GetTarget();
- if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
- target_symbols))
+ module_list.FindSymbolsWithNameAndType(name, symbol_type, target_symbols);
+ if (target_symbols.IsEmpty())
return LLDB_INVALID_ADDRESS;
SymbolContext sym_ctx;
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td
new file mode 100644
index 000000000000..0493838bc85d
--- /dev/null
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td
@@ -0,0 +1,9 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "jitloadergdb" in {
+ def Enable: Property<"enable", "Enum">,
+ Global,
+ DefaultEnumValue<"eEnableJITLoaderGDBDefault">,
+ EnumValues<"OptionEnumValues(g_enable_jit_loader_gdb_enumerators)">,
+ Desc<"Enable GDB's JIT compilation interface (default: enabled on all platforms except macOS)">;
+}
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 87b5b5947f35..5cfd978774fd 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -17,6 +17,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,16 +40,17 @@ public:
return;
}
- Status err;
- TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
- &err, lldb::eLanguageTypeC_plus_plus);
-
- if (!err.Success() || !type_system) {
+ auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(
+ lldb::eLanguageTypeC_plus_plus);
+ 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");
return;
}
ClangASTContext *clang_ast_context =
- llvm::dyn_cast<ClangASTContext>(type_system);
+ llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_context) {
return;
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 44b9e5e24ccd..489fa7d0ad91 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -486,8 +486,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp,
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
"libc++ std::list synthetic children",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), stl_deref_flags,
- true);
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_deref_flags, true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
@@ -547,8 +550,8 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"))),
+ RegularExpression(
+ llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
@@ -566,12 +569,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
stl_synth_flags, true);
- AddCXXSummary(
- cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider,
- "libc++ std::function summary provider",
- ConstString("^std::__[[:alnum:]]+::function<.+>$"), stl_summary_flags,
- true);
-
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
AddCXXSummary(cpp_category_sp,
@@ -589,11 +586,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::list summary provider",
ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxContainerSummaryProvider,
- "libc++ std::list summary provider",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"),
- stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::map summary provider",
@@ -750,38 +750,32 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
false);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(true);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -860,6 +854,14 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
// FIXME because of a bug in the FormattersContainer we need to add a summary
// for both X* and const X* (<rdar://problem/12717717>)
AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t * summary provider", ConstString("char8_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t [] summary provider",
+ ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
"char16_t * summary provider", ConstString("char16_t *"), string_flags);
AddCXXSummary(cpp_category_sp,
@@ -896,6 +898,9 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
.SetHideItemNames(true)
.SetShowMembersOneLiner(false);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
+ "char8_t summary provider", ConstString("char8_t"),
+ widechar_flags);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
"char16_t summary provider", ConstString("char16_t"), widechar_flags);
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 959079070acc..3ea7589d8e4a 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -32,6 +32,31 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+bool lldb_private::formatters::Char8StringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options)) {
+ stream.Printf("Summary Unavailable");
+ return true;
+ }
+
+ return true;
+}
+
bool lldb_private::formatters::Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
ProcessSP process_sp = valobj.GetProcessSP();
@@ -128,6 +153,32 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
return true;
}
+bool lldb_private::formatters::Char8SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Status error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode8, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+}
+
bool lldb_private::formatters::Char16SummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
DataExtractor data;
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
index 92bef2382eac..35498b3b568f 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
@@ -16,6 +16,9 @@
namespace lldb_private {
namespace formatters {
+bool Char8StringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t*
+
bool Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t* and unichar*
@@ -27,6 +30,9 @@ bool Char32StringSummaryProvider(
bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // wchar_t*
+bool Char8SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t
+
bool Char16SummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t and unichar
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 815dafb6c724..78c453cd1b3c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -30,8 +30,15 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ // Value objects created from raw data (i.e. in a different cluster) must
+ // be referenced via shared pointer to keep them alive, however.
std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_first;
+ ValueObject* m_first = nullptr;
CompilerType m_bool_type;
ByteOrder m_byte_order = eByteOrderInvalid;
uint8_t m_byte_size = 0;
@@ -50,7 +57,7 @@ BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
bool BitsetFrontEnd::Update() {
m_elements.clear();
- m_first.reset();
+ m_first = nullptr;
TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
@@ -63,7 +70,7 @@ bool BitsetFrontEnd::Update() {
m_elements.assign(size, ValueObjectSP());
- m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
+ m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get();
return false;
}
@@ -86,7 +93,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
} else {
type = m_first->GetCompilerType();
- chunk = m_first;
+ chunk = m_first->GetSP();
}
if (!type || !chunk)
return {};
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index 116021588848..b1ad171d0b0c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -31,7 +31,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
index 4b72089c6ba2..2f06d684f953 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -38,16 +38,21 @@ public:
}
private:
- ValueObjectSP m_container_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_container_sp = nullptr;
};
} // namespace
bool QueueFrontEnd::Update() {
- m_container_sp.reset();
+ m_container_sp = nullptr;
ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
if (!c_sp)
return false;
- m_container_sp = c_sp->GetSyntheticValue();
+ m_container_sp = c_sp->GetSyntheticValue().get();
return false;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
index 8da7460f2275..45294e25f0f5 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -30,47 +30,58 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
- std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_base_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_elements;
+ ValueObject* m_base = nullptr;
};
}
bool TupleFrontEnd::Update() {
m_elements.clear();
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
- if (! m_base_sp) {
+ m_base = nullptr;
+
+ ValueObjectSP base_sp;
+ base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
+ if (!base_sp) {
// Pre r304382 name of the base element.
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
+ base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
}
- if (! m_base_sp)
+ if (!base_sp)
return false;
- m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(),
- ValueObjectSP());
+ m_base = base_sp.get();
+ m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
+ nullptr);
return false;
}
ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
if (idx >= m_elements.size())
return ValueObjectSP();
- if (!m_base_sp)
+ if (!m_base)
return ValueObjectSP();
if (m_elements[idx])
- return m_elements[idx];
+ return m_elements[idx]->GetSP();
CompilerType holder_type =
- m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
+ m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
if (!holder_type)
return ValueObjectSP();
- ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true);
+ ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true);
if (!holder_sp)
return ValueObjectSP();
ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
if (elem_sp)
m_elements[idx] =
- elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str()));
+ elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
- return m_elements[idx];
+ if (m_elements[idx])
+ return m_elements[idx]->GetSP();
+ return ValueObjectSP();
}
SyntheticChildrenFrontEnd *
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
index 491cf048e459..62945bd3ce80 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
@@ -184,7 +184,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
index 66624e5beb6d..0ac7b8f8e02b 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -37,7 +37,12 @@ public:
size_t GetIndexOfChildWithName(ConstString name) override;
private:
- std::vector<ValueObjectSP> m_members;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_members;
};
} // end of anonymous namespace
@@ -72,7 +77,7 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() {
if (value_sp) {
StreamString name;
name.Printf("[%zd]", m_members.size());
- m_members.push_back(value_sp->Clone(ConstString(name.GetString())));
+ m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get());
}
}
}
@@ -85,8 +90,8 @@ bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx < m_members.size())
- return m_members[idx];
+ if (idx < m_members.size() && m_members[idx])
+ return m_members[idx]->GetSP();
return lldb::ValueObjectSP();
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index 3860f960cb3d..cceb511cdc46 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -39,9 +39,14 @@ public:
bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
private:
- ValueObjectSP m_ptr_obj;
- ValueObjectSP m_obj_obj;
- ValueObjectSP m_del_obj;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_ptr_obj = nullptr;
+ ValueObject* m_obj_obj = nullptr;
+ ValueObject* m_del_obj = nullptr;
ValueObjectSP GetTuple();
};
@@ -92,17 +97,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
if (ptr_obj)
- m_ptr_obj = ptr_obj->Clone(ConstString("pointer"));
+ m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
if (del_obj)
- m_del_obj = del_obj->Clone(ConstString("deleter"));
+ m_del_obj = del_obj->Clone(ConstString("deleter")).get();
if (m_ptr_obj) {
Status error;
ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
if (error.Success()) {
- m_obj_obj = obj_obj->Clone(ConstString("object"));
+ m_obj_obj = obj_obj->Clone(ConstString("object")).get();
}
}
@@ -113,12 +118,12 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx == 0)
- return m_ptr_obj;
- if (idx == 1)
- return m_del_obj;
- if (idx == 2)
- return m_obj_obj;
+ if (idx == 0 && m_ptr_obj)
+ return m_ptr_obj->GetSP();
+ if (idx == 1 && m_del_obj)
+ return m_del_obj->GetSP();
+ if (idx == 2 && m_obj_obj)
+ return m_obj_obj->GetSP();
return lldb::ValueObjectSP();
}
diff --git a/source/Plugins/Language/ObjC/CoreMedia.cpp b/source/Plugins/Language/ObjC/CoreMedia.cpp
index d19290ec56fb..247429da1b06 100644
--- a/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -10,6 +10,7 @@
#include "CoreMedia.h"
#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
@@ -25,18 +26,21 @@ bool lldb_private::formatters::CMTimeSummaryProvider(
if (!type.IsValid())
return false;
- TypeSystem *type_system =
+ auto type_system_or_err =
valobj.GetExecutionContextRef()
.GetTargetSP()
- ->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
- if (!type_system)
+ ->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
+ std::move(err), "Failed to get scratch type system");
return false;
-
+ }
// fetch children by offset to compensate for potential lack of debug info
- auto int64_ty =
- type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
- auto int32_ty =
- type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
+ auto int64_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingSint, 64);
+ auto int32_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
+ eEncodingSint, 32);
auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 404dabf2870c..7219c016dfd1 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -461,12 +461,13 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
if (valobj_sp) {
- clang::ASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext()
- ->getASTContext();
- if (ast)
- m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
+ auto *clang_ast_context = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (clang_ast_context)
+ m_id_type = CompilerType(
+ clang_ast_context,
+ clang_ast_context->getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr());
if (valobj_sp->GetProcessSP())
m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
}
@@ -609,12 +610,13 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
if (valobj_sp) {
CompilerType type = valobj_sp->GetCompilerType();
if (type) {
- ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchClangASTContext();
- if (ast)
- m_id_type = CompilerType(ast->getASTContext(),
- ast->getASTContext()->ObjCBuiltinIdTy);
+ auto *clang_ast_context = valobj_sp->GetExecutionContextRef()
+ .GetTargetSP()
+ ->GetScratchClangASTContext();
+ if (clang_ast_context)
+ m_id_type = CompilerType(clang_ast_context,
+ clang_ast_context->getASTContext()
+ ->ObjCBuiltinIdTy.getAsOpaquePtr());
}
}
}
diff --git a/source/Plugins/Language/ObjC/NSDictionary.h b/source/Plugins/Language/ObjC/NSDictionary.h
index ecb3fccdf877..44d56f9c2c68 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.h
+++ b/source/Plugins/Language/ObjC/NSDictionary.h
@@ -68,10 +68,10 @@ public:
};
typedef Matcher::UP MatcherUP;
- MatcherUP GetFullMatch(ConstString n) { return llvm::make_unique<Full>(n); }
+ MatcherUP GetFullMatch(ConstString n) { return std::make_unique<Full>(n); }
MatcherUP GetPrefixMatch(ConstString p) {
- return llvm::make_unique<Prefix>(p);
+ return std::make_unique<Prefix>(p);
}
};
diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp
index 4800c955e5f5..55e129b098dc 100644
--- a/source/Plugins/Language/ObjC/NSString.cpp
+++ b/source/Plugins/Language/ObjC/NSString.cpp
@@ -78,12 +78,12 @@ bool lldb_private::formatters::NSStringSummaryProvider(
return false;
ConstString class_name_cs = descriptor->GetClassName();
- const char *class_name = class_name_cs.GetCString();
+ llvm::StringRef class_name = class_name_cs.GetStringRef();
- if (!class_name || !*class_name)
+ if (class_name.empty())
return false;
- bool is_tagged_ptr = (0 == strcmp(class_name, "NSTaggedPointerString")) &&
+ bool is_tagged_ptr = class_name == "NSTaggedPointerString" &&
descriptor->GetTaggedPointerInfo();
// for a tagged pointer, the descriptor has everything we need
if (is_tagged_ptr)
@@ -111,7 +111,7 @@ bool lldb_private::formatters::NSStringSummaryProvider(
bool is_inline = (info_bits & 0x60) == 0;
bool has_explicit_length = (info_bits & (1 | 4)) != 4;
bool is_unicode = (info_bits & 0x10) == 0x10;
- bool is_path_store = strcmp(class_name, "NSPathStore2") == 0;
+ bool is_path_store = class_name == "NSPathStore2";
bool has_null = (info_bits & 8) == 8;
size_t explicit_length = 0;
@@ -135,14 +135,14 @@ bool lldb_private::formatters::NSStringSummaryProvider(
}
}
- if (strcmp(class_name, "NSString") && strcmp(class_name, "CFStringRef") &&
- strcmp(class_name, "CFMutableStringRef") &&
- strcmp(class_name, "__NSCFConstantString") &&
- strcmp(class_name, "__NSCFString") &&
- strcmp(class_name, "NSCFConstantString") &&
- strcmp(class_name, "NSCFString") && strcmp(class_name, "NSPathStore2")) {
+ const llvm::StringSet<> supported_string_classes = {
+ "NSString", "CFMutableStringRef",
+ "CFStringRef", "__NSCFConstantString",
+ "__NSCFString", "NSCFConstantString",
+ "NSCFString", "NSPathStore2"};
+ if (supported_string_classes.count(class_name) == 0) {
// not one of us - but tell me class name
- stream.Printf("class name = %s", class_name);
+ stream.Printf("class name = %s", class_name_cs.GetCString());
return true;
}
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index f9ab18688de7..c5bfb5747c13 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/Threading.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
#include "CF.h"
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index b392282c3eb1..f38014505a8b 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -231,7 +231,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
SymbolContextList scl;
target.GetImages().FindSymbolsMatchingRegExAndType(
- RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl, true);
+ RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl);
// Case 1,2 or 3
if (scl.GetSize() >= 1) {
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 41f38a4e3dcd..02e62a263286 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -79,11 +79,10 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
if (name && strstr(name, vtable_demangled_prefix) == name) {
Log *log(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("0x%16.16" PRIx64
- ": static-type = '%s' has vtable symbol '%s'\n",
- original_ptr, in_value.GetTypeName().GetCString(),
- name);
+ LLDB_LOGF(log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has vtable symbol '%s'\n",
+ original_ptr, in_value.GetTypeName().GetCString(), name);
// We are a C++ class, that's good. Get the class name and look it
// up:
const char *class_name = name + strlen(vtable_demangled_prefix);
@@ -96,87 +95,81 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
const bool exact_match = true;
TypeList class_types;
- uint32_t num_matches = 0;
// First look in the module that the vtable symbol came from and
// look for a single exact match.
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- if (sc.module_sp) {
- num_matches = sc.module_sp->FindTypes(
- ConstString(lookup_name), exact_match, 1,
- searched_symbol_files, class_types);
- }
+ if (sc.module_sp)
+ sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+ searched_symbol_files, class_types);
// If we didn't find a symbol, then move on to the entire module
// list in the target and get as many unique matches as possible
- if (num_matches == 0) {
- num_matches = target.GetImages().FindTypes(
- nullptr, ConstString(lookup_name), exact_match, UINT32_MAX,
- searched_symbol_files, class_types);
- }
+ if (class_types.Empty())
+ target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
+ exact_match, UINT32_MAX,
+ searched_symbol_files, class_types);
lldb::TypeSP type_sp;
- if (num_matches == 0) {
- if (log)
- log->Printf("0x%16.16" PRIx64 ": is not dynamic\n",
- original_ptr);
+ if (class_types.Empty()) {
+ LLDB_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
+ original_ptr);
return TypeAndOrName();
}
- if (num_matches == 1) {
+ if (class_types.GetSize() == 1) {
type_sp = class_types.GetTypeAtIndex(0);
if (type_sp) {
if (ClangASTContext::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
- if (log)
- log->Printf(
- "0x%16.16" PRIx64
- ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
- "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
type_info.SetTypeSP(type_sp);
}
}
- } else if (num_matches > 1) {
+ } else {
size_t i;
if (log) {
- for (i = 0; i < num_matches; i++) {
+ for (i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
- if (log)
- log->Printf(
- "0x%16.16" PRIx64
- ": static-type = '%s' has multiple matching dynamic "
- "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
}
}
}
- for (i = 0; i < num_matches; i++) {
+ for (i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
if (ClangASTContext::IsCXXClassType(
type_sp->GetForwardCompilerType())) {
- if (log)
- log->Printf(
- "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
- "matching dynamic types, picking "
- "this one: uid={0x%" PRIx64
- "}, type-name='%s'\n",
- original_ptr, in_value.GetTypeName().AsCString(),
- type_sp->GetID(), type_sp->GetName().GetCString());
+ LLDB_LOGF(
+ log,
+ "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+ "matching dynamic types, picking "
+ "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(),
+ type_sp->GetID(), type_sp->GetName().GetCString());
type_info.SetTypeSP(type_sp);
}
}
}
- if (log && i == num_matches) {
- log->Printf(
- "0x%16.16" PRIx64
- ": static-type = '%s' has multiple matching dynamic "
- "types, didn't find a C++ match\n",
- original_ptr, in_value.GetTypeName().AsCString());
+ if (log) {
+ LLDB_LOGF(log,
+ "0x%16.16" PRIx64
+ ": static-type = '%s' has multiple matching dynamic "
+ "types, didn't find a C++ match\n",
+ original_ptr, in_value.GetTypeName().AsCString());
}
}
if (type_info)
@@ -351,7 +344,7 @@ protected:
bool demangled_any = false;
bool error_any = false;
for (auto &entry : command.entries()) {
- if (entry.ref.empty())
+ if (entry.ref().empty())
continue;
// the actual Mangled class should be strict about this, but on the
@@ -359,21 +352,21 @@ protected:
// they will come out with an extra underscore - be willing to strip this
// on behalf of the user. This is the moral equivalent of the -_/-n
// options to c++filt
- auto name = entry.ref;
+ auto name = entry.ref();
if (name.startswith("__Z"))
name = name.drop_front();
- Mangled mangled(name, true);
+ Mangled mangled(name);
if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) {
ConstString demangled(
mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
demangled_any = true;
- result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(),
+ result.AppendMessageWithFormat("%s ---> %s\n", entry.c_str(),
demangled.GetCString());
} else {
error_any = true;
result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n",
- entry.ref.str().c_str());
+ entry.ref().str().c_str());
}
}
@@ -471,8 +464,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {
if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
// Limit the number of modules that are searched for these breakpoints for
// Apple binaries.
- filter_modules.Append(FileSpec("libc++abi.dylib"));
- filter_modules.Append(FileSpec("libSystem.B.dylib"));
+ filter_modules.EmplaceBack("libc++abi.dylib");
+ filter_modules.EmplaceBack("libSystem.B.dylib");
}
return target.GetSearchFilterForModuleList(&filter_modules);
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 18f2a1829a41..1f27a4f0b3ed 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -38,12 +38,13 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
- "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
- current_id,
- static_cast<void *>(&decl_ctx->getParentASTContext()),
- name.getAsString().c_str(), decl_ctx->getDeclKindName(),
- static_cast<const void *>(decl_ctx));
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName[%"
+ "u] on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
+ current_id,
+ static_cast<void *>(&decl_ctx->getParentASTContext()),
+ name.getAsString().c_str(), decl_ctx->getDeclKindName(),
+ static_cast<const void *>(decl_ctx));
}
do {
@@ -77,19 +78,20 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] on "
- "(ASTContext*)%p Completing (TagDecl*)%p named %s",
- current_id, static_cast<void *>(&tag_decl->getASTContext()),
- static_cast<void *>(tag_decl),
- tag_decl->getName().str().c_str());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::CompleteType[%u] on "
+ "(ASTContext*)%p Completing (TagDecl*)%p named %s",
+ current_id, static_cast<void *>(&tag_decl->getASTContext()),
+ static_cast<void *>(tag_decl),
+ tag_decl->getName().str().c_str());
+
+ LLDB_LOGF(log, " AOEAS::CT[%u] Before:", current_id);
ASTDumper dumper((clang::Decl *)tag_decl);
dumper.ToLog(log, " [CT] ");
}
if (log) {
- log->Printf(" AOEAS::CT[%u] After:", current_id);
+ LLDB_LOGF(log, " AOEAS::CT[%u] After:", current_id);
ASTDumper dumper((clang::Decl *)tag_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -104,14 +106,15 @@ public:
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log) {
- log->Printf("AppleObjCExternalASTSource::CompleteType[%u] 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());
-
- log->Printf(" AOEAS::CT[%u] Before:", current_id);
+ LLDB_LOGF(log,
+ "AppleObjCExternalASTSource::CompleteType[%u] 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);
ASTDumper dumper((clang::Decl *)interface_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -119,7 +122,7 @@ public:
m_decl_vendor.FinishDecl(interface_decl);
if (log) {
- log->Printf(" [CT] After:");
+ LLDB_LOGF(log, " [CT] After:");
ASTDumper dumper((clang::Decl *)interface_decl);
dumper.ToLog(log, " [CT] ");
}
@@ -148,12 +151,13 @@ private:
};
AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
- : DeclVendor(), m_runtime(runtime), m_ast_ctx(runtime.GetProcess()
- ->GetTarget()
- .GetArchitecture()
- .GetTriple()
- .getTriple()
- .c_str()),
+ : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime),
+ m_ast_ctx(runtime.GetProcess()
+ ->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .getTriple()
+ .c_str()),
m_type_realizer_sp(m_runtime.GetEncodingToType()) {
m_external_source = new AppleObjCExternalASTSource(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
@@ -462,8 +466,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
clang::ObjCMethodDecl *method_decl =
method_type.BuildMethod(interface_decl, name, true, m_type_realizer_sp);
- if (log)
- log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name, types);
+ LLDB_LOGF(log, "[ AOTV::FD] Instance method [%s] [%s]", name, types);
if (method_decl)
interface_decl->addDecl(method_decl);
@@ -481,8 +484,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
interface_decl, name, false, m_type_realizer_sp);
- if (log)
- log->Printf("[ AOTV::FD] Class method [%s] [%s]", name, types);
+ LLDB_LOGF(log, "[ AOTV::FD] Class method [%s] [%s]", name, types);
if (method_decl)
interface_decl->addDecl(method_decl);
@@ -498,10 +500,9 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
const bool for_expression = false;
- if (log)
- log->Printf(
- "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name,
- type, offset_ptr);
+ LLDB_LOGF(log,
+ "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
+ name, type, offset_ptr);
CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(
m_ast_ctx, type, for_expression);
@@ -527,9 +528,10 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
if (log) {
ASTDumper method_dumper((clang::Decl *)interface_decl);
- log->Printf("[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
- "interface for %s",
- descriptor->GetClassName().AsCString());
+ LLDB_LOGF(log,
+ "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
+ "interface for %s",
+ descriptor->GetClassName().AsCString());
}
if (!descriptor->Describe(superclass_func, instance_method_func,
@@ -539,7 +541,8 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
if (log) {
ASTDumper method_dumper((clang::Decl *)interface_decl);
- log->Printf(
+ LLDB_LOGF(
+ log,
"[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
method_dumper.ToLog(log, " [AOTV::FD] ");
@@ -558,10 +561,9 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
Log *log(GetLogIfAllCategoriesSet(
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- if (log)
- log->Printf("AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
- current_id, (const char *)name.AsCString(),
- append ? "true" : "false", max_matches);
+ LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
+ current_id, (const char *)name.AsCString(),
+ append ? "true" : "false", max_matches);
if (!append)
decls.clear();
@@ -595,24 +597,25 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
if (metadata)
isa_value = metadata->GetISAPtr();
- log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
- ") in the ASTContext",
- current_id, dumper.GetCString(), isa_value);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] Found %s (isa 0x%" PRIx64
+ ") in the ASTContext",
+ current_id, dumper.GetCString(), isa_value);
}
decls.push_back(result_iface_decl);
ret++;
break;
} else {
- if (log)
- log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but "
- "it's not something we know about",
- current_id);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] There's something in the ASTContext, but "
+ "it's not something we know about",
+ current_id);
break;
}
} else if (log) {
- log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
- current_id, name.AsCString());
+ LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find %s in the ASTContext",
+ current_id, name.AsCString());
}
// It's not. If it exists, we have to put it into our ASTContext.
@@ -620,8 +623,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
if (!isa) {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't find the isa", current_id);
+ LLDB_LOGF(log, "AOCTV::FT [%u] Couldn't find the isa", current_id);
break;
}
@@ -629,10 +631,10 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa);
if (!iface_decl) {
- if (log)
- log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for "
- "isa 0x%" PRIx64,
- current_id, (uint64_t)isa);
+ LLDB_LOGF(log,
+ "AOCTV::FT [%u] Couldn't get the Objective-C interface for "
+ "isa 0x%" PRIx64,
+ current_id, (uint64_t)isa);
break;
}
@@ -641,8 +643,8 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::QualType new_iface_type =
ast_ctx->getObjCInterfaceType(iface_decl);
ASTDumper dumper(new_iface_type);
- log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")", current_id,
- dumper.GetCString(), (uint64_t)isa);
+ LLDB_LOGF(log, "AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")",
+ current_id, dumper.GetCString(), (uint64_t)isa);
}
decls.push_back(iface_decl);
@@ -655,8 +657,7 @@ AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
clang::ExternalASTMerger::ImporterSource
AppleObjCDeclVendor::GetImporterSource() {
- return {*m_ast_ctx.getASTContext(),
- *m_ast_ctx.getFileManager(),
- m_ast_ctx.GetOriginMap()
- };
+ return clang::ExternalASTMerger::ImporterSource(*m_ast_ctx.getASTContext(),
+ *m_ast_ctx.getFileManager(),
+ m_ast_ctx.GetOriginMap());
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index 77b30b7fde79..99ca4b748709 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -10,19 +10,23 @@
#define liblldb_AppleObjCDeclVendor_h_
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/DeclVendor.h"
#include "lldb/lldb-private.h"
+#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
namespace lldb_private {
class AppleObjCExternalASTSource;
-class AppleObjCDeclVendor : public DeclVendor {
+class AppleObjCDeclVendor : public ClangDeclVendor {
public:
AppleObjCDeclVendor(ObjCLanguageRuntime &runtime);
+ static bool classof(const DeclVendor *vendor) {
+ return vendor->GetKind() == eAppleObjCDeclVendor;
+ }
+
uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) override;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 52ed3628520f..8ca9ad7b843a 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -223,11 +223,14 @@ Address *AppleObjCRuntime::GetPrintForDebuggerAddr() {
SymbolContextList contexts;
SymbolContext context;
- if ((!modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"),
- eSymbolTypeCode, contexts)) &&
- (!modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"),
- eSymbolTypeCode, contexts)))
- return nullptr;
+ modules.FindSymbolsWithNameAndType(ConstString("_NSPrintForDebugger"),
+ eSymbolTypeCode, contexts);
+ if (contexts.IsEmpty()) {
+ modules.FindSymbolsWithNameAndType(ConstString("_CFPrintForDebugger"),
+ eSymbolTypeCode, contexts);
+ if (contexts.IsEmpty())
+ return nullptr;
+ }
contexts.GetContextAtIndex(0, context);
@@ -444,10 +447,12 @@ bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() {
SymbolContextList sc_list;
- return target.GetImages().FindSymbolsWithNameAndType(
- s_method_signature, eSymbolTypeCode, sc_list) ||
- target.GetImages().FindSymbolsWithNameAndType(
- s_arclite_method_signature, eSymbolTypeCode, sc_list);
+ target.GetImages().FindSymbolsWithNameAndType(s_method_signature,
+ eSymbolTypeCode, sc_list);
+ if (sc_list.IsEmpty())
+ target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature,
+ eSymbolTypeCode, sc_list);
+ return !sc_list.IsEmpty();
}
lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index c8884fd5c9b9..88bfe2ce0203 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -395,10 +395,11 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
- " from _objc_debug_class_hash to "
- "isa->descriptor cache",
- isa);
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
+ " from _objc_debug_class_hash to "
+ "isa->descriptor cache",
+ isa);
AddClass(isa, descriptor_sp);
}
@@ -417,7 +418,8 @@ void AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() {
new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf(
+ LLDB_LOGF(
+ log,
"AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64
" from _objc_debug_class_hash to isa->descriptor "
"cache",
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 635eaff637bc..9bdbef393e39 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -582,9 +582,9 @@ protected:
case 0:
break;
case 1: {
- regex_up.reset(new RegularExpression());
- if (!regex_up->Compile(llvm::StringRef::withNullAsEmpty(
- command.GetArgumentAtIndex(0)))) {
+ regex_up.reset(new RegularExpression(
+ llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0))));
+ if (!regex_up->IsValid()) {
result.AppendError(
"invalid argument - please provide a valid regular expression");
result.SetStatus(lldb::eReturnStatusFailed);
@@ -1209,11 +1209,11 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
objc_class_sp = GetClassDescriptorFromISA(isa);
if (isa && !objc_class_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("0x%" PRIx64
- ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
- "not in class descriptor cache 0x%" PRIx64,
- isa_pointer, isa);
+ LLDB_LOGF(log,
+ "0x%" PRIx64
+ ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+ "not in class descriptor cache 0x%" PRIx64,
+ isa_pointer, isa);
}
}
}
@@ -1317,8 +1317,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
// Read the total number of classes from the hash table
const uint32_t num_classes = hash_table.GetCount();
if (num_classes == 0) {
- if (log)
- log->Printf("No dynamic classes found in gdb_objc_realized_classes.");
+ LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes.");
return DescriptorMapUpdateResult::Success(0);
}
@@ -1337,17 +1336,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
g_get_dynamic_class_info_body, eLanguageTypeObjC,
g_get_dynamic_class_info_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility Function for implementation lookup: %s",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to get Utility Function for implementation lookup: %s",
+ error.AsCString());
m_get_class_info_code.reset();
} else {
diagnostics.Clear();
if (!m_get_class_info_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup");
+ LLDB_LOGF(log, "Failed to install implementation lookup");
diagnostics.Dump(log);
}
m_get_class_info_code.reset();
@@ -1372,17 +1370,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
clang_uint32_t_type, arguments, thread_sp, error);
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to make function caller for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to make function caller for implementation lookup: %s.",
+ error.AsCString());
return DescriptorMapUpdateResult::Fail();
}
} else {
get_class_info_function = m_get_class_info_code->GetFunctionCaller();
if (!get_class_info_function) {
if (log) {
- log->Printf("Failed to get implementation lookup function caller.");
+ LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
diagnostics.Dump(log);
}
@@ -1399,10 +1396,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
if (class_infos_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("unable to allocate %" PRIu32
- " bytes in process for shared cache read",
- class_infos_byte_size);
+ LLDB_LOGF(log,
+ "unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
return DescriptorMapUpdateResult::Fail();
}
@@ -1451,8 +1448,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes\n", num_class_infos);
+ LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos);
if (num_class_infos > 0) {
// Read the ClassInfo structures
DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
@@ -1468,13 +1464,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
success = true;
} else {
if (log) {
- log->Printf("Error evaluating our find class name function.");
+ LLDB_LOGF(log, "Error evaluating our find class name function.");
diagnostics.Dump(log);
}
}
} else {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
}
@@ -1507,17 +1503,18 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
if (isa == 0) {
if (should_log)
- log->Printf(
- "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+ LLDB_LOGF(
+ log, "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
continue;
}
// Check if we already know about this ISA, if we do, the info will never
// change, so we can just skip it.
if (ISAIsCached(isa)) {
if (should_log)
- log->Printf("AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
- ", ignoring this class info",
- isa);
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
+ ", ignoring this class info",
+ isa);
offset += 4;
} else {
// Read the 32 bit hash for the class name
@@ -1536,15 +1533,16 @@ uint32_t AppleObjCRuntimeV2::ParseClassInfoArray(const DataExtractor &data,
AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr));
num_parsed++;
if (should_log)
- log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64
- ", hash=0x%8.8x, name=%s",
- isa, name_hash,
- descriptor_sp->GetClassName().AsCString("<unknown>"));
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 added isa=0x%" PRIx64
+ ", hash=0x%8.8x, name=%s",
+ isa, name_hash,
+ descriptor_sp->GetClassName().AsCString("<unknown>"));
}
}
if (should_log)
- log->Printf("AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
- num_parsed);
+ LLDB_LOGF(log, "AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
+ num_parsed);
return num_parsed;
}
@@ -1603,7 +1601,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
// use that in our jitted expression. Else fall back to the old
// class_getName.
static ConstString g_class_getName_symbol_name("class_getName");
- static ConstString g_class_getNameRaw_symbol_name("class_getNameRaw");
+ static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw");
ConstString class_name_getter_function_name = g_class_getName_symbol_name;
ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
@@ -1646,17 +1644,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
shared_class_expression.c_str(), eLanguageTypeObjC,
g_get_shared_cache_class_info_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility function for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Failed to get Utility function for implementation lookup: %s.",
+ error.AsCString());
m_get_shared_cache_class_info_code.reset();
} else {
diagnostics.Clear();
if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup.");
+ LLDB_LOGF(log, "Failed to install implementation lookup.");
diagnostics.Dump(log);
}
m_get_shared_cache_class_info_code.reset();
@@ -1703,10 +1700,10 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
if (class_infos_addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("unable to allocate %" PRIu32
- " bytes in process for shared cache read",
- class_infos_byte_size);
+ LLDB_LOGF(log,
+ "unable to allocate %" PRIu32
+ " bytes in process for shared cache read",
+ class_infos_byte_size);
return DescriptorMapUpdateResult::Fail();
}
@@ -1757,9 +1754,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
if (results == eExpressionCompleted) {
// The result is the number of ClassInfo structures that were filled in
num_class_infos = return_value.GetScalar().ULong();
- if (log)
- log->Printf("Discovered %u ObjC classes in shared cache\n",
- num_class_infos);
+ LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n",
+ num_class_infos);
assert(num_class_infos <= num_classes);
if (num_class_infos > 0) {
if (num_class_infos > num_classes) {
@@ -1786,13 +1782,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
}
} else {
if (log) {
- log->Printf("Error evaluating our find class name function.");
+ LLDB_LOGF(log, "Error evaluating our find class name function.");
diagnostics.Dump(log);
}
}
} else {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
}
@@ -1827,9 +1823,10 @@ bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory(
new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
- " (%s) from dynamic table to isa->descriptor cache",
- elt.second, elt.first.AsCString());
+ LLDB_LOGF(log,
+ "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
+ " (%s) from dynamic table to isa->descriptor cache",
+ elt.second, elt.first.AsCString());
AddClass(elt.second, descriptor_sp, elt.first.AsCString());
}
@@ -1912,14 +1909,14 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
DescriptorMapUpdateResult shared_cache_update_result =
UpdateISAToDescriptorMapSharedCache();
- if (log)
- log->Printf("attempted to read objc class data - results: "
- "[dynamic_update]: ran: %s, count: %" PRIu32
- " [shared_cache_update]: ran: %s, count: %" PRIu32,
- dynamic_update_result.m_update_ran ? "yes" : "no",
- dynamic_update_result.m_num_found,
- shared_cache_update_result.m_update_ran ? "yes" : "no",
- shared_cache_update_result.m_num_found);
+ LLDB_LOGF(log,
+ "attempted to read objc class data - results: "
+ "[dynamic_update]: ran: %s, count: %" PRIu32
+ " [shared_cache_update]: ran: %s, count: %" PRIu32,
+ dynamic_update_result.m_update_ran ? "yes" : "no",
+ dynamic_update_result.m_num_found,
+ shared_cache_update_result.m_update_ran ? "yes" : "no",
+ shared_cache_update_result.m_num_found);
// warn if:
// - we could not run either expression
@@ -2032,8 +2029,8 @@ lldb::addr_t AppleObjCRuntimeV2::LookupRuntimeSymbol(ConstString name) {
if (name_cstr) {
llvm::StringRef name_strref(name_cstr);
- static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
- static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
+ llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
+ llvm::StringRef class_prefix("OBJC_CLASS_$_");
if (name_strref.startswith(ivar_prefix)) {
llvm::StringRef ivar_skipped_prefix =
@@ -2516,8 +2513,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
ObjCISA isa, ObjCISA &ret_isa) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
- if (log)
- log->Printf("AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
+ LLDB_LOGF(log, "AOCRT::NPI Evalulate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
if ((isa & ~m_objc_debug_isa_class_mask) == 0)
return false;
@@ -2543,10 +2539,10 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
// read the count again, and update the cache if the count has been
// updated.
if (index > m_indexed_isa_cache.size()) {
- if (log)
- log->Printf("AOCRT::NPI (index = %" PRIu64
- ") exceeds cache (size = %" PRIu64 ")",
- (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
+ LLDB_LOGF(log,
+ "AOCRT::NPI (index = %" PRIu64
+ ") exceeds cache (size = %" PRIu64 ")",
+ (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
Process *process(m_runtime.GetProcess());
@@ -2561,9 +2557,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (error.Fail())
return false;
- if (log)
- log->Printf("AOCRT::NPI (new class count = %" PRIu64 ")",
- (uint64_t)objc_indexed_classes_count);
+ LLDB_LOGF(log, "AOCRT::NPI (new class count = %" PRIu64 ")",
+ (uint64_t)objc_indexed_classes_count);
if (objc_indexed_classes_count > m_indexed_isa_cache.size()) {
// Read the class entries we don't have. We should just read all of
@@ -2581,9 +2576,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (error.Fail() || bytes_read != buffer.GetByteSize())
return false;
- if (log)
- log->Printf("AOCRT::NPI (read new classes count = %" PRIu64 ")",
- (uint64_t)num_new_classes);
+ LLDB_LOGF(log, "AOCRT::NPI (read new classes count = %" PRIu64 ")",
+ (uint64_t)num_new_classes);
// Append the new entries to the existing cache.
DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
@@ -2600,9 +2594,8 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
if (index > m_indexed_isa_cache.size())
return false;
- if (log)
- log->Printf("AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
- (uint64_t)m_indexed_isa_cache[index]);
+ LLDB_LOGF(log, "AOCRT::NPI Evalulate(ret_isa = 0x%" PRIx64 ")",
+ (uint64_t)m_indexed_isa_cache[index]);
ret_isa = m_indexed_isa_cache[index];
return (ret_isa != 0); // this is a pointer so 0 is not a valid value
@@ -2647,8 +2640,9 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() {
std::function<lldb::addr_t(ConstString)> get_symbol =
[this](ConstString sym) -> lldb::addr_t {
SymbolContextList sc_list;
- if (GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
- sym, lldb::eSymbolTypeData, sc_list) == 1) {
+ GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ sym, lldb::eSymbolTypeData, sc_list);
+ if (sc_list.GetSize() == 1) {
SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
if (sc.symbol)
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index b3eb09caa86d..379ef3dca86c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -543,7 +543,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
Status error;
DataExtractor data;
error = argument_values.GetValueAtIndex(0)->GetValueAsData(&exe_ctx, data,
- 0, nullptr);
+ nullptr);
lldb::offset_t offset = 0;
lldb::addr_t region_addr = data.GetPointer(&offset);
@@ -593,7 +593,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions(
if (log) {
StreamString s;
m_regions.back().Dump(s);
- log->Printf("Read vtable region: \n%s", s.GetData());
+ LLDB_LOGF(log, "Read vtable region: \n%s", s.GetData());
}
next_region = m_regions.back().GetNextRegionAddr();
@@ -704,7 +704,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler(
// step through any method dispatches. Warn to that effect and get out of
// here.
if (process_sp->CanJIT()) {
- process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf(
+ process_sp->GetTarget().GetDebugger().GetErrorStream().Printf(
"Could not find implementation lookup function \"%s\""
" step in through ObjC method dispatch will not work.\n",
get_impl_name.AsCString());
@@ -779,25 +779,24 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
m_lookup_implementation_function_code, eLanguageTypeObjC,
g_lookup_implementation_function_name, error));
if (error.Fail()) {
- if (log)
- log->Printf(
- "Failed to get Utility Function for implementation lookup: %s.",
- error.AsCString());
+ LLDB_LOGF(
+ log,
+ "Failed to get Utility Function for implementation lookup: %s.",
+ error.AsCString());
m_impl_code.reset();
return args_addr;
}
if (!m_impl_code->Install(diagnostics, exe_ctx)) {
if (log) {
- log->Printf("Failed to install implementation lookup.");
+ LLDB_LOGF(log, "Failed to install implementation lookup.");
diagnostics.Dump(log);
}
m_impl_code.reset();
return args_addr;
}
} else {
- if (log)
- log->Printf("No method lookup implementation code.");
+ LLDB_LOGF(log, "No method lookup implementation code.");
return LLDB_INVALID_ADDRESS;
}
@@ -811,10 +810,9 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
impl_function_caller = m_impl_code->MakeFunctionCaller(
clang_void_ptr_type, dispatch_values, thread_sp, error);
if (error.Fail()) {
- if (log)
- log->Printf(
- "Error getting function caller for dispatch lookup: \"%s\".",
- error.AsCString());
+ LLDB_LOGF(log,
+ "Error getting function caller for dispatch lookup: \"%s\".",
+ error.AsCString());
return args_addr;
}
} else {
@@ -833,7 +831,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
if (!impl_function_caller->WriteFunctionArguments(
exe_ctx, args_addr, dispatch_values, diagnostics)) {
if (log) {
- log->Printf("Error writing function arguments.");
+ LLDB_LOGF(log, "Error writing function arguments.");
diagnostics.Dump(log);
}
return args_addr;
@@ -934,9 +932,9 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
lldb::addr_t obj_addr =
argument_values.GetValueAtIndex(obj_index)->GetScalar().ULongLong();
if (obj_addr == 0x0) {
- if (log)
- log->Printf(
- "Asked to step to dispatch to nil object, returning empty plan.");
+ LLDB_LOGF(
+ log,
+ "Asked to step to dispatch to nil object, returning empty plan.");
return ret_plan_sp;
}
@@ -976,13 +974,11 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (super_value.GetScalar().IsValid())
isa_addr = super_value.GetScalar().ULongLong();
else {
- if (log)
- log->Printf("Failed to extract the super class value from the "
- "class in objc_super.");
+ LLDB_LOGF(log, "Failed to extract the super class value from the "
+ "class in objc_super.");
}
} else {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
+ LLDB_LOGF(log, "Failed to extract the class value from objc_super.");
}
} else {
// In the objc_msgSendSuper case, we don't get the object
@@ -998,8 +994,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (super_value.GetScalar().IsValid()) {
isa_addr = super_value.GetScalar().ULongLong();
} else {
- if (log)
- log->Printf("Failed to extract the class value from objc_super.");
+ LLDB_LOGF(log, "Failed to extract the class value from objc_super.");
}
}
} else {
@@ -1022,8 +1017,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (isa_value.GetScalar().IsValid()) {
isa_addr = isa_value.GetScalar().ULongLong();
} else {
- if (log)
- log->Printf("Failed to extract the isa value from object.");
+ LLDB_LOGF(log, "Failed to extract the isa value from object.");
}
}
@@ -1033,9 +1027,10 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (isa_addr != LLDB_INVALID_ADDRESS) {
if (log) {
- log->Printf("Resolving call for class - 0x%" PRIx64
- " and selector - 0x%" PRIx64,
- isa_addr, sel_addr);
+ LLDB_LOGF(log,
+ "Resolving call for class - 0x%" PRIx64
+ " and selector - 0x%" PRIx64,
+ isa_addr, sel_addr);
}
ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*thread.GetProcess());
@@ -1047,9 +1042,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (impl_addr != LLDB_INVALID_ADDRESS) {
// Yup, it was in the cache, so we can run to that address directly.
- if (log)
- log->Printf("Found implementation address in cache: 0x%" PRIx64,
- impl_addr);
+ LLDB_LOGF(log, "Found implementation address in cache: 0x%" PRIx64,
+ impl_addr);
ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, impl_addr,
stop_others);
@@ -1137,7 +1131,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
if (log) {
StreamString s;
ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
- log->Printf("Using ObjC step plan: %s.\n", s.GetData());
+ LLDB_LOGF(log, "Using ObjC step plan: %s.\n", s.GetData());
}
}
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 26654e9212b9..6402e80d6f98 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -18,7 +18,6 @@
#include <vector>
using namespace lldb_private;
-using namespace lldb_utility;
AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
ObjCLanguageRuntime &runtime)
@@ -32,16 +31,14 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
.c_str()));
}
-std::string
-AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer &type) {
+std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) {
StreamString buffer;
while (type.HasAtLeast(1) && type.Peek() != '=')
buffer.Printf("%c", type.Next());
return buffer.GetString();
}
-std::string
-AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
+std::string AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) {
StreamString buffer;
while (type.HasAtLeast(1) && type.Peek() != '"')
buffer.Printf("%c", type.Next());
@@ -51,8 +48,7 @@ AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
return buffer.GetString();
}
-uint32_t
-AppleObjCTypeEncodingParser::ReadNumber(lldb_utility::StringLexer &type) {
+uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
uint32_t total = 0;
while (type.HasAtLeast(1) && isdigit(type.Peek()))
total = 10 * total + (type.Next() - '0');
@@ -68,7 +64,7 @@ AppleObjCTypeEncodingParser::StructElement::StructElement()
AppleObjCTypeEncodingParser::StructElement
AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StringLexer &type,
bool for_expression) {
StructElement retval;
if (type.NextIf('"'))
@@ -81,25 +77,21 @@ AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
return retval;
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildStruct(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '{', '}',
clang::TTK_Struct);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildUnion(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, '(', ')',
clang::TTK_Union);
}
clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
- clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
- bool for_expression, char opener, char closer, uint32_t kind) {
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression,
+ char opener, char closer, uint32_t kind) {
if (!type.NextIf(opener))
return clang::QualType();
std::string name(ReadStructName(type));
@@ -149,8 +141,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
}
ClangASTContext::AddFieldToRecordType(
union_type, element.name.c_str(),
- CompilerType(&ast_ctx, element.type), lldb::eAccessPublic,
- element.bitfield);
+ CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ element.type.getAsOpaquePtr()),
+ lldb::eAccessPublic, element.bitfield);
++count;
}
ClangASTContext::CompleteTagDeclarationDefinition(union_type);
@@ -158,10 +151,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
return ClangUtil::GetQualType(union_type);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
- bool for_expression) {
+clang::QualType AppleObjCTypeEncodingParser::BuildArray(
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('['))
return clang::QualType();
uint32_t size = ReadNumber(type);
@@ -172,7 +163,9 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
if (!lldb_ctx)
return clang::QualType();
CompilerType array_type(lldb_ctx->CreateArrayType(
- CompilerType(&ast_ctx, element_type), size, false));
+ CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ element_type.getAsOpaquePtr()),
+ size, false));
return ClangUtil::GetQualType(array_type);
}
@@ -182,8 +175,7 @@ AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
// 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(
- clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
- bool for_expression) {
+ clang::ASTContext &ast_ctx, StringLexer &type, bool for_expression) {
if (!type.NextIf('@'))
return clang::QualType();
@@ -375,7 +367,8 @@ CompilerType AppleObjCTypeEncodingParser::RealizeType(
if (name && name[0]) {
StringLexer lexer(name);
clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
- return CompilerType(&ast_ctx, qual_type);
+ return CompilerType(ClangASTContext::GetASTContext(&ast_ctx),
+ qual_type.getAsOpaquePtr());
}
return CompilerType();
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index e576e8f283f2..590bc4ba9eae 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -15,12 +15,8 @@
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
-namespace lldb_utility {
-class StringLexer;
-}
-
namespace lldb_private {
-
+class StringLexer;
class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType {
public:
AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime);
@@ -39,41 +35,35 @@ private:
~StructElement() = default;
};
- clang::QualType BuildType(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildType(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression,
uint32_t *bitfield_bit_size = nullptr);
- clang::QualType BuildStruct(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildStruct(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildAggregate(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildAggregate(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression, char opener, char closer,
uint32_t kind);
- clang::QualType BuildUnion(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildUnion(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- clang::QualType BuildArray(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ clang::QualType BuildArray(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
- std::string ReadStructName(lldb_utility::StringLexer &type);
+ std::string ReadStructName(StringLexer &type);
- StructElement ReadStructElement(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StructElement ReadStructElement(clang::ASTContext &ast_ctx, StringLexer &type,
bool for_expression);
clang::QualType BuildObjCObjectPointerType(clang::ASTContext &ast_ctx,
- lldb_utility::StringLexer &type,
+ StringLexer &type,
bool for_expression);
- uint32_t ReadNumber(lldb_utility::StringLexer &type);
+ uint32_t ReadNumber(StringLexer &type);
- std::string ReadQuotedString(lldb_utility::StringLexer &type);
+ std::string ReadQuotedString(StringLexer &type);
ObjCLanguageRuntime &m_runtime;
};
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index d18435c9c6db..af630eee7265 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -141,17 +141,15 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (target_addr == 0) {
- if (log)
- log->Printf("Got target implementation of 0x0, stopping.");
+ LLDB_LOGF(log, "Got target implementation of 0x0, stopping.");
SetPlanComplete();
return true;
}
if (m_trampoline_handler->AddrIsMsgForward(target_addr)) {
- if (log)
- log->Printf(
- "Implementation lookup returned msgForward function: 0x%" PRIx64
- ", stopping.",
- target_addr);
+ LLDB_LOGF(log,
+ "Implementation lookup returned msgForward function: 0x%" PRIx64
+ ", stopping.",
+ target_addr);
SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
eSymbolContextEverything);
@@ -167,18 +165,17 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
return false;
}
- if (log)
- log->Printf("Running to ObjC method implementation: 0x%" PRIx64,
- target_addr);
+ LLDB_LOGF(log, "Running to ObjC method implementation: 0x%" PRIx64,
+ target_addr);
ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*GetThread().GetProcess());
assert(objc_runtime != nullptr);
objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr);
- if (log)
- log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
- "} = addr=0x%" PRIx64 " to cache.",
- m_isa_addr, m_sel_addr, target_addr);
+ LLDB_LOGF(log,
+ "Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
+ "} = addr=0x%" PRIx64 " to cache.",
+ m_isa_addr, m_sel_addr, target_addr);
// Extract the target address from the value:
diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 631c15c46ce8..87ae4c2c6c48 100644
--- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -64,9 +64,10 @@ void ObjCLanguageRuntime::AddToMethodCache(lldb::addr_t class_addr,
lldb::addr_t impl_addr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log) {
- log->Printf("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64
- " implementation 0x%" PRIx64 ".",
- class_addr, selector, impl_addr);
+ LLDB_LOGF(log,
+ "Caching: class 0x%" PRIx64 " selector 0x%" PRIx64
+ " implementation 0x%" PRIx64 ".",
+ class_addr, selector, impl_addr);
}
m_impl_cache.insert(std::pair<ClassAndSel, lldb::addr_t>(
ClassAndSel(class_addr, selector), impl_addr));
@@ -102,8 +103,8 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
const ModuleList &modules = m_process->GetTarget().GetImages();
SymbolContextList sc_list;
- const size_t matching_symbols =
- modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+ modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+ const size_t matching_symbols = sc_list.GetSize();
if (matching_symbols) {
SymbolContext sc;
@@ -120,20 +121,17 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
TypeList types;
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- const uint32_t num_types = module_sp->FindTypes(
- name, exact_match, max_matches, searched_symbol_files, types);
-
- if (num_types) {
- uint32_t i;
- for (i = 0; i < num_types; ++i) {
- TypeSP type_sp(types.GetTypeAtIndex(i));
-
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
- type_sp->GetForwardCompilerType())) {
- if (type_sp->IsCompleteObjCClass()) {
- m_complete_class_cache[name] = type_sp;
- return type_sp;
- }
+ module_sp->FindTypes(name, exact_match, max_matches, searched_symbol_files,
+ types);
+
+ for (uint32_t i = 0; i < types.GetSize(); ++i) {
+ TypeSP type_sp(types.GetTypeAtIndex(i));
+
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ type_sp->GetForwardCompilerType())) {
+ if (type_sp->IsCompleteObjCClass()) {
+ m_complete_class_cache[name] = type_sp;
+ return type_sp;
}
}
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 1925c78ed342..39acd6e9f268 100644
--- a/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -17,6 +17,7 @@
#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"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index 60549663db66..b396781e6726 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -140,10 +140,10 @@ bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
// We've been using a triple and datalayout of some ARM variant all along,
// so we need to let the backend know that this is no longer the case.
if (log) {
- log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__,
- real_triple.str().c_str());
- log->Printf(
- "%s - Changing RS datalayout to '%s'", __FUNCTION__,
+ LLDB_LOGF(log, "%s - Changing RS target triple to '%s'", __FUNCTION__,
+ real_triple.str().c_str());
+ LLDB_LOGF(
+ log, "%s - Changing RS datalayout to '%s'", __FUNCTION__,
target_machine->createDataLayout().getStringRepresentation().c_str());
}
module.setTargetTriple(real_triple);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index c9cd34cf379d..5200749d759f 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -138,9 +138,8 @@ bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
size_t read =
ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), err);
if (read != arg_size || !err.Success()) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 " '%s'",
- __FUNCTION__, uint64_t(i), err.AsCString());
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 " '%s'",
+ __FUNCTION__, uint64_t(i), err.AsCString());
return false;
}
}
@@ -173,8 +172,7 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
// check the stack alignment was correct (16 byte aligned)
if ((sp & 0xf) != 0x0) {
- if (log)
- log->Printf("%s - stack misaligned", __FUNCTION__);
+ LLDB_LOGF(log, "%s - stack misaligned", __FUNCTION__);
return false;
}
@@ -213,9 +211,8 @@ bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -258,9 +255,8 @@ bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -285,15 +281,13 @@ bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// arguments passed on the stack
else {
- if (log)
- log->Printf("%s - reading arguments spilled to stack not implemented",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - reading arguments spilled to stack not implemented",
+ __FUNCTION__);
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__,
- uint64_t(i));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64, __FUNCTION__,
+ uint64_t(i));
return false;
}
}
@@ -337,9 +331,8 @@ bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -385,9 +378,8 @@ bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
}
// fail if we couldn't read this argument
if (!success) {
- if (log)
- log->Printf("%s - error reading argument: %" PRIu64 ", reason: %s",
- __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
+ LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
+ __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
return false;
}
}
@@ -399,8 +391,7 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
// verify that we have a target
if (!exe_ctx.GetTargetPtr()) {
- if (log)
- log->Printf("%s - invalid target", __FUNCTION__);
+ LLDB_LOGF(log, "%s - invalid target", __FUNCTION__);
return false;
}
@@ -430,9 +421,8 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
default:
// unsupported architecture
if (log) {
- log->Printf(
- "%s - architecture not supported: '%s'", __FUNCTION__,
- exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName());
+ LLDB_LOGF(log, "%s - architecture not supported: '%s'", __FUNCTION__,
+ exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName());
}
return false;
}
@@ -452,28 +442,20 @@ bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
// elements fails the contents of &coord are undefined and `false` is
// returned, `true` otherwise
- RegularExpression regex;
- RegularExpression::Match regex_match(3);
-
- bool matched = false;
- if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+),([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
- else if (regex.Compile(llvm::StringRef("^([0-9]+),([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
- else if (regex.Compile(llvm::StringRef("^([0-9]+)$")) &&
- regex.Execute(coord_s, &regex_match))
- matched = true;
-
- if (!matched)
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+
+ if (!RegularExpression("^([0-9]+),([0-9]+),([0-9]+)$")
+ .Execute(coord_s, &matches) &&
+ !RegularExpression("^([0-9]+),([0-9]+)$").Execute(coord_s, &matches) &&
+ !RegularExpression("^([0-9]+)$").Execute(coord_s, &matches))
return false;
- auto get_index = [&](int idx, uint32_t &i) -> bool {
+ auto get_index = [&](size_t idx, uint32_t &i) -> bool {
std::string group;
errno = 0;
- if (regex_match.GetMatchAtIndex(coord_s.str().c_str(), idx + 1, group))
- return !llvm::StringRef(group).getAsInteger<uint32_t>(10, i);
+ if (idx + 1 < matches.size()) {
+ return !llvm::StringRef(matches[idx + 1]).getAsInteger<uint32_t>(10, i);
+ }
return true;
};
@@ -492,9 +474,8 @@ bool SkipPrologue(lldb::ModuleSP &module, Address &addr) {
ConstString name = sc.GetFunctionName();
if (offset)
addr.Slide(offset);
- if (log)
- log->Printf("%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
- name.AsCString(), offset);
+ LLDB_LOGF(log, "%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
+ name.AsCString(), offset);
}
return true;
} else
@@ -809,7 +790,7 @@ RenderScriptRuntime::CreateInstance(Process *process,
// symbol.
Searcher::CallbackReturn
RSBreakpointResolver::SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *, bool) {
+ SymbolContext &context, Address *) {
ModuleSP module = context.module_sp;
if (!module || !IsRenderScriptScriptModule(module))
@@ -839,7 +820,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
Searcher::CallbackReturn
RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
lldb_private::SymbolContext &context,
- Address *, bool) {
+ Address *) {
// 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.
@@ -884,14 +865,13 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
if (filter.AddressPasses(address)) {
bool new_bp;
if (!SkipPrologue(module, address)) {
- if (log)
- log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
}
m_breakpoint->AddLocation(address, &new_bp);
- if (log)
- log->Printf("%s: %s reduction breakpoint on %s in %s", __FUNCTION__,
- new_bp ? "new" : "existing", kernel_name.GetCString(),
- address.GetModule()->GetFileSpec().GetCString());
+ LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s",
+ __FUNCTION__, new_bp ? "new" : "existing",
+ kernel_name.GetCString(),
+ address.GetModule()->GetFileSpec().GetCString());
}
}
}
@@ -900,8 +880,7 @@ RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
}
Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
- SearchFilter &filter, SymbolContext &context, Address *addr,
- bool containing) {
+ SearchFilter &filter, SymbolContext &context, Address *addr) {
if (!m_breakpoint)
return eCallbackReturnContinue;
@@ -920,48 +899,43 @@ Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
for (auto &name : names) {
const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name));
if (!sg) {
- if (log)
- log->Printf("%s: could not find script group for %s", __FUNCTION__,
- name.c_str());
+ LLDB_LOGF(log, "%s: could not find script group for %s", __FUNCTION__,
+ name.c_str());
continue;
}
- if (log)
- log->Printf("%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
+ LLDB_LOGF(log, "%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) {
if (log) {
- log->Printf("%s: Adding breakpoint for %s", __FUNCTION__,
- k.m_name.AsCString());
- log->Printf("%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
+ LLDB_LOGF(log, "%s: Adding breakpoint for %s", __FUNCTION__,
+ k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
}
const lldb_private::Symbol *sym =
module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode);
if (!sym) {
- if (log)
- log->Printf("%s: Unable to find symbol for %s", __FUNCTION__,
- k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Unable to find symbol for %s", __FUNCTION__,
+ k.m_name.AsCString());
continue;
}
if (log) {
- log->Printf("%s: Found symbol name is %s", __FUNCTION__,
- sym->GetName().AsCString());
+ LLDB_LOGF(log, "%s: Found symbol name is %s", __FUNCTION__,
+ sym->GetName().AsCString());
}
auto address = sym->GetAddress();
if (!SkipPrologue(module, address)) {
- if (log)
- log->Printf("%s: Error trying to skip prologue", __FUNCTION__);
+ LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
}
bool new_bp;
m_breakpoint->AddLocation(address, &new_bp);
- if (log)
- log->Printf("%s: Placed %sbreakpoint on %s", __FUNCTION__,
- new_bp ? "new " : "", k.m_name.AsCString());
+ LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__,
+ new_bp ? "new " : "", k.m_name.AsCString());
// exit after placing the first breakpoint if we do not intend to stop on
// all kernels making up this script group
@@ -1136,8 +1110,7 @@ void RenderScriptRuntime::HookCallback(RuntimeHook *hook,
ExecutionContext &exe_ctx) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s - '%s'", __FUNCTION__, hook->defn->name);
+ LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name);
if (hook->defn->grabber) {
(this->*(hook->defn->grabber))(hook, exe_ctx);
@@ -1163,19 +1136,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
}};
if (!GetArgs(context, args.data(), args.size())) {
- if (log)
- log->Printf("%s - Error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error while reading the function parameters",
+ __FUNCTION__);
return;
} else if (log) {
- log->Printf("%s - groupName : 0x%" PRIx64, __FUNCTION__,
- addr_t(args[eGroupName]));
- log->Printf("%s - groupNameSize: %" PRIu64, __FUNCTION__,
- uint64_t(args[eGroupNameSize]));
- log->Printf("%s - kernel : 0x%" PRIx64, __FUNCTION__,
- addr_t(args[eKernel]));
- log->Printf("%s - kernelCount : %" PRIu64, __FUNCTION__,
- uint64_t(args[eKernelCount]));
+ LLDB_LOGF(log, "%s - groupName : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eGroupName]));
+ LLDB_LOGF(log, "%s - groupNameSize: %" PRIu64, __FUNCTION__,
+ uint64_t(args[eGroupNameSize]));
+ LLDB_LOGF(log, "%s - kernel : 0x%" PRIx64, __FUNCTION__,
+ addr_t(args[eKernel]));
+ LLDB_LOGF(log, "%s - kernelCount : %" PRIu64, __FUNCTION__,
+ uint64_t(args[eKernelCount]));
}
// parse script group name
@@ -1187,12 +1159,10 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err);
buffer.get()[len] = '\0';
if (!err.Success()) {
- if (log)
- log->Printf("Error reading scriptgroup name from target");
+ LLDB_LOGF(log, "Error reading scriptgroup name from target");
return;
} else {
- if (log)
- log->Printf("Extracted scriptgroup name %s", buffer.get());
+ LLDB_LOGF(log, "Extracted scriptgroup name %s", buffer.get());
}
// write back the script group name
group_name.SetCString(buffer.get());
@@ -1214,9 +1184,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
m_scriptGroups.push_back(group);
} else {
// already have this script group
- if (log)
- log->Printf("Attempt to add duplicate script group %s",
- group_name.AsCString());
+ LLDB_LOGF(log, "Attempt to add duplicate script group %s",
+ group_name.AsCString());
return;
}
}
@@ -1234,21 +1203,18 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
size_t read =
m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
if (!err.Success() || read != target_ptr_size) {
- if (log)
- log->Printf("Error parsing kernel address %" PRIu64 " in script group",
- i);
+ LLDB_LOGF(log, "Error parsing kernel address %" PRIu64 " in script group",
+ i);
return;
}
- if (log)
- log->Printf("Extracted scriptgroup kernel address - 0x%" PRIx64,
- kernel_addr);
+ LLDB_LOGF(log, "Extracted scriptgroup kernel address - 0x%" PRIx64,
+ kernel_addr);
kernel.m_addr = kernel_addr;
// try to resolve the associated kernel name
if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) {
- if (log)
- log->Printf("Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
- kernel_addr);
+ LLDB_LOGF(log, "Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
+ kernel_addr);
return;
}
@@ -1261,9 +1227,8 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
// verify this function is a valid kernel
if (IsKnownKernel(base_kernel)) {
kernel.m_name = base_kernel;
- if (log)
- log->Printf("%s - found non expand version '%s'", __FUNCTION__,
- base_kernel.GetCString());
+ LLDB_LOGF(log, "%s - found non expand version '%s'", __FUNCTION__,
+ base_kernel.GetCString());
}
}
}
@@ -1276,15 +1241,13 @@ void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
Target &target = m_process->GetTarget();
const BreakpointList &list = target.GetBreakpointList();
const size_t num_breakpoints = list.GetSize();
- if (log)
- log->Printf("Resolving %zu breakpoints", num_breakpoints);
+ LLDB_LOGF(log, "Resolving %zu breakpoints", num_breakpoints);
for (size_t i = 0; i < num_breakpoints; ++i) {
const BreakpointSP bp = list.GetBreakpointAtIndex(i);
if (bp) {
if (bp->MatchesName(group_name.AsCString())) {
- if (log)
- log->Printf("Found breakpoint with name %s",
- group_name.AsCString());
+ LLDB_LOGF(log, "Found breakpoint with name %s",
+ group_name.AsCString());
bp->ResolveBreakpoint();
}
}
@@ -1322,9 +1285,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - Error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error while reading the function parameters",
+ __FUNCTION__);
return;
}
@@ -1342,10 +1304,9 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
uint64_t result = 0;
size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err);
if (read != target_ptr_size || !err.Success()) {
- if (log)
- log->Printf(
- "%s - Error while reading allocation list argument %" PRIu64,
- __FUNCTION__, i);
+ LLDB_LOGF(log,
+ "%s - Error while reading allocation list argument %" PRIu64,
+ __FUNCTION__, i);
} else {
allocs.push_back(result);
}
@@ -1375,8 +1336,8 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
if (log) {
if (alloc->context.isValid() &&
*alloc->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Allocation used by multiple contexts",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Allocation used by multiple contexts",
+ __FUNCTION__);
}
alloc->context = addr_t(args[eRsContext]);
}
@@ -1388,7 +1349,7 @@ void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
if (log) {
if (script->context.isValid() &&
*script->context.get() != addr_t(args[eRsContext]))
- log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Script used by multiple contexts", __FUNCTION__);
}
script->context = addr_t(args[eRsContext]);
}
@@ -1416,26 +1377,26 @@ void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook,
bool success = GetArgs(context, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error reading the function parameters.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error reading the function parameters.", __FUNCTION__);
return;
}
if (log) {
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
- ":%" PRIu64 "bytes.",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
- uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
+ LLDB_LOGF(log,
+ "%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
+ ":%" PRIu64 "bytes.",
+ __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
+ uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
addr_t script_addr = addr_t(args[eRsScript]);
if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) {
auto rsm = m_scriptMappings[script_addr];
if (uint64_t(args[eRsId]) < rsm->m_globals.size()) {
auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
- log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__,
- rsg.m_name.AsCString(),
- rsm->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(log, "%s - Setting of '%s' within '%s' inferred",
+ __FUNCTION__, rsg.m_name.AsCString(),
+ rsm->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1455,16 +1416,14 @@ void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook,
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
+ __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]),
+ uint64_t(args[eRsForceZero]));
AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc]));
if (alloc)
@@ -1487,29 +1446,25 @@ void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook,
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters.",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
- uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
+ uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) {
auto &allocation_up = *iter; // get the unique pointer
if (allocation_up->address.isValid() &&
*allocation_up->address.get() == addr_t(args[eRsAlloc])) {
m_allocations.erase(iter);
- if (log)
- log->Printf("%s - deleted allocation entry.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - deleted allocation entry.", __FUNCTION__);
return;
}
}
- if (log)
- log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't find destroyed allocation.", __FUNCTION__);
}
void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
@@ -1526,32 +1481,28 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
bool success = GetArgs(exe_ctx, &args[0], args.size());
if (!success) {
- if (log)
- log->Printf("%s - error while reading the function parameters.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - error while reading the function parameters.",
+ __FUNCTION__);
return;
}
std::string res_name;
process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - error reading res_name: %s.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error reading res_name: %s.", __FUNCTION__,
+ err.AsCString());
}
std::string cache_dir;
process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - error reading cache_dir: %s.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error reading cache_dir: %s.", __FUNCTION__,
+ err.AsCString());
}
- if (log)
- log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
- __FUNCTION__, uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]), res_name.c_str(), cache_dir.c_str());
+ LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
+ __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]),
+ res_name.c_str(), cache_dir.c_str());
if (res_name.size() > 0) {
StreamString strm;
@@ -1566,13 +1517,14 @@ void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
script->context = addr_t(args[eRsContext]);
}
- if (log)
- log->Printf("%s - '%s' tagged with context 0x%" PRIx64
- " and script 0x%" PRIx64 ".",
- __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
- uint64_t(args[eRsScript]));
+ LLDB_LOGF(log,
+ "%s - '%s' tagged with context 0x%" PRIx64
+ " and script 0x%" PRIx64 ".",
+ __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]));
} else if (log) {
- log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - resource name invalid, Script not tagged.",
+ __FUNCTION__);
}
}
@@ -1593,8 +1545,7 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
machine != llvm::Triple::ArchType::mipsel &&
machine != llvm::Triple::ArchType::mips64el &&
machine != llvm::Triple::ArchType::x86_64) {
- if (log)
- log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - unable to hook runtime functions.", __FUNCTION__);
return;
}
@@ -1618,23 +1569,22 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
ConstString(symbol_name), eSymbolTypeCode);
if (!sym) {
if (log) {
- log->Printf("%s - symbol '%s' related to the function %s not found",
- __FUNCTION__, symbol_name, hook_defn->name);
+ LLDB_LOGF(log, "%s - symbol '%s' related to the function %s not found",
+ __FUNCTION__, symbol_name, hook_defn->name);
}
continue;
}
addr_t addr = sym->GetLoadAddress(&target);
if (addr == LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("%s - unable to resolve the address of hook function '%s' "
- "with symbol '%s'.",
- __FUNCTION__, hook_defn->name, symbol_name);
+ LLDB_LOGF(log,
+ "%s - unable to resolve the address of hook function '%s' "
+ "with symbol '%s'.",
+ __FUNCTION__, hook_defn->name, symbol_name);
continue;
} else {
- if (log)
- log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
- __FUNCTION__, hook_defn->name, addr);
+ LLDB_LOGF(log, "%s - function %s, address resolved at 0x%" PRIx64,
+ __FUNCTION__, hook_defn->name, addr);
}
RuntimeHookSP hook(new RuntimeHook());
@@ -1644,11 +1594,12 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
m_runtimeHooks[addr] = hook;
if (log) {
- log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64
- " at 0x%" PRIx64 ".",
- __FUNCTION__, hook_defn->name,
- module->GetFileSpec().GetFilename().AsCString(),
- (uint64_t)hook_defn->version, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "%s - successfully hooked '%s' in '%s' version %" PRIu64
+ " at 0x%" PRIx64 ".",
+ __FUNCTION__, hook_defn->name,
+ module->GetFileSpec().GetFilename().AsCString(),
+ (uint64_t)hook_defn->version, (uint64_t)addr);
}
hook_placed[idx] = true;
}
@@ -1661,8 +1612,8 @@ void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
const HookDefn &hook_defn = s_runtimeHookDefns[i];
if (hook_defn.kind != kind)
continue;
- log->Printf("%s - function %s was not hooked", __FUNCTION__,
- hook_defn.name);
+ LLDB_LOGF(log, "%s - function %s was not hooked", __FUNCTION__,
+ hook_defn.name);
}
}
}
@@ -1697,11 +1648,11 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
if (m_scriptMappings.find(script) != m_scriptMappings.end()) {
// if the module we have stored is different to the one we just received.
if (m_scriptMappings[script] != rsmodule_sp) {
- if (log)
- log->Printf(
- "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
- __FUNCTION__, (uint64_t)script,
- rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(
+ log,
+ "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
// We don't have a script mapping for the current script.
@@ -1713,11 +1664,9 @@ void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
rsmodule_sp->m_resname = res_name;
// Add Script/Module pair to map.
m_scriptMappings[script] = rsmodule_sp;
- if (log)
- log->Printf(
- "%s - script %" PRIx64 " associated with rsmodule '%s'.",
- __FUNCTION__, (uint64_t)script,
- rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ LLDB_LOGF(log, "%s - script %" PRIx64 " associated with rsmodule '%s'.",
+ __FUNCTION__, (uint64_t)script,
+ rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1730,8 +1679,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
StackFrame *frame_ptr,
uint64_t *result) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (log)
- log->Printf("%s(%s)", __FUNCTION__, expr);
+ LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr);
ValueObjectSP expr_result;
EvaluateExpressionOptions options;
@@ -1741,8 +1689,7 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
target.EvaluateExpression(expr, frame_ptr, expr_result, options);
if (!expr_result) {
- if (log)
- log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
+ LLDB_LOGF(log, "%s: couldn't evaluate expression.", __FUNCTION__);
return false;
}
@@ -1751,16 +1698,14 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
Status err = expr_result->GetError();
// Expression returned is void, so this is actually a success
if (err.GetError() == UserExpression::kNoResult) {
- if (log)
- log->Printf("%s - expression returned void.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression returned void.", __FUNCTION__);
result = nullptr;
return true;
}
- if (log)
- log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error evaluating expression result: %s", __FUNCTION__,
+ err.AsCString());
return false;
}
@@ -1769,9 +1714,8 @@ bool RenderScriptRuntime::EvalRSExpression(const char *expr,
*result = expr_result->GetValueAsUnsigned(0, &success);
if (!success) {
- if (log)
- log->Printf("%s - couldn't convert expression result to uint32_t",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't convert expression result to uint32_t",
+ __FUNCTION__);
return false;
}
@@ -1884,8 +1828,7 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1895,12 +1838,10 @@ bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), x, y, z);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1922,8 +1863,7 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid() || !alloc->context.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1933,12 +1873,10 @@ bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->context.get(), *alloc->address.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1960,8 +1898,7 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) {
- if (log)
- log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1983,12 +1920,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str,
*alloc->context.get(), bits, *alloc->type_ptr.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2007,10 +1942,10 @@ bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
addr_t element_ptr = static_cast<lldb::addr_t>(results[3]);
alloc->element.element_ptr = element_ptr;
- if (log)
- log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
- ") Element*: 0x%" PRIx64 ".",
- __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
+ LLDB_LOGF(log,
+ "%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
+ ") Element*: 0x%" PRIx64 ".",
+ __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
return true;
}
@@ -2024,8 +1959,7 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2042,12 +1976,10 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context,
*elem.element_ptr.get());
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2063,11 +1995,11 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
elem.type_vec_size = static_cast<uint32_t>(results[2]);
elem.field_count = static_cast<uint32_t>(results[3]);
- if (log)
- log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32
- ", vector size %" PRIu32 ", field count %" PRIu32,
- __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
- *elem.type_vec_size.get(), *elem.field_count.get());
+ LLDB_LOGF(log,
+ "%s - data type %" PRIu32 ", pixel type %" PRIu32
+ ", vector size %" PRIu32 ", field count %" PRIu32,
+ __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
+ *elem.type_vec_size.get(), *elem.field_count.get());
// If this Element has subelements then JIT rsaElementGetSubElements() for
// details about its fields
@@ -2084,8 +2016,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2107,12 +2038,10 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
context, field_count, field_count, field_count,
*elem.element_ptr.get(), field_count, field_index);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2120,8 +2049,7 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
return false;
- if (log)
- log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
+ LLDB_LOGF(log, "%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
switch (expr_index) {
case 0: // Element* of child
@@ -2136,9 +2064,8 @@ bool RenderScriptRuntime::JITSubelements(Element &elem,
if (!err.Fail())
child.type_name = ConstString(name);
else {
- if (log)
- log->Printf("%s - warning: Couldn't read field name.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - warning: Couldn't read field name.",
+ __FUNCTION__);
}
break;
}
@@ -2173,8 +2100,7 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
if (!alloc->address.isValid() || !alloc->dimension.isValid() ||
!alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2196,9 +2122,8 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get();
- if (log)
- log->Printf("%s - inferred size of struct allocation %" PRIu32 ".",
- __FUNCTION__, *alloc->size.get());
+ LLDB_LOGF(log, "%s - inferred size of struct allocation %" PRIu32 ".",
+ __FUNCTION__, *alloc->size.get());
return true;
}
@@ -2213,12 +2138,10 @@ bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), dim_x, dim_y, dim_z);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2242,8 +2165,7 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) {
- if (log)
- log->Printf("%s - failed to find allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -2253,12 +2175,10 @@ bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
*alloc->address.get(), 0, 1, 0);
if (written < 0) {
- if (log)
- log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
return false;
} else if (written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - expression too long.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
return false;
}
@@ -2354,9 +2274,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
// '#rs_padding_[0-9]+'
if (found && num_children < elem.children.size()) {
const uint32_t size_diff = elem.children.size() - num_children;
- if (log)
- log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__,
- size_diff);
+ LLDB_LOGF(log, "%s - %" PRIu32 " padding struct entries", __FUNCTION__,
+ size_diff);
for (uint32_t i = 0; i < size_diff; ++i) {
ConstString name = elem.children[num_children + i].type_name;
@@ -2377,9 +2296,8 @@ void RenderScriptRuntime::FindStructTypeName(Element &elem,
// Save name of variable in Element.
elem.type_name = valobj_sp->GetTypeName();
- if (log)
- log->Printf("%s - element name set to %s", __FUNCTION__,
- elem.type_name.AsCString());
+ LLDB_LOGF(log, "%s - element name set to %s", __FUNCTION__,
+ elem.type_name.AsCString());
return;
}
@@ -2424,9 +2342,8 @@ void RenderScriptRuntime::SetElementSize(Element &elem) {
elem.padding = padding;
elem.datum_size = data_size + padding;
- if (log)
- log->Printf("%s - element size set to %" PRIu32, __FUNCTION__,
- data_size + padding);
+ LLDB_LOGF(log, "%s - element size set to %" PRIu32, __FUNCTION__,
+ data_size + padding);
}
// Given an allocation, this function copies the allocation contents from
@@ -2439,13 +2356,11 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
return nullptr;
}
}
@@ -2458,9 +2373,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
const uint32_t size = *alloc->size.get();
std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
if (!buffer) {
- if (log)
- log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer",
- __FUNCTION__, size);
+ LLDB_LOGF(log, "%s - couldn't allocate a %" PRIu32 " byte buffer",
+ __FUNCTION__, size);
return nullptr;
}
@@ -2469,10 +2383,10 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
lldb::addr_t data_ptr = *alloc->data_ptr.get();
GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err);
if (err.Fail()) {
- if (log)
- log->Printf("%s - '%s' Couldn't read %" PRIu32
- " bytes of allocation data from 0x%" PRIx64,
- __FUNCTION__, err.AsCString(), size, data_ptr);
+ LLDB_LOGF(log,
+ "%s - '%s' Couldn't read %" PRIu32
+ " bytes of allocation data from 0x%" PRIx64,
+ __FUNCTION__, err.AsCString(), size, data_ptr);
return nullptr;
}
@@ -2493,19 +2407,16 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
if (!alloc)
return false;
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
return false;
}
}
@@ -2559,9 +2470,8 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
sizeof(AllocationDetails::FileHeader),
sizeof(AllocationDetails::ElementHeader));
- if (log)
- log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32,
- __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
+ LLDB_LOGF(log, "%s - header type %" PRIu32 ", element size %" PRIu32,
+ __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
// Check if the target allocation and file both have the same number of bytes
// for an Element
@@ -2717,19 +2627,16 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
if (!alloc)
return false;
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
+ *alloc->address.get());
// JIT all the allocation details
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr)) {
- if (log)
- log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - couldn't JIT allocation details.", __FUNCTION__);
return false;
}
}
@@ -2743,14 +2650,14 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Check we can create writable file
FileSpec file_spec(path);
FileSystem::Instance().Resolve(file_spec);
- File file;
- FileSystem::Instance().Open(file, file_spec,
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate |
- File::eOpenOptionTruncate);
+ auto file = FileSystem::Instance().Open(
+ file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionTruncate);
if (!file) {
- strm.Printf("Error: Failed to open '%s' for writing", path);
+ std::string error = llvm::toString(file.takeError());
+ strm.Printf("Error: Failed to open '%s' for writing: %s", path,
+ error.c_str());
strm.EOL();
return false;
}
@@ -2779,11 +2686,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write the file header
size_t num_bytes = sizeof(AllocationDetails::FileHeader);
- if (log)
- log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
- (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
- Status err = file.Write(&head, num_bytes);
+ Status err = file.get()->Write(&head, num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2805,11 +2711,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write headers for allocation element type to file
num_bytes = element_header_size;
- if (log)
- log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.",
- __FUNCTION__, (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.",
+ __FUNCTION__, (uint64_t)num_bytes);
- err = file.Write(element_header_buffer.get(), num_bytes);
+ err = file.get()->Write(element_header_buffer.get(), num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2818,11 +2723,10 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
// Write allocation data to file
num_bytes = static_cast<size_t>(*alloc->size.get());
- if (log)
- log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
- (uint64_t)num_bytes);
+ LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
+ (uint64_t)num_bytes);
- err = file.Write(buffer.get(), num_bytes);
+ err = file.get()->Write(buffer.get(), num_bytes);
if (!err.Success()) {
strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
strm.EOL();
@@ -2894,17 +2798,17 @@ bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
addr_t addr = debug_present->GetLoadAddress(&target);
GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err);
if (err.Success()) {
- if (log)
- log->Printf("%s - debugger present flag set on debugee.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - debugger present flag set on debugee.",
+ __FUNCTION__);
m_debuggerPresentFlagged = true;
} else if (log) {
- log->Printf("%s - error writing debugger present flags '%s' ",
- __FUNCTION__, err.AsCString());
+ LLDB_LOGF(log, "%s - error writing debugger present flags '%s' ",
+ __FUNCTION__, err.AsCString());
}
} else if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"%s - error writing debugger present flags - symbol not found",
__FUNCTION__);
}
@@ -3004,8 +2908,7 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
return false;
}
- if (log)
- log->Printf("Found RenderScript reduction '%s'", spec[2].str().c_str());
+ LLDB_LOGF(log, "Found RenderScript reduction '%s'", spec[2].str().c_str());
m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size,
spec[2], spec[3], spec[4],
@@ -3082,10 +2985,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
{
const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes());
raw_rs_info.split(info_lines, '\n');
- if (log)
- log->Printf("'.rs.info symbol for '%s':\n%s",
- m_module->GetFileSpec().GetCString(),
- raw_rs_info.str().c_str());
+ LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s",
+ m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str());
}
enum {
@@ -3153,9 +3054,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
success = ParseVersionInfo(line, n_lines);
break;
default: {
- if (log)
- log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__,
- line->str().c_str());
+ LLDB_LOGF(log, "%s - skipping .rs.info field '%s'", __FUNCTION__,
+ line->str().c_str());
continue;
}
}
@@ -3276,15 +3176,13 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
if (!alloc)
return false; // FindAllocByID() will print error message for us here
- if (log)
- log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__,
- *alloc->address.get());
+ LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
+ *alloc->address.get());
// Check we have information about the allocation, if not calculate it
if (alloc->ShouldRefresh()) {
- if (log)
- log->Printf("%s - allocation details not calculated yet, jitting info.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
+ __FUNCTION__);
// JIT all the allocation information
if (!RefreshAllocation(alloc, frame_ptr)) {
@@ -3313,9 +3211,8 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
const uint32_t data_size = *alloc->element.datum_size.get();
- if (log)
- log->Printf("%s - element size %" PRIu32 " bytes, including padding",
- __FUNCTION__, data_size);
+ LLDB_LOGF(log, "%s - element size %" PRIu32 " bytes, including padding",
+ __FUNCTION__, data_size);
// Allocate a buffer to copy data into
std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
@@ -3340,10 +3237,10 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
const uint32_t size = *alloc->size.get(); // Size of whole allocation
const uint32_t padding =
alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
- if (log)
- log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32
- " bytes, padding %" PRIu32,
- __FUNCTION__, stride, size, padding);
+ LLDB_LOGF(log,
+ "%s - stride %" PRIu32 " bytes, size %" PRIu32
+ " bytes, padding %" PRIu32,
+ __FUNCTION__, stride, size, padding);
// Find dimensions used to index loops, so need to be non-zero
uint32_t dim_x = alloc->dimension.get()->dim_1;
@@ -3395,8 +3292,7 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
*alloc->data_ptr.get() + offset);
if (written < 0 || written >= jit_max_expr_size) {
- if (log)
- log->Printf("%s - error in snprintf().", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error in snprintf().", __FUNCTION__);
continue;
}
@@ -3573,17 +3469,16 @@ void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) {
for (const auto &module : m_rsmodules)
BreakOnModuleKernels(module);
- if (log)
- log->Printf("%s(True) - breakpoints set on all currently loaded kernels.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "%s(True) - breakpoints set on all currently loaded kernels.",
+ __FUNCTION__);
} else if (!do_break &&
m_breakAllKernels) // Breakpoints won't be set on any new kernels.
{
m_breakAllKernels = false;
- if (log)
- log->Printf("%s(False) - breakpoints no longer automatically set.",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s(False) - breakpoints no longer automatically set.",
+ __FUNCTION__);
}
}
@@ -3595,8 +3490,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) {
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3610,9 +3505,8 @@ RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) {
Status err;
target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
if (err.Fail() && log)
- if (log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
return bp;
}
@@ -3624,8 +3518,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name,
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3640,8 +3534,8 @@ RenderScriptRuntime::CreateReductionBreakpoint(ConstString name,
Status err;
target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
if (err.Fail() && log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
return bp;
}
@@ -3663,9 +3557,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
var_sp, err));
if (!err.Success()) {
- if (log)
- log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__,
- var_name);
+ LLDB_LOGF(log, "%s - error, couldn't find '%s' in frame", __FUNCTION__,
+ var_name);
return false;
}
@@ -3673,9 +3566,8 @@ bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
bool success = false;
val = value_sp->GetValueAsUnsigned(0, &success);
if (!success) {
- if (log)
- log->Printf("%s - error, couldn't parse '%s' as an uint32_t.",
- __FUNCTION__, var_name);
+ LLDB_LOGF(log, "%s - error, couldn't parse '%s' as an uint32_t.",
+ __FUNCTION__, var_name);
return false;
}
@@ -3695,8 +3587,7 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!thread_ptr) {
- if (log)
- log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__);
return false;
}
@@ -3718,17 +3609,15 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
if (!func_name)
continue;
- if (log)
- log->Printf("%s - Inspecting function '%s'", __FUNCTION__,
- func_name.GetCString());
+ LLDB_LOGF(log, "%s - Inspecting function '%s'", __FUNCTION__,
+ func_name.GetCString());
// Check if function name has .expand suffix
if (!func_name.GetStringRef().endswith(".expand"))
continue;
- if (log)
- log->Printf("%s - Found .expand function '%s'", __FUNCTION__,
- func_name.GetCString());
+ LLDB_LOGF(log, "%s - Found .expand function '%s'", __FUNCTION__,
+ func_name.GetCString());
// Get values for variables in .expand frame that tell us the current
// kernel invocation
@@ -3770,9 +3659,8 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
// Coordinate we want to stop on
RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton);
- if (log)
- log->Printf("%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, break_id,
- target_coord.x, target_coord.y, target_coord.z);
+ LLDB_LOGF(log, "%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__,
+ break_id, target_coord.x, target_coord.y, target_coord.z);
// Select current thread
ExecutionContext context(ctx->exe_ctx_ref);
@@ -3782,22 +3670,19 @@ bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
// Find current kernel invocation from .expand frame variables
RSCoordinate current_coord{};
if (!GetKernelCoordinate(current_coord, thread_ptr)) {
- if (log)
- log->Printf("%s - Error, couldn't select .expand stack frame",
- __FUNCTION__);
+ LLDB_LOGF(log, "%s - Error, couldn't select .expand stack frame",
+ __FUNCTION__);
return false;
}
- if (log)
- log->Printf("%s - " FMT_COORD, __FUNCTION__, current_coord.x,
- current_coord.y, current_coord.z);
+ LLDB_LOGF(log, "%s - " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
// Check if the current kernel invocation coordinate matches our target
// coordinate
if (target_coord == current_coord) {
- if (log)
- log->Printf("%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
- current_coord.y, current_coord.z);
+ LLDB_LOGF(log, "%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
+ current_coord.y, current_coord.z);
BreakpointSP breakpoint_sp =
context.GetTargetPtr()->GetBreakpointByID(break_id);
@@ -3865,8 +3750,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name,
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp) {
- if (log)
- log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
+ LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
+ __FUNCTION__);
return nullptr;
}
@@ -3880,8 +3765,8 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name,
Status err;
target.AddNameToBreakpoint(bp, name.GetCString(), err);
if (err.Fail() && log)
- log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
- err.AsCString());
+ LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
+ err.AsCString());
// ask the breakpoint to resolve itself
bp->ResolveBreakpoint();
return bp;
@@ -3964,9 +3849,8 @@ RenderScriptRuntime::CreateAllocation(addr_t address) {
auto it = m_allocations.begin();
while (it != m_allocations.end()) {
if (*((*it)->address) == address) {
- if (log)
- log->Printf("%s - Removing allocation id: %d, address: 0x%" PRIx64,
- __FUNCTION__, (*it)->id, address);
+ LLDB_LOGF(log, "%s - Removing allocation id: %d, address: 0x%" PRIx64,
+ __FUNCTION__, (*it)->id, address);
it = m_allocations.erase(it);
} else {
@@ -3988,9 +3872,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
Address resolved;
// RenderScript module
if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) {
- if (log)
- log->Printf("%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
- __FUNCTION__, kernel_addr);
+ LLDB_LOGF(log, "%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
+ __FUNCTION__, kernel_addr);
return false;
}
@@ -4000,9 +3883,8 @@ bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
name = sym->GetName();
assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule()));
- if (log)
- log->Printf("%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
- kernel_addr, name.GetCString());
+ LLDB_LOGF(log, "%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
+ kernel_addr, name.GetCString());
return true;
}
@@ -4256,13 +4138,12 @@ public:
// Matching a comma separated list of known words is fairly
// straightforward with PCRE, but we're using ERE, so we end up with a
// little ugliness...
- RegularExpression::Match match(/* max_matches */ 5);
RegularExpression match_type_list(
llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
assert(match_type_list.IsValid());
- if (!match_type_list.Execute(option_val, &match)) {
+ if (!match_type_list.Execute(option_val)) {
err_str.PutCString(
"a comma-separated list of kernel types is required");
return false;
@@ -4696,32 +4577,36 @@ public:
return false;
}
- Stream *output_strm = nullptr;
- StreamFile outfile_stream;
+ Stream *output_stream_p = nullptr;
+ std::unique_ptr<Stream> output_stream_storage;
+
const FileSpec &outfile_spec =
m_options.m_outfile; // Dump allocation to file instead
if (outfile_spec) {
// Open output file
std::string path = outfile_spec.GetPath();
- auto error = FileSystem::Instance().Open(
- outfile_stream.GetFile(), outfile_spec,
- File::eOpenOptionWrite | File::eOpenOptionCanCreate);
- if (error.Success()) {
- output_strm = &outfile_stream;
+ auto file = FileSystem::Instance().Open(
+ outfile_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate);
+ if (file) {
+ output_stream_storage =
+ std::make_unique<StreamFile>(std::move(file.get()));
+ output_stream_p = output_stream_storage.get();
result.GetOutputStream().Printf("Results written to '%s'",
path.c_str());
result.GetOutputStream().EOL();
} else {
- result.AppendErrorWithFormat("Couldn't open file '%s'", path.c_str());
+ std::string error = llvm::toString(file.takeError());
+ result.AppendErrorWithFormat("Couldn't open file '%s': %s",
+ path.c_str(), error.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
} else
- output_strm = &result.GetOutputStream();
+ output_stream_p = &result.GetOutputStream();
- assert(output_strm != nullptr);
+ assert(output_stream_p != nullptr);
bool dumped =
- runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
+ runtime->DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(), id);
if (dumped)
result.SetStatus(eReturnStatusSuccessFinishResult);
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 3923221d4302..c3740ba55a11 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -67,8 +67,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
@@ -117,8 +117,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
@@ -262,8 +262,8 @@ public:
void Dump(Stream *s) const override {}
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override;
+ SymbolContext &context,
+ Address *addr) override;
lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
index 4725e8c5b0eb..a6d225d2fbd8 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -93,9 +93,8 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
assert(orig && "CallInst has no called function");
llvm::FunctionType *orig_type = orig->getFunctionType();
auto name = orig->getName();
- if (log)
- log->Printf("%s - cloning to StructRet function for '%s'", __FUNCTION__,
- name.str().c_str());
+ LLDB_LOGF(log, "%s - cloning to StructRet function for '%s'", __FUNCTION__,
+ name.str().c_str());
unsigned num_params = orig_type->getNumParams();
std::vector<llvm::Type *> new_params{num_params + 1, nullptr};
@@ -113,9 +112,9 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) {
if (!return_type_ptr_type)
return nullptr;
- if (log)
- log->Printf("%s - return type pointer type for StructRet clone @ '0x%p':\n",
- __FUNCTION__, (void *)return_type_ptr_type);
+ LLDB_LOGF(log,
+ "%s - return type pointer type for StructRet clone @ '0x%p':\n",
+ __FUNCTION__, (void *)return_type_ptr_type);
// put the sret pointer argument in place at the beginning of the
// argument list.
params.emplace(params.begin(), return_type_ptr_type);
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index d489eaf11115..de17d986a860 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -16,7 +16,19 @@ using namespace lldb_private;
using namespace lldb_private::breakpad;
namespace {
-enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init };
+enum class Token {
+ Unknown,
+ Module,
+ Info,
+ CodeID,
+ File,
+ Func,
+ Public,
+ Stack,
+ CFI,
+ Init,
+ Win,
+};
}
template<typename T>
@@ -33,6 +45,7 @@ template <> Token stringTo<Token>(llvm::StringRef Str) {
.Case("STACK", Token::Stack)
.Case("CFI", Token::CFI)
.Case("INIT", Token::Init)
+ .Case("WIN", Token::Win)
.Default(Token::Unknown);
}
@@ -127,6 +140,8 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
switch (Tok) {
case Token::CFI:
return Record::StackCFI;
+ case Token::Win:
+ return Record::StackWin;
default:
return llvm::None;
}
@@ -134,13 +149,13 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
case Token::Unknown:
// Optimistically assume that any unrecognised token means this is a line
// record, those don't have a special keyword and start directly with a
- // hex number. CODE_ID should never be at the start of a line, but if it
- // is, it can be treated the same way as a garbled line record.
+ // hex number.
return Record::Line;
case Token::CodeID:
case Token::CFI:
case Token::Init:
+ case Token::Win:
// These should never appear at the start of a valid record.
return llvm::None;
}
@@ -390,6 +405,81 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
return OS << " " << R.UnwindRules;
}
+llvm::Optional<StackWinRecord> StackWinRecord::parse(llvm::StringRef Line) {
+ // STACK WIN type rva code_size prologue_size epilogue_size parameter_size
+ // saved_register_size local_size max_stack_size has_program_string
+ // program_string_OR_allocates_base_pointer
+
+ if (consume<Token>(Line) != Token::Stack)
+ return llvm::None;
+ if (consume<Token>(Line) != Token::Win)
+ return llvm::None;
+
+ llvm::StringRef Str;
+ uint8_t Type;
+ std::tie(Str, Line) = getToken(Line);
+ // Right now we only support the "FrameData" frame type.
+ if (!to_integer(Str, Type) || FrameType(Type) != FrameType::FrameData)
+ return llvm::None;
+
+ lldb::addr_t RVA;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, RVA, 16))
+ return llvm::None;
+
+ lldb::addr_t CodeSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, CodeSize, 16))
+ return llvm::None;
+
+ // Skip fields which we aren't using right now.
+ std::tie(Str, Line) = getToken(Line); // prologue_size
+ std::tie(Str, Line) = getToken(Line); // epilogue_size
+
+ lldb::addr_t ParameterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, ParameterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t SavedRegisterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, SavedRegisterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t LocalSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, LocalSize, 16))
+ return llvm::None;
+
+ std::tie(Str, Line) = getToken(Line); // max_stack_size
+
+ uint8_t HasProgramString;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, HasProgramString))
+ return llvm::None;
+ // FrameData records should always have a program string.
+ if (!HasProgramString)
+ return llvm::None;
+
+ return StackWinRecord(RVA, CodeSize, ParameterSize, SavedRegisterSize,
+ LocalSize, Line.trim());
+}
+
+bool breakpad::operator==(const StackWinRecord &L, const StackWinRecord &R) {
+ return L.RVA == R.RVA && L.CodeSize == R.CodeSize &&
+ L.ParameterSize == R.ParameterSize &&
+ L.SavedRegisterSize == R.SavedRegisterSize &&
+ L.LocalSize == R.LocalSize && L.ProgramString == R.ProgramString;
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const StackWinRecord &R) {
+ return OS << llvm::formatv(
+ "STACK WIN 4 {0:x-} {1:x-} ? ? {2} {3} {4} ? 1 {5}", R.RVA,
+ R.CodeSize, R.ParameterSize, R.SavedRegisterSize, R.LocalSize,
+ R.ProgramString);
+}
+
llvm::StringRef breakpad::toString(Record::Kind K) {
switch (K) {
case Record::Module:
@@ -406,6 +496,8 @@ llvm::StringRef breakpad::toString(Record::Kind K) {
return "PUBLIC";
case Record::StackCFI:
return "STACK CFI";
+ case Record::StackWin:
+ return "STACK WIN";
}
llvm_unreachable("Unknown record kind!");
}
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 5d5cdb319c10..27bef975125d 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -20,7 +20,7 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, StackCFI };
+ enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin };
/// Attempt to guess the kind of the record present in the argument without
/// doing a full parse. The returned kind will always be correct for valid
@@ -157,6 +157,29 @@ public:
bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);
+class StackWinRecord : public Record {
+public:
+ static llvm::Optional<StackWinRecord> parse(llvm::StringRef Line);
+
+ StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize,
+ lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize,
+ lldb::addr_t LocalSize, llvm::StringRef ProgramString)
+ : Record(StackWin), RVA(RVA), CodeSize(CodeSize),
+ ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize),
+ LocalSize(LocalSize), ProgramString(ProgramString) {}
+
+ enum class FrameType : uint8_t { FPO = 0, FrameData = 4 };
+ lldb::addr_t RVA;
+ lldb::addr_t CodeSize;
+ lldb::addr_t ParameterSize;
+ lldb::addr_t SavedRegisterSize;
+ lldb::addr_t LocalSize;
+ llvm::StringRef ProgramString;
+};
+
+bool operator==(const StackWinRecord &L, const StackWinRecord &R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);
+
} // namespace breakpad
} // namespace lldb_private
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 60dd9f9cecf0..3b9e0e2092a9 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -42,6 +42,8 @@ llvm::Optional<Header> Header::parse(llvm::StringRef text) {
return Header{ArchSpec(triple), std::move(uuid)};
}
+char ObjectFileBreakpad::ID;
+
void ObjectFileBreakpad::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
@@ -125,7 +127,7 @@ Symtab *ObjectFileBreakpad::GetSymtab() {
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
llvm::Optional<Record::Kind> current_section;
offset_t section_start;
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index e8885e0cc898..cb4bba01fb71 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -48,6 +48,13 @@ public:
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;
@@ -78,8 +85,6 @@ public:
UUID GetUUID() override { return m_uuid; }
- FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); }
-
uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
Type CalculateType() override { return eTypeDebugInfo; }
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index d62afa34bbe8..3f8502548fc2 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/LZMA.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
@@ -29,12 +30,13 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
-
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MipsABIFlags.h"
@@ -80,41 +82,6 @@ const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
-// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_AUXV 6
-#define NT_SIGINFO 0x53494749
-#define NT_FILE 0x46494c45
-#define NT_PRXFPREG 0x46e62b7f
-#define NT_PPC_VMX 0x100
-#define NT_PPC_SPE 0x101
-#define NT_PPC_VSX 0x102
-#define NT_386_TLS 0x200
-#define NT_386_IOPERM 0x201
-#define NT_X86_XSTATE 0x202
-#define NT_S390_HIGH_GPRS 0x300
-#define NT_S390_TIMER 0x301
-#define NT_S390_TODCMP 0x302
-#define NT_S390_TODPREG 0x303
-#define NT_S390_CTRS 0x304
-#define NT_S390_PREFIX 0x305
-#define NT_S390_LAST_BREAK 0x306
-#define NT_S390_SYSTEM_CALL 0x307
-#define NT_S390_TDB 0x308
-#define NT_S390_VXRS_LOW 0x309
-#define NT_S390_VXRS_HIGH 0x30a
-#define NT_ARM_VFP 0x400
-#define NT_ARM_TLS 0x401
-#define NT_ARM_HW_BREAK 0x402
-#define NT_ARM_HW_WATCH 0x403
-#define NT_ARM_SYSTEM_CALL 0x404
-#define NT_METAG_CBUF 0x500
-#define NT_METAG_RPIPE 0x501
-#define NT_METAG_TLS 0x502
-
//===----------------------------------------------------------------------===//
/// \class ELFRelocation
/// Generic wrapper for ELFRel and ELFRela.
@@ -264,8 +231,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
if (cstr == nullptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
- if (log)
- log->Printf("Failed to parse note name lacking nul terminator");
+ LLDB_LOGF(log, "Failed to parse note name lacking nul terminator");
return false;
}
@@ -333,6 +299,8 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
return LLDB_INVALID_CPUTYPE;
}
+char ObjectFileELF::ID;
+
// Arbitrary constant used as UUID prefix for core files.
const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
@@ -429,67 +397,9 @@ bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
return false;
}
-/*
- * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
- *
- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
- * code or tables extracted from it, as desired without restriction.
- */
-static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) {
- static const uint32_t g_crc32_tab[] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
- const uint8_t *p = (const uint8_t *)buf;
-
- crc = crc ^ ~0U;
- while (size--)
- crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
- return crc ^ ~0U;
-}
-
-static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
- return calc_crc32(0U, buf, size);
+static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) {
+ return llvm::crc32(
+ init, llvm::makeArrayRef(data.GetDataStart(), data.GetByteSize()));
}
uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
@@ -509,8 +419,7 @@ uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
break;
}
- core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(),
- segment_data.GetByteSize());
+ core_notes_crc = calc_crc32(core_notes_crc, segment_data);
}
}
@@ -608,10 +517,9 @@ size_t ObjectFileELF::GetModuleSpecifications(
llvm::Triple::OSType spec_ostype =
spec.GetArchitecture().GetTriple().getOS();
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s",
- __FUNCTION__, file.GetPath().c_str(),
- OSABIAsCString(header.e_ident[EI_OSABI]));
+ LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s",
+ __FUNCTION__, file.GetPath().c_str(),
+ OSABIAsCString(header.e_ident[EI_OSABI]));
// SetArchitecture should have set the vendor to unknown
vendor = spec.GetArchitecture().GetTriple().getVendor();
@@ -623,10 +531,10 @@ size_t ObjectFileELF::GetModuleSpecifications(
GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
assert(spec_ostype == ostype);
if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type "
- "from ELF header OSABI.",
- __FUNCTION__, file.GetPath().c_str());
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s file '%s' set ELF module OS type "
+ "from ELF header OSABI.",
+ __FUNCTION__, file.GetPath().c_str());
}
data_sp = MapFileData(file, -1, file_offset);
@@ -652,12 +560,12 @@ size_t ObjectFileELF::GetModuleSpecifications(
llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
- if (log)
- log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s "
- "(architecture %s)",
- __FUNCTION__, file.GetPath().c_str(),
- spec_triple.getTriple().c_str(),
- spec.GetArchitecture().GetArchitectureName());
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s file '%s' module set to triple: %s "
+ "(architecture %s)",
+ __FUNCTION__, file.GetPath().c_str(),
+ spec_triple.getTriple().c_str(),
+ spec.GetArchitecture().GetArchitectureName());
if (!uuid.IsValid()) {
uint32_t core_notes_crc = 0;
@@ -682,8 +590,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
core_notes_crc =
CalculateELFNotesSegmentsCRC32(program_headers, data);
} else {
- gnu_debuglink_crc = calc_gnu_debuglink_crc32(
- data.GetDataStart(), data.GetByteSize());
+ gnu_debuglink_crc = calc_crc32(0, data);
}
}
using u32le = llvm::support::ulittle32_t;
@@ -721,27 +628,16 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp, lldb::offset_t data_offset,
const FileSpec *file, lldb::offset_t file_offset,
lldb::offset_t length)
- : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
- m_program_headers(), m_section_headers(), m_dynamic_symbols(),
- m_filespec_up(), m_entry_point_address(), m_arch_spec() {
+ : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
if (file)
m_file = *file;
- ::memset(&m_header, 0, sizeof(m_header));
}
ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
DataBufferSP &header_data_sp,
const lldb::ProcessSP &process_sp,
addr_t header_addr)
- : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
- m_program_headers(), m_section_headers(), m_dynamic_symbols(),
- m_filespec_up(), m_entry_point_address(), m_arch_spec() {
- ::memset(&m_header, 0, sizeof(m_header));
-}
-
-ObjectFileELF::~ObjectFileELF() {}
+ : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
bool ObjectFileELF::IsExecutable() const {
return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
@@ -872,8 +768,7 @@ UUID ObjectFileELF::GetUUID() {
}
} else {
if (!m_gnu_debuglink_crc)
- m_gnu_debuglink_crc = calc_gnu_debuglink_crc32(m_data.GetDataStart(),
- m_data.GetByteSize());
+ m_gnu_debuglink_crc = calc_crc32(0, m_data);
if (m_gnu_debuglink_crc) {
// Use 4 bytes of crc from the .gnu_debuglink section.
u32le data(m_gnu_debuglink_crc);
@@ -885,14 +780,10 @@ UUID ObjectFileELF::GetUUID() {
return m_uuid;
}
-lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
- FileSpecList file_spec_list;
-
- if (!m_gnu_debuglink_file.empty()) {
- FileSpec file_spec(m_gnu_debuglink_file);
- file_spec_list.Append(file_spec);
- }
- return file_spec_list;
+llvm::Optional<FileSpec> ObjectFileELF::GetDebugLink() {
+ if (m_gnu_debuglink_file.empty())
+ return llvm::None;
+ return FileSpec(m_gnu_debuglink_file);
}
uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
@@ -1120,9 +1011,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
return error;
}
- if (log)
- log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
- __FUNCTION__, note.n_name.c_str(), note.n_type);
+ LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
+ __FUNCTION__, note.n_name.c_str(), note.n_type);
// Process FreeBSD ELF notes.
if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
@@ -1147,11 +1037,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOSName(os_name);
arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
- ".%" PRIu32,
- __FUNCTION__, version_major, version_minor,
- static_cast<uint32_t>(version_info % 1000));
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
+ ".%" PRIu32,
+ __FUNCTION__, version_major, version_minor,
+ static_cast<uint32_t>(version_info % 1000));
}
// Process GNU ELF notes.
else if (note.n_name == LLDB_NT_OWNER_GNU) {
@@ -1172,12 +1062,11 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf(
- "ObjectFileELF::%s detected Linux, min version %" PRIu32
- ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Linux, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
// FIXME we have the minimal version number, we could be propagating
// that. version_info[1] = OS Major, version_info[2] = OS Minor,
// version_info[3] = Revision.
@@ -1186,30 +1075,28 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min "
- "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Hurd (unsupported), min "
+ "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
break;
case LLDB_NT_GNU_ABI_OS_SOLARIS:
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
arch_spec.GetTriple().setVendor(
llvm::Triple::VendorType::UnknownVendor);
- if (log)
- log->Printf(
- "ObjectFileELF::%s detected Solaris, min version %" PRIu32
- ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[1], version_info[2],
- version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s detected Solaris, min version %" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[1], version_info[2],
+ version_info[3]);
break;
default:
- if (log)
- log->Printf(
- "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
- ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
- __FUNCTION__, version_info[0], version_info[1],
- version_info[2], version_info[3]);
+ LLDB_LOGF(log,
+ "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
+ ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
+ __FUNCTION__, version_info[0], version_info[1],
+ version_info[2], version_info[3]);
break;
}
}
@@ -1618,9 +1505,8 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
section_size) == section_size)) {
Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
if (error.Fail()) {
- if (log)
- log->Printf("ObjectFileELF::%s ELF note processing failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s",
+ __FUNCTION__, error.AsCString());
}
}
}
@@ -1790,6 +1676,8 @@ class VMAddressProvider {
VMMap Segments = VMMap(Alloc);
VMMap Sections = VMMap(Alloc);
lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ size_t SegmentCount = 0;
+ std::string SegmentName;
VMRange GetVMRange(const ELFSectionHeader &H) {
addr_t Address = H.sh_addr;
@@ -1804,18 +1692,23 @@ class VMAddressProvider {
}
public:
- VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {}
+ VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
+ : ObjectType(Type), SegmentName(SegmentName) {}
+
+ std::string GetNextSegmentName() const {
+ return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
+ }
llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
if (H.p_memsz == 0) {
- LLDB_LOG(Log,
- "Ignoring zero-sized PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
- LLDB_LOG(Log,
- "Ignoring overlapping PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
return VMRange(H.p_vaddr, H.p_memsz);
@@ -1850,6 +1743,7 @@ public:
void AddSegment(const VMRange &Range, SectionSP Seg) {
Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
+ ++SegmentCount;
}
void AddSection(SectionAddressInfo Info, SectionSP Sect) {
@@ -1867,29 +1761,32 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
- m_sections_up = llvm::make_unique<SectionList>();
- VMAddressProvider address_provider(GetType());
+ m_sections_up = std::make_unique<SectionList>();
+ VMAddressProvider regular_provider(GetType(), "PT_LOAD");
+ VMAddressProvider tls_provider(GetType(), "PT_TLS");
- size_t LoadID = 0;
for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
const ELFProgramHeader &PHdr = EnumPHdr.value();
- if (PHdr.p_type != PT_LOAD)
+ if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS)
continue;
- auto InfoOr = address_provider.GetAddressInfo(PHdr);
+ VMAddressProvider &provider =
+ PHdr.p_type == PT_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(PHdr);
if (!InfoOr)
continue;
- ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str());
uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
SectionSP Segment = std::make_shared<Section>(
- GetModule(), this, SegmentID(EnumPHdr.index()), Name,
- eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),
- PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);
+ GetModule(), this, SegmentID(EnumPHdr.index()),
+ ConstString(provider.GetNextSegmentName()), eSectionTypeContainer,
+ InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset,
+ PHdr.p_filesz, Log2Align, /*flags*/ 0);
Segment->SetPermissions(GetPermissions(PHdr));
+ Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS);
m_sections_up->AddSection(Segment);
- address_provider.AddSegment(*InfoOr, std::move(Segment));
+ provider.AddSegment(*InfoOr, std::move(Segment));
}
ParseSectionHeaders();
@@ -1904,7 +1801,9 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
const uint64_t file_size =
header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
- auto InfoOr = address_provider.GetAddressInfo(header);
+ VMAddressProvider &provider =
+ header.sh_flags & SHF_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(header);
if (!InfoOr)
continue;
@@ -1935,13 +1834,77 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
(InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)
.AddSection(section_sp);
- address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));
+ provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
// For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
// unified section list.
if (GetType() != eTypeDebugInfo)
unified_section_list = *m_sections_up;
+
+ // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
+ // embedded in there and replace the one in the original object file (if any).
+ // If there's none in the orignal object file, we add it to it.
+ if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) {
+ if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
+ if (SectionSP symtab_section_sp =
+ gdd_objfile_section_list->FindSectionByType(
+ eSectionTypeELFSymbolTable, true)) {
+ SectionSP module_section_sp = unified_section_list.FindSectionByType(
+ eSectionTypeELFSymbolTable, true);
+ if (module_section_sp)
+ unified_section_list.ReplaceSection(module_section_sp->GetID(),
+ symtab_section_sp);
+ else
+ unified_section_list.AddSection(symtab_section_sp);
+ }
+ }
+ }
+}
+
+std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
+ if (m_gnu_debug_data_object_file != nullptr)
+ return m_gnu_debug_data_object_file;
+
+ SectionSP section =
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"));
+ if (!section)
+ return nullptr;
+
+ if (!lldb_private::lzma::isAvailable()) {
+ GetModule()->ReportWarning(
+ "No LZMA support found for reading .gnu_debugdata section");
+ return nullptr;
+ }
+
+ // Uncompress the data
+ DataExtractor data;
+ section->GetSectionData(data);
+ llvm::SmallVector<uint8_t, 0> uncompressedData;
+ auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData);
+ if (err) {
+ GetModule()->ReportWarning(
+ "An error occurred while decompression the section %s: %s",
+ section->GetName().AsCString(), llvm::toString(std::move(err)).c_str());
+ return nullptr;
+ }
+
+ // Construct ObjectFileELF object from decompressed buffer
+ DataBufferSP gdd_data_buf(
+ new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
+ auto fspec = GetFileSpec().CopyByAppendingPathComponent(
+ llvm::StringRef("gnu_debugdata"));
+ m_gnu_debug_data_object_file.reset(new ObjectFileELF(
+ GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
+
+ // This line is essential; otherwise a breakpoint can be set but not hit.
+ m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo);
+
+ ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
+ if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
+ return m_gnu_debug_data_object_file;
+
+ return nullptr;
}
// Find the arm/aarch64 mapping symbol character in the given symbol name.
@@ -2246,8 +2209,6 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
bool is_global = symbol.getBinding() == STB_GLOBAL;
uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
- bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z');
-
llvm::StringRef symbol_ref(symbol_name);
// Symbol names may contain @VERSION suffixes. Find those and strip them
@@ -2255,7 +2216,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
size_t version_pos = symbol_ref.find('@');
bool has_suffix = version_pos != llvm::StringRef::npos;
llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
- Mangled mangled(ConstString(symbol_bare), is_mangled);
+ Mangled mangled(symbol_bare);
// Now append the suffix back to mangled and unmangled names. Only do it if
// the demangling was successful (string is not empty).
@@ -2486,14 +2447,11 @@ static unsigned ParsePLTRelocations(
break;
const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
- bool is_mangled =
- symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
uint64_t plt_index = plt_offset + i * plt_entsize;
Symbol jump_symbol(
i + start_id, // Symbol table index
symbol_name, // symbol name.
- is_mangled, // is the symbol name mangled?
eSymbolTypeTrampoline, // Type of this symbol
false, // Is this globally visible?
false, // Is this symbol debug info?
@@ -2654,7 +2612,7 @@ unsigned ObjectFileELF::ApplyRelocations(
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
Log *log =
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
- log->Printf("Failed to apply debug info relocations");
+ LLDB_LOGF(log, "Failed to apply debug info relocations");
break;
}
uint32_t truncated_addr = (value & 0xFFFFFFFF);
@@ -2749,19 +2707,29 @@ Symtab *ObjectFileELF::GetSymtab() {
// while the reverse is not necessarily true.
Section *symtab =
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (!symtab) {
- // The symtab section is non-allocable and can be stripped, so if it
- // doesn't exist then use the dynsym section which should always be
- // there.
- symtab =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- }
if (symtab) {
m_symtab_up.reset(new Symtab(symtab->GetObjectFile()));
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
}
+ // The symtab section is non-allocable and can be stripped, while the
+ // .dynsym section which should always be always be there. To support the
+ // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+ // section, nomatter if .symtab was already parsed or not. This is because
+ // minidebuginfo normally removes the .symtab symbols which have their
+ // matching .dynsym counterparts.
+ if (!symtab ||
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym) {
+ if (!m_symtab_up)
+ m_symtab_up.reset(new Symtab(dynsym->GetObjectFile()));
+ symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
+ }
+ }
+
// DT_JMPREL
// If present, this entry's d_ptr member holds the address of
// relocation
@@ -2803,6 +2771,50 @@ Symtab *ObjectFileELF::GetSymtab() {
if (m_symtab_up == nullptr)
m_symtab_up.reset(new 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
+ // 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.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ if (CalculateType() == eTypeExecutable) {
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress();
+ bool is_valid_entry_point =
+ entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+ addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+ if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
+ uint64_t symbol_id = m_symtab_up->GetNumSymbols();
+ Symbol symbol(symbol_id,
+ GetNextSyntheticSymbolName().GetCString(), // Symbol name.
+ eSymbolTypeCode, // Type of this symbol.
+ true, // Is this globally visible?
+ false, // Is this symbol debug info?
+ false, // Is this symbol a trampoline?
+ true, // Is this symbol artificial?
+ entry_point_addr.GetSection(), // Section where this
+ // symbol is defined.
+ 0, // Offset in section or symbol value.
+ 0, // Size.
+ false, // Size is valid.
+ false, // Contains linker annotations?
+ 0); // Symbol flags.
+ m_symtab_up->AddSymbol(symbol);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this
+ // address.
+ if (arch.GetMachine() == llvm::Triple::arm &&
+ (entry_point_file_addr & 1))
+ m_address_class_map[entry_point_file_addr ^ 1] =
+ AddressClass::eCodeAlternateISA;
+ else
+ m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+ }
+ }
+
m_symtab_up->CalculateSymbolSizes();
}
@@ -2881,7 +2893,6 @@ void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
Symbol eh_symbol(
symbol_id, // Symbol table index.
symbol_name, // Symbol name.
- false, // Is the symbol name mangled?
eSymbolTypeCode, // Type of this symbol.
true, // Is this globally visible?
false, // Is this symbol debug info?
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index b63a5d14d4f5..3b273896cb59 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -56,8 +56,6 @@ struct ELFNote {
/// the ObjectFile protocol.
class ObjectFileELF : public lldb_private::ObjectFile {
public:
- ~ObjectFileELF() override;
-
// Static Functions
static void Initialize();
@@ -91,6 +89,13 @@ public:
uint32_t GetPluginVersion() override;
+ // 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;
@@ -117,7 +122,9 @@ public:
lldb_private::UUID GetUUID() override;
- lldb_private::FileSpecList GetDebugSymbolFilePaths() override;
+ /// Return the contents of the .gnu_debuglink section, if the object file
+ /// contains it.
+ llvm::Optional<lldb_private::FileSpec> GetDebugLink();
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -190,7 +197,7 @@ private:
/// ELF .gnu_debuglink file and crc data if available.
std::string m_gnu_debuglink_file;
- uint32_t m_gnu_debuglink_crc;
+ uint32_t m_gnu_debuglink_crc = 0;
/// Collection of program headers.
ProgramHeaderColl m_program_headers;
@@ -201,6 +208,10 @@ private:
/// Collection of symbols from the dynamic table.
DynamicSymbolColl m_dynamic_symbols;
+ /// Object file parsed from .gnu_debugdata section (\sa
+ /// GetGnuDebugDataObjectFile())
+ std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file;
+
/// List of file specifications corresponding to the modules (shared
/// libraries) on which this object file depends.
mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up;
@@ -376,6 +387,14 @@ private:
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
+
+ /// Takes the .gnu_debugdata and returns the decompressed object file that is
+ /// stored within that section.
+ ///
+ /// \returns either the decompressed object file stored within the
+ /// .gnu_debugdata section or \c nullptr if an error occured or if there's no
+ /// section with that name.
+ std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();
};
#endif // liblldb_ObjectFileELF_h_
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index eaf973da3835..c55b96d9110b 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -39,6 +39,8 @@
using namespace lldb;
using namespace lldb_private;
+char ObjectFileJIT::ID;
+
void ObjectFileJIT::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index 99241126cd1a..c992683cfc3c 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -46,6 +46,13 @@ public:
lldb::offset_t length,
lldb_private::ModuleSpecList &specs);
+ // 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); }
+
// Member Functions
bool ParseHeader() override;
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index c1fe0cc8ddda..b777a5319104 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -120,10 +120,10 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
return nullptr;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
- if (log)
- log->Printf("OperatingSystemPython::GetDynamicRegisterInfo() fetching "
- "thread register definitions from python for pid %" PRIu64,
- m_process->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::GetDynamicRegisterInfo() fetching "
+ "thread register definitions from python for pid %" PRIu64,
+ m_process->GetID());
StructuredData::DictionarySP dictionary =
m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
@@ -169,12 +169,12 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
api_lock.try_lock();
auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
- if (log)
- log->Printf("OperatingSystemPython::UpdateThreadList() fetching thread "
- "data from python for pid %" PRIu64,
- m_process->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::UpdateThreadList() fetching thread "
+ "data from python for pid %" PRIu64,
+ m_process->GetID());
- // The threads that are in "new_thread_list" upon entry are the threads from
+ // The threads that are in "core_thread_list" upon entry are the threads from
// the lldb_private::Process subclass, no memory threads will be in this
// list.
StructuredData::ArraySP threads_list =
@@ -190,7 +190,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
if (log) {
StreamString strm;
threads_list->Dump(strm);
- log->Printf("threads_list = %s", strm.GetData());
+ LLDB_LOGF(log, "threads_list = %s", strm.GetData());
}
const uint32_t num_threads = threads_list->GetSize();
@@ -316,21 +316,21 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
if (reg_data_addr != LLDB_INVALID_ADDRESS) {
// The registers data is in contiguous memory, just create the register
// context using the address provided
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64
- ") creating memory register context",
- thread->GetID(), thread->GetProtocolID(), reg_data_addr);
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64
+ ") creating memory register context",
+ thread->GetID(), thread->GetProtocolID(), reg_data_addr);
reg_ctx_sp = std::make_shared<RegisterContextMemory>(
*thread, 0, *GetDynamicRegisterInfo(), reg_data_addr);
} else {
// No register data address is provided, query the python plug-in to let it
// make up the data as it sees fit
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ", 0x%" PRIx64
- ") fetching register data from python",
- thread->GetID(), thread->GetProtocolID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ", 0x%" PRIx64
+ ") fetching register data from python",
+ thread->GetID(), thread->GetProtocolID());
StructuredData::StringSP reg_context_data =
m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
@@ -351,10 +351,10 @@ OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
// if we still have no register data, fallback on a dummy context to avoid
// crashing
if (!reg_ctx_sp) {
- if (log)
- log->Printf("OperatingSystemPython::CreateRegisterContextForThread (tid "
- "= 0x%" PRIx64 ") forcing a dummy register context",
- thread->GetID());
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateRegisterContextForThread (tid "
+ "= 0x%" PRIx64 ") forcing a dummy register context",
+ thread->GetID());
reg_ctx_sp = std::make_shared<RegisterContextDummy>(
*thread, 0, target.GetArchitecture().GetAddressByteSize());
}
@@ -375,10 +375,10 @@ lldb::ThreadSP OperatingSystemPython::CreateThread(lldb::tid_t tid,
addr_t context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64
- ", context = 0x%" PRIx64 ") fetching register data from python",
- tid, context);
+ LLDB_LOGF(log,
+ "OperatingSystemPython::CreateThread (tid = 0x%" PRIx64
+ ", context = 0x%" PRIx64 ") fetching register data from python",
+ tid, context);
if (m_interpreter && m_python_object_sp) {
// First thing we have to do is to try to get the API lock, and the
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index d10557596ff8..b12e21deb459 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -27,11 +27,11 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/ScopeExit.h"
using namespace lldb;
using namespace lldb_private;
@@ -276,8 +276,7 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
} else
command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(),
GetHostname(), dst_path.c_str());
- if (log)
- log->Printf("[PutFile] Running command: %s\n", command.GetData());
+ LLDB_LOGF(log, "[PutFile] Running command: %s\n", command.GetData());
int retcode;
Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr,
nullptr, std::chrono::minutes(1));
@@ -334,8 +333,7 @@ lldb_private::Status PlatformPOSIX::GetFile(
command.Printf("rsync %s %s:%s %s", GetRSyncOpts(),
m_remote_platform_sp->GetHostname(), src_path.c_str(),
dst_path.c_str());
- if (log)
- log->Printf("[GetFile] Running command: %s\n", command.GetData());
+ LLDB_LOGF(log, "[GetFile] Running command: %s\n", command.GetData());
int retcode;
Host::RunShellCommand(command.GetData(), nullptr, &retcode, nullptr,
nullptr, std::chrono::minutes(1));
@@ -348,8 +346,7 @@ lldb_private::Status PlatformPOSIX::GetFile(
// read/write, read/write, read/write, ...
// close src
// close dst
- if (log)
- log->Printf("[GetFile] Using block by block transfer....\n");
+ LLDB_LOGF(log, "[GetFile] Using block by block transfer....\n");
Status error;
user_id_t fd_src = OpenFile(source, File::eOpenOptionRead,
lldb::eFilePermissionsFileDefault, error);
@@ -515,24 +512,21 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
error = debugger.GetTargetList().CreateTarget(
debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
target = new_target_sp.get();
- if (log)
- log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__);
+ LLDB_LOGF(log, "PlatformPOSIX::%s created new target", __FUNCTION__);
} else {
error.Clear();
- if (log)
- log->Printf("PlatformPOSIX::%s target already existed, setting target",
- __FUNCTION__);
+ LLDB_LOGF(log, "PlatformPOSIX::%s target already existed, setting target",
+ __FUNCTION__);
}
if (target && error.Success()) {
debugger.GetTargetList().SetSelectedTarget(target);
if (log) {
ModuleSP exe_module_sp = target->GetExecutableModule();
- log->Printf("PlatformPOSIX::%s set selected target to %p %s",
- __FUNCTION__, (void *)target,
- exe_module_sp
- ? exe_module_sp->GetFileSpec().GetPath().c_str()
- : "<null>");
+ LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s",
+ __FUNCTION__, (void *)target,
+ exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>");
}
process_sp =
@@ -804,12 +798,13 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
"for path: %s", utility_error.AsCString());
return LLDB_INVALID_IMAGE_TOKEN;
}
-
+
// Make sure we deallocate the input string memory:
- CleanUp path_cleanup([process, path_addr] {
- process->DeallocateMemory(path_addr);
+ auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
+ // Deallocate the buffer.
+ process->DeallocateMemory(path_addr);
});
-
+
process->WriteMemory(path_addr, path.c_str(), path_len, utility_error);
if (utility_error.Fail()) {
error.SetErrorStringWithFormat("dlopen error: could not write path string:"
@@ -830,21 +825,24 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the result structure memory
- CleanUp return_cleanup([process, return_addr] {
- process->DeallocateMemory(return_addr);
+ auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
+ // Deallocate the buffer
+ process->DeallocateMemory(return_addr);
});
-
+
// This will be the address of the storage for paths, if we are using them,
// or nullptr to signal we aren't.
lldb::addr_t path_array_addr = 0x0;
- llvm::Optional<CleanUp> path_array_cleanup;
+ llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
+ path_array_cleanup;
// This is the address to a buffer large enough to hold the largest path
// conjoined with the library name we're passing in. This is a convenience
// to avoid having to call malloc in the dlopen function.
lldb::addr_t buffer_addr = 0x0;
- llvm::Optional<CleanUp> buffer_cleanup;
-
+ llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
+ buffer_cleanup;
+
// Set the values into our args and write them to the target:
if (paths != nullptr) {
// First insert the paths into the target. This is expected to be a
@@ -877,8 +875,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the paths array.
- path_array_cleanup.emplace([process, path_array_addr] {
- process->DeallocateMemory(path_array_addr);
+ path_array_cleanup.emplace([process, path_array_addr]() {
+ // Deallocate the path array.
+ process->DeallocateMemory(path_array_addr);
});
process->WriteMemory(path_array_addr, path_array.data(),
@@ -904,8 +903,9 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
}
// Make sure we deallocate the buffer memory:
- buffer_cleanup.emplace([process, buffer_addr] {
- process->DeallocateMemory(buffer_addr);
+ buffer_cleanup.emplace([process, buffer_addr]() {
+ // Deallocate the buffer.
+ process->DeallocateMemory(buffer_addr);
});
}
@@ -930,10 +930,11 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
// Make sure we clean up the args structure. We can't reuse it because the
// Platform lives longer than the process and the Platforms don't get a
// signal to clean up cached data when a process goes away.
- CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
- do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
- });
-
+ auto args_cleanup =
+ llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
+ do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
+ });
+
// Now run the caller:
EvaluateExpressionOptions options;
options.SetExecutionPolicy(eExecutionPolicyAlways);
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 9c52b59e2b06..1e62ddfe94fd 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -169,21 +169,21 @@ bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec,
const auto module_path = module_file_spec.GetPath(false);
if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) {
- if (log)
- log->Printf(
- "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_path.c_str(),
- arch.GetTriple().getTriple().c_str());
+ LLDB_LOGF(
+ log,
+ "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_path.c_str(),
+ arch.GetTriple().getTriple().c_str());
return false;
}
if (log) {
StreamString stream;
module_spec.Dump(stream);
- log->Printf(
- "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_path.c_str(), arch.GetTriple().getTriple().c_str(),
- stream.GetData());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_path.c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
}
return true;
@@ -253,9 +253,9 @@ FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
FileSpec working_dir;
if (m_gdb_client.GetWorkingDir(working_dir) && log)
- log->Printf(
- "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
- working_dir.GetCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
+ working_dir.GetCString());
return working_dir;
} else {
return Platform::GetRemoteWorkingDirectory();
@@ -268,9 +268,8 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
// Clear the working directory it case it doesn't get set correctly. This
// will for use to re-read it
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
- working_dir.GetCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
+ working_dir.GetCString());
return m_gdb_client.SetWorkingDir(working_dir) == 0;
} else
return Platform::SetRemoteWorkingDirectory(working_dir);
@@ -370,8 +369,7 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
Status error;
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__);
auto num_file_actions = launch_info.GetNumFileActions();
for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
@@ -408,10 +406,10 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
const char *arch_triple = arch_spec.GetTriple().str().c_str();
m_gdb_client.SendLaunchArchPacket(arch_triple);
- if (log)
- log->Printf(
- "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
- __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
+ LLDB_LOGF(
+ log,
+ "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
+ __FUNCTION__, arch_triple ? arch_triple : "<NULL>");
int arg_packet_err;
{
@@ -427,22 +425,21 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
const auto pid = m_gdb_client.GetCurrentProcessID(false);
if (pid != LLDB_INVALID_PROCESS_ID) {
launch_info.SetProcessID(pid);
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() pid %" PRIu64
- " launched successfully",
- __FUNCTION__, pid);
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s() pid %" PRIu64
+ " launched successfully",
+ __FUNCTION__, pid);
} else {
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() launch succeeded but we "
- "didn't get a valid process id back!",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::%s() launch succeeded but we "
+ "didn't get a valid process id back!",
+ __FUNCTION__);
error.SetErrorString("failed to get PID");
}
} else {
error.SetErrorString(error_str.c_str());
- if (log)
- log->Printf("PlatformRemoteGDBServer::%s() launch failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() launch failed: %s",
+ __FUNCTION__, error.AsCString());
}
} else {
error.SetErrorStringWithFormat("'A' packet returned an error: %i",
@@ -600,11 +597,10 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
uint32_t mode) {
Status error = m_gdb_client.MakeDirectory(file_spec, mode);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
- "error = %u (%s)",
- file_spec.GetCString(), mode, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
+ "error = %u (%s)",
+ file_spec.GetCString(), mode, error.GetError(), error.AsCString());
return error;
}
@@ -612,11 +608,11 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions) {
Status error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
- "file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
return error;
}
@@ -624,16 +620,17 @@ Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions) {
Status error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
- "file_permissions=%o) error = %u (%s)",
- file_spec.GetCString(), file_permissions, error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
+ "file_permissions=%o) error = %u (%s)",
+ file_spec.GetCString(), file_permissions, error.GetError(),
+ error.AsCString());
return error;
}
lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
- uint32_t flags, uint32_t mode,
+ File::OpenOptions flags,
+ uint32_t mode,
Status &error) {
return m_gdb_client.OpenFile(file_spec, flags, mode, error);
}
@@ -671,20 +668,19 @@ Status PlatformRemoteGDBServer::CreateSymlink(
{
Status error = m_gdb_client.CreateSymlink(src, dst);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
- "error = %u (%s)",
- src.GetCString(), dst.GetCString(), error.GetError(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
+ "error = %u (%s)",
+ src.GetCString(), dst.GetCString(), error.GetError(),
+ error.AsCString());
return error;
}
Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
Status error = m_gdb_client.Unlink(file_spec);
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
- file_spec.GetCString(), error.GetError(), error.AsCString());
+ LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
+ file_spec.GetCString(), error.GetError(), error.AsCString());
return error;
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index c774daa8ab73..13edcbab9f59 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -113,7 +113,7 @@ public:
Status SetFilePermissions(const FileSpec &file_spec,
uint32_t file_permissions) override;
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
uint32_t mode, Status &error) override;
bool CloseFile(lldb::user_id_t fd, Status &error) override;
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index 3ec410fe7d76..f70ef97a2bc5 100644
--- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -254,9 +254,8 @@ CreatePosixSpawnFileAction(const FileAction &action,
case FileAction::eFileActionNone:
default:
- if (log)
- log->Printf("%s(): unsupported file action %u", __FUNCTION__,
- action.GetAction());
+ LLDB_LOGF(log, "%s(): unsupported file action %u", __FUNCTION__,
+ action.GetAction());
break;
}
@@ -288,8 +287,7 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
int error_code;
if ((error_code = ::posix_spawnattr_init(&attr)) != 0) {
- if (log)
- log->Printf("::posix_spawnattr_init(&attr) failed");
+ LLDB_LOGF(log, "::posix_spawnattr_init(&attr) failed");
error.SetError(error_code, eErrorTypePOSIX);
return error;
}
@@ -378,10 +376,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
error = CreatePosixSpawnFileAction(*action, &file_actions);
if (!error.Success()) {
- if (log)
- log->Printf("%s(): error converting FileAction to posix_spawn "
- "file action: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "%s(): error converting FileAction to posix_spawn "
+ "file action: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -416,10 +414,10 @@ static Status PosixSpawnChildForPTraceDebugging(const char *path,
if (actual_cpu_type) {
*actual_cpu_type = GetCPUTypeForLocalProcess(*pid);
- if (log)
- log->Printf("%s(): cpu type for launched process pid=%i: "
- "cpu_type=0x%8.8x",
- __FUNCTION__, *pid, *actual_cpu_type);
+ LLDB_LOGF(log,
+ "%s(): cpu type for launched process pid=%i: "
+ "cpu_type=0x%8.8x",
+ __FUNCTION__, *pid, *actual_cpu_type);
}
return error;
@@ -477,23 +475,21 @@ Status LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
char resolved_path[PATH_MAX];
resolved_path[0] = '\0';
- if (log)
- log->Printf("%s(): attempting to resolve given binary path: \"%s\"",
- __FUNCTION__, given_path);
+ 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))) {
- if (log)
- log->Printf("%s(): failed to resolve binary path, using "
- "what was given verbatim and hoping for the best",
- __FUNCTION__);
+ 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 {
- if (log)
- log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
- resolved_path);
+ LLDB_LOGF(log, "%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
+ resolved_path);
}
char launch_err_str[PATH_MAX];
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
index 70ad6736a748..073ad64b300c 100644
--- a/source/Plugins/Process/Darwin/MachException.cpp
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -67,10 +67,11 @@ extern "C" kern_return_t catch_mach_exception_raise_state(
// TODO change to LIBLLDB_LOG_EXCEPTION
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%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);
+ 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;
}
@@ -83,13 +84,14 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity(
thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%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));
+ 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;
@@ -102,13 +104,14 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
mach_msg_type_number_t exc_data_count) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log) {
- log->Printf("::%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));
+ 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) {
@@ -187,15 +190,16 @@ Status MachException::Message::Receive(mach_port_t port,
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
- log->Printf("::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);
+ 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 =
@@ -213,15 +217,16 @@ Status MachException::Message::Receive(mach_port_t port,
// Dump any errors we get
if (error.Fail() && log) {
- log->Printf("::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());
+ 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;
}
@@ -264,10 +269,10 @@ bool MachException::Message::CatchExceptionRaise(task_t task) {
} else {
Log *log(
GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::Message::%s(): mach_exc_server "
- "returned zero...",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "MachException::Message::%s(): mach_exc_server "
+ "returned zero...",
+ __FUNCTION__);
}
g_message = NULL;
return success;
@@ -293,10 +298,10 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
auto mach_err = ::pid_for_task(state.task_port, &state_pid);
if (mach_err) {
error.SetError(mach_err, eErrorTypeMachKernel);
- if (log)
- log->Printf("MachException::Message::%s(): pid_for_task() "
- "failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "MachException::Message::%s(): pid_for_task() "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -309,25 +314,25 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
error.SetError(errno, eErrorTypePOSIX);
if (!error.Success()) {
- if (log)
- log->Printf("::ptrace(request = PT_THUPDATE, pid = "
- "0x%4.4x, tid = 0x%4.4x, signal = %i)",
- state_pid, state.thread_port, soft_signal);
+ 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;
}
}
}
- if (log)
- log->Printf("::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);
+ 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,
@@ -342,12 +347,13 @@ Status MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
log->PutCString("::mach_msg() - send interrupted");
// TODO: keep retrying to reply???
} else if (state.task_port == inferior_task) {
- log->Printf("mach_msg(): returned an error when replying "
- "to a mach exception: error = %u (%s)",
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "mach_msg(): returned an error when replying "
+ "to a mach exception: error = %u (%s)",
+ error.GetError(), error.AsCString());
} else {
- log->Printf("::mach_msg() - failed (child of task): %u (%s)",
- error.GetError(), error.AsCString());
+ LLDB_LOGF(log, "::mach_msg() - failed (child of task): %u (%s)",
+ error.GetError(), error.AsCString());
}
}
@@ -377,9 +383,8 @@ Status MachException::PortInfo::Save(task_t task) {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
- task);
+ 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
@@ -394,13 +399,15 @@ Status MachException::PortInfo::Save(task_t task) {
if (log) {
if (error.Success()) {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors)",
- task, mask, count);
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors)",
+ task, mask, count);
} else {
- log->Printf("::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());
+ 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());
}
}
@@ -413,15 +420,17 @@ Status MachException::PortInfo::Save(task_t task) {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success()) {
- log->Printf("::task_get_exception_ports(task = 0x%4.4x, "
- "mask = 0x%x, maskCnt => %u, ports, behaviors, "
- "flavors)",
- task, mask, count);
+ LLDB_LOGF(log,
+ "::task_get_exception_ports(task = 0x%4.4x, "
+ "mask = 0x%x, maskCnt => %u, ports, behaviors, "
+ "flavors)",
+ task, mask, count);
} else {
- log->Printf("::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());
+ 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());
}
}
}
@@ -437,8 +446,7 @@ Status MachException::PortInfo::Restore(task_t task) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("MachException::PortInfo::Restore(task = 0x%4.4x)", task);
+ LLDB_LOGF(log, "MachException::PortInfo::Restore(task = 0x%4.4x)", task);
uint32_t i = 0;
if (count > 0) {
@@ -449,17 +457,19 @@ Status MachException::PortInfo::Restore(task_t task) {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success()) {
- log->Printf("::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]);
+ 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 {
- log->Printf("::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());
+ 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());
}
}
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
index fe7de27e0ee6..18dbdda9a33b 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -75,19 +75,19 @@ Status NativeProcessProtocol::Launch(
// Handle launch failure.
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() failed to launch process: "
- "%s",
- __FUNCTION__, error.AsCString());
+ 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) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
- "pid was returned! Aborting.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() launch succeeded but no "
+ "pid was returned! Aborting.",
+ __FUNCTION__);
return error;
}
@@ -104,10 +104,10 @@ Status NativeProcessProtocol::Launch(
// NativeProcessDarwin instance.
error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
- " the launching of the process: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s() aborting, failed to finalize"
+ " the launching of the process: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -120,9 +120,8 @@ Status NativeProcessProtocol::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
- pid);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
// Retrieve the architecture for the running process.
ArchSpec process_arch;
@@ -173,10 +172,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
error = StartExceptionThread();
if (!error.Success()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failure starting the "
- "mach exception port monitor thread: %s",
- __FUNCTION__, error.AsCString());
+ 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,
@@ -195,33 +194,31 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
if (err == 0) {
// m_flags |= eMachProcessFlagsAttached;
- if (log)
- log->Printf("NativeProcessDarwin::%s(): successfully spawned "
- "process with pid %" PRIu64,
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): successfully spawned "
+ "process with pid %" PRIu64,
+ __FUNCTION__, m_pid);
} else {
error.SetErrorToErrno();
SetState(eStateExited);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): error: failed to "
- "attach to spawned pid %" PRIu64 " (error=%d (%s))",
- __FUNCTION__, m_pid, (int)error.GetError(),
- error.AsCString());
+ 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;
}
}
- if (log)
- log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
- __FUNCTION__, m_pid);
+ 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()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
- "thread: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to start waitpid() "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
kill(SIGKILL, static_cast<::pid_t>(m_pid));
return error;
}
@@ -230,10 +227,10 @@ Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
// 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.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): could not get task port "
- "for process, sending SIGKILL and exiting: %s",
- __FUNCTION__, error.AsCString());
+ 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;
}
@@ -278,18 +275,17 @@ void NativeProcessDarwin::ExceptionMessageReceived(
// the exception to our internal exception stack
m_exception_messages.push_back(message);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
- __FUNCTION__, m_exception_messages.size());
+ 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) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
- "thread, mandatory process arg was null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot run mach exception "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
return nullptr;
}
@@ -299,9 +295,8 @@ void *NativeProcessDarwin::ExceptionThread(void *arg) {
void *NativeProcessDarwin::DoExceptionThread() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
- if (log)
- log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
- __FUNCTION__, this);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(arg=%p) starting thread...",
+ __FUNCTION__, this);
pthread_setname_np("exception monitoring thread");
@@ -344,20 +339,20 @@ void *NativeProcessDarwin::DoExceptionThread() {
if (process->ProcessUsingSpringBoard()) {
// Request a renewal for every 60 seconds if we attached using SpringBoard.
watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
- if (log)
- log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
- "=> %p",
- pid, watchdog.get());
+ LLDB_LOGF(log,
+ "::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
+ "=> %p",
+ pid, watchdog.get());
if (watchdog.get()) {
::SBSWatchdogAssertionRenew(watchdog.get());
CFTimeInterval watchdogRenewalInterval =
::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
- if (log)
- log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
- "%g seconds",
- watchdog.get(), watchdogRenewalInterval);
+ 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) {
@@ -425,11 +420,11 @@ void *NativeProcessDarwin::DoExceptionThread() {
// If we have no task port we should exit this thread, as it implies
// the inferior went down.
if (!IsExceptionPortValid()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior "
- "exception port is no longer valid, "
- "canceling exception thread...",
- __FUNCTION__);
+ 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;
}
@@ -437,19 +432,19 @@ void *NativeProcessDarwin::DoExceptionThread() {
// Make sure the inferior task is still valid.
if (IsTaskValid()) {
// Task is still ok.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): interrupted, but "
- "the inferior task iss till valid, "
- "continuing...",
- __FUNCTION__);
+ 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.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior task "
- "has exited, and so will we...",
- __FUNCTION__);
+ 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;
@@ -471,18 +466,18 @@ void *NativeProcessDarwin::DoExceptionThread() {
// our task is still valid.
if (IsTaskValid(task)) {
// Task is still ok.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): got a timeout, "
- "continuing...",
- __FUNCTION__);
+ 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.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): the inferior "
- "task has exited, and so will we...",
- __FUNCTION__);
+ 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;
@@ -493,18 +488,17 @@ void *NativeProcessDarwin::DoExceptionThread() {
if (watchdog.get()) {
watchdog_elapsed += periodic_timeout;
if (watchdog_elapsed >= watchdog_timeout) {
- if (log)
- log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
+ LLDB_LOGF(log, "SBSWatchdogAssertionRenew(%p)", watchdog.get());
::SBSWatchdogAssertionRenew(watchdog.get());
watchdog_elapsed = 0;
}
}
#endif
} else {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): continuing after "
- "receiving an unexpected error: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): continuing after "
+ "receiving an unexpected error: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
// TODO: notify of error?
}
}
@@ -523,17 +517,15 @@ void *NativeProcessDarwin::DoExceptionThread() {
}
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
- if (log)
- log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
- this);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
+ this);
return nullptr;
}
Status NativeProcessDarwin::StartExceptionThread() {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
// Make sure we've looked up the inferior port.
TaskPortForProcessID(error);
@@ -554,11 +546,11 @@ Status NativeProcessDarwin::StartExceptionThread() {
&m_exception_port);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("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());
+ 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;
}
@@ -567,23 +559,23 @@ Status NativeProcessDarwin::StartExceptionThread() {
task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("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());
+ 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)) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
- "failed, cannot install exception handler: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
+ "failed, cannot install exception handler: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -593,14 +585,14 @@ Status NativeProcessDarwin::StartExceptionThread() {
EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::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());
+ 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;
}
@@ -609,10 +601,10 @@ Status NativeProcessDarwin::StartExceptionThread() {
::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
error.SetError(pthread_err, eErrorTypePOSIX);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
- "exception-handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create Mach "
+ "exception-handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
}
return error;
@@ -677,10 +669,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
- if (log)
- log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
- "messages.",
- __FUNCTION__, m_exception_messages.size());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): processing %lu exception "
+ "messages.",
+ __FUNCTION__, m_exception_messages.size());
if (m_exception_messages.empty()) {
// Not particularly useful...
@@ -733,18 +725,18 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
const bool force_update = true;
const task_t new_task = TaskPortForProcessID(error, force_update);
if (old_task != new_task) {
- if (log)
- log->Printf("exec: inferior task port changed "
- "from 0x%4.4x to 0x%4.4x",
- 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 {
- if (log)
- log->Printf("NativeProcessDarwin::%s() warning: "
- "failed to read all_image_infos."
- "infoArrayCount from 0x%8.8llx",
- __FUNCTION__, info_array_count_addr);
+ 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)) {
@@ -756,10 +748,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
if (m_did_exec) {
cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
if (m_cpu_type != process_cpu_type) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): arch changed from "
- "0x%8.8x to 0x%8.8x",
- __FUNCTION__, 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);
@@ -772,10 +764,10 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
if (m_sent_interrupt_signo != 0) {
if (received_interrupt) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): process "
- "successfully interrupted with signal %i",
- __FUNCTION__, m_sent_interrupt_signo);
+ 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;
@@ -792,19 +784,19 @@ task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
// Only auto_resume if we stopped with _only_ the interrupt signal.
if (num_task_exceptions == 1) {
auto_resume = true;
- if (log)
- log->Printf("NativeProcessDarwin::%s(): auto "
- "resuming due to unhandled interrupt "
- "signal %i",
- __FUNCTION__, m_auto_resume_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): auto "
+ "resuming due to unhandled interrupt "
+ "signal %i",
+ __FUNCTION__, m_auto_resume_signo);
}
m_auto_resume_signo = 0;
}
} else {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): didn't get signal "
- "%i after MachProcess::Interrupt()",
- __FUNCTION__, m_sent_interrupt_signo);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): didn't get signal "
+ "%i after MachProcess::Interrupt()",
+ __FUNCTION__, m_sent_interrupt_signo);
}
}
}
@@ -878,10 +870,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
const bool child_inherits = false;
error = m_waitpid_pipe.CreateNew(child_inherits);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
- "communication pipe: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create waitpid "
+ "communication pipe: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -889,8 +881,8 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
// TODO make PipePOSIX derive from IOObject. This is goofy here.
const bool transfer_ownership = false;
- auto io_sp = IOObjectSP(
- new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
+ 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);
@@ -899,10 +891,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
error.SetError(pthread_err, eErrorTypePOSIX);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
- "handling thread: %u (%s)",
- __FUNCTION__, error.GetError(), error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to create waitpid "
+ "handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
return error;
}
@@ -912,10 +904,10 @@ Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
void *NativeProcessDarwin::WaitpidThread(void *arg) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (!arg) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
- "thread, mandatory process arg was null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot run waitpid "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
return nullptr;
}
@@ -938,10 +930,10 @@ void *NativeProcessDarwin::DoWaitpidThread() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (m_pid == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
- "not set, cannot waitpid on it",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): inferior process ID is "
+ "not set, cannot waitpid on it",
+ __FUNCTION__);
return nullptr;
}
@@ -962,41 +954,41 @@ void *NativeProcessDarwin::DoWaitpidThread() {
if (error.Fail()) {
if (error.GetError() == EINTR) {
// This is okay, we can keep going.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) interrupted, continuing",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) interrupted, continuing",
+ __FUNCTION__, m_pid);
continue;
}
// This error is not okay, abort.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) aborting due to error: %u (%s)",
- __FUNCTION__, m_pid, error.GetError(), error.AsCString());
+ 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.
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ", &status, 0) => %i, status = %i",
- __FUNCTION__, m_pid, child_pid, status);
+ 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)) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
- ") received a stop, continuing waitpid() loop",
- __FUNCTION__, m_pid);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ") received a stop, continuing waitpid() loop",
+ __FUNCTION__, m_pid);
continue;
} else // if (WIFEXITED(status) || WIFSIGNALED(status))
{
- if (log)
- log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
- "waitpid thread is setting exit status for pid = "
- "%i to %i",
- __FUNCTION__, m_pid, child_pid, 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;
@@ -1005,12 +997,11 @@ void *NativeProcessDarwin::DoWaitpidThread() {
// 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.
- if (log)
- log->Printf(
- "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);
+ 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;
@@ -1026,11 +1017,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
// Send the pid.
error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
if (error.Fail() || (bytes_written < sizeof(pid))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to write "
- "waitpid exiting pid to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
+ 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;
}
@@ -1038,11 +1029,11 @@ Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
bytes_written = 0;
error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
if (error.Fail() || (bytes_written < sizeof(status))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to write "
- "waitpid exit result to the pipe. Client will not "
- "hear about inferior exit status!",
- __FUNCTION__);
+ 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;
}
@@ -1058,11 +1049,11 @@ Status NativeProcessDarwin::HandleWaitpidResult() {
size_t bytes_read = 0;
error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
if (error.Fail() || (bytes_read < sizeof(pid))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to read "
- "waitpid exiting pid from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
+ 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;
}
@@ -1071,21 +1062,21 @@ Status NativeProcessDarwin::HandleWaitpidResult() {
int status = -1;
error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
if (error.Fail() || (bytes_read < sizeof(status))) {
- if (log)
- log->Printf("NativeProcessDarwin::%s() - failed to read "
- "waitpid exit status from the pipe. Will notify "
- "as if parent process died with exit status -1.",
- __FUNCTION__);
+ 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.
- if (log)
- log->Printf("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);
+ 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;
@@ -1096,10 +1087,10 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
if ((m_task == TASK_NULL) || force) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (m_pid == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): cannot get task due "
- "to invalid pid",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): cannot get task due "
+ "to invalid pid",
+ __FUNCTION__);
return TASK_NULL;
}
@@ -1115,19 +1106,21 @@ task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
// Succeeded. Save and return it.
error.Clear();
m_task = task;
- log->Printf("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);
+ 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) {
- log->Printf("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());
+ 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());
}
}
@@ -1156,20 +1149,21 @@ Status NativeProcessDarwin::PrivateResume() {
if (log) {
if (m_auto_resume_signo)
- log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
- "unhandled interrupt signal %i)...",
- __FUNCTION__, m_task, 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
- log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
- __FUNCTION__, m_task);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): task 0x%x resuming...",
+ __FUNCTION__, m_task);
}
error = ReplyToAllExceptions();
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
- "reply to exceptions: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): aborting, failed to "
+ "reply to exceptions: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
// bool stepOverBreakInstruction = step;
@@ -1196,9 +1190,8 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
TaskPortForProcessID(error);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
- __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s(): no task port, aborting",
+ __FUNCTION__);
return error;
}
@@ -1211,9 +1204,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
size_t index = 0;
for (auto &message : m_exception_messages) {
if (log) {
- log->Printf("NativeProcessDarwin::%s(): replying to exception "
- "%zu...",
- __FUNCTION__, index++);
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): replying to exception "
+ "%zu...",
+ __FUNCTION__, index++);
}
int thread_reply_signal = 0;
@@ -1234,9 +1228,10 @@ Status NativeProcessDarwin::ReplyToAllExceptions() {
if (error.Fail() && log) {
// We log any error here, but we don't stop the exception response
// handling.
- log->Printf("NativeProcessDarwin::%s(): failed to reply to "
- "exception: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to reply to "
+ "exception: %s",
+ __FUNCTION__, error.AsCString());
error.Clear();
}
}
@@ -1253,10 +1248,10 @@ Status NativeProcessDarwin::ResumeTask() {
TaskPortForProcessID(error);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to get task port "
- "for process when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
+ 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) {
@@ -1265,20 +1260,20 @@ Status NativeProcessDarwin::ResumeTask() {
return error;
}
- if (log)
- log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
- "0x%4.4x",
- __FUNCTION__, m_task);
+ 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()) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): failed to get task "
- "BasicInfo when attempting to resume: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): failed to get task "
+ "BasicInfo when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -1289,16 +1284,16 @@ Status NativeProcessDarwin::ResumeTask() {
error.SetError(mach_err, eErrorTypeMachKernel);
if (log) {
if (error.Success())
- log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
+ LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x): success", m_task);
else
- log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
- error.AsCString());
+ LLDB_LOGF(log, "::task_resume(target_task = 0x%4.4x) error: %s", m_task,
+ error.AsCString());
}
} else {
- if (log)
- log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
- "already running",
- m_task);
+ LLDB_LOGF(log,
+ "::task_resume(target_task = 0x%4.4x): ignored, "
+ "already running",
+ m_task);
}
return error;
@@ -1353,11 +1348,11 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task,
auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
error.SetError(err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::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());
+ 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;
}
@@ -1368,11 +1363,12 @@ NativeProcessDarwin::GetTaskBasicInfo(task_t task,
(float)info->user_time.microseconds / 1000000.0f;
float system = (float)info->user_time.seconds +
(float)info->user_time.microseconds / 1000000.0f;
- verbose_log->Printf("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);
+ 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;
}
@@ -1383,16 +1379,15 @@ Status NativeProcessDarwin::SuspendTask() {
if (m_task == TASK_NULL) {
error.SetErrorString("task port is null, cannot suspend task");
- if (log)
- log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ 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)
- log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);
+ LLDB_LOGF(log, "::task_suspend(target_task = 0x%4.4x)", m_task);
return error;
}
@@ -1401,8 +1396,7 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
Status error;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "NativeProcessDarwin::%s() called", __FUNCTION__);
if (CanResume()) {
m_thread_actions = resume_actions;
@@ -1412,10 +1406,10 @@ Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
auto state = GetState();
if (state == eStateRunning) {
- if (log)
- log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
- "running, ignoring...",
- __FUNCTION__, TaskPortForProcessID(error));
+ LLDB_LOGF(log,
+ "NativeProcessDarwin::%s(): task 0x%x is already "
+ "running, ignoring...",
+ __FUNCTION__, TaskPortForProcessID(error));
return error;
}
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
index 89de92a6df4d..1faa5b219cbc 100644
--- a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
@@ -301,10 +301,10 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
- if (log)
- log->Printf("NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
- "%u) process stop count = %u",
- __FUNCTION__, process.GetID(), update, process.GetStopID());
+ 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
@@ -346,11 +346,11 @@ uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
error.SetError(mach_err, eErrorTypeMachKernel);
if (error.Fail()) {
- if (log)
- log->Printf("::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());
+ 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;
}
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 749835531279..0a49f96f54a1 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -288,9 +288,8 @@ void FreeBSDThread::DidStop() {
void FreeBSDThread::WillResume(lldb::StateType resume_state) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("tid %lu resume_state = %s", GetID(),
- lldb_private::StateAsCString(resume_state));
+ LLDB_LOGF(log, "tid %lu resume_state = %s", GetID(),
+ lldb_private::StateAsCString(resume_state));
ProcessSP process_sp(GetProcess());
ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
int signo = GetResumeSignal();
@@ -322,9 +321,8 @@ bool FreeBSDThread::Resume() {
bool status;
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
- StateAsCString(resume_state));
+ LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
+ StateAsCString(resume_state));
switch (resume_state) {
default:
@@ -352,9 +350,8 @@ bool FreeBSDThread::Resume() {
void FreeBSDThread::Notify(const ProcessMessage &message) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
- __FUNCTION__, message.PrintKind(), GetID());
+ LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
+ __FUNCTION__, message.PrintKind(), GetID());
switch (message.GetKind()) {
default:
@@ -457,8 +454,7 @@ void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
// corresponding to our current PC.
assert(GetRegisterContext());
lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
@@ -490,10 +486,9 @@ void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
lldb::addr_t halt_addr = message.GetHWAddress();
- if (log)
- log->Printf(
- "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
- __FUNCTION__, halt_addr);
+ LLDB_LOGF(log,
+ "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
+ __FUNCTION__, halt_addr);
POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx) {
@@ -527,8 +522,7 @@ void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
// Try to resolve the breakpoint object corresponding to the current PC.
assert(GetRegisterContext());
lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(
GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 770794569f72..32e3320150f8 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -154,9 +154,8 @@ Status ProcessFreeBSD::DoResume() {
do_step = true;
}
- if (log)
- log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
- do_step ? "step" : "continue");
+ LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(),
+ do_step ? "step" : "continue");
if (do_step && !software_single_step)
m_monitor->SingleStep(GetID(), m_resume_signo);
else
@@ -168,9 +167,8 @@ Status ProcessFreeBSD::DoResume() {
bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (log)
- log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
- GetID());
+ LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
std::vector<lldb::pid_t> tds;
if (!GetMonitor().GetCurrentThreadIDs(tds)) {
@@ -183,20 +181,18 @@ bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
if (!thread_sp) {
thread_sp.reset(new FreeBSDThread(*this, tid));
- if (log)
- log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__,
+ tid);
} else {
- if (log)
- log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
- tid);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
+ tid);
}
new_thread_list.AddThread(thread_sp);
}
for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
if (old_thread_sp) {
- if (log)
- log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__);
}
}
@@ -698,14 +694,13 @@ Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
return error;
}
@@ -753,14 +748,13 @@ Status ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (!wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
+ watchID, (uint64_t)addr);
// This is needed (for now) to keep watchpoints disabled correctly
wp->SetEnabled(false, notify);
return error;
@@ -970,8 +964,9 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
if (log) {
- log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+ LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
+ addr);
}
// Validate the address.
@@ -982,11 +977,10 @@ Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
Breakpoint *const sw_step_break =
m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
- sw_step_break->SetBreakpointKind("software-signle-step");
+ sw_step_break->SetBreakpointKind("software-single-step");
- if (log)
- log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
- __FUNCTION__, addr);
+ LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
+ __FUNCTION__, addr);
m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
return Status();
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 4b9225db5e39..ff3fb0a75e2d 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -37,9 +37,6 @@
using namespace lldb;
using namespace lldb_private;
-// We disable the tracing of ptrace calls for integration builds to avoid the
-// additional indirection and checks.
-#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.
const char *Get_PT_IO_OP(int op) {
@@ -66,13 +63,14 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
if (log) {
- log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
- reqName, pid, addr, data, file, line);
+ LLDB_LOGF(log,
+ "ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
+ reqName, pid, addr, data, file, line);
if (req == PT_IO) {
struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
- log->Printf("PT_IO: op=%s offs=%zx size=%zu", Get_PT_IO_OP(pi->piod_op),
- (size_t)pi->piod_offs, pi->piod_len);
+ LLDB_LOGF(log, "PT_IO: op=%s offs=%zx size=%zu",
+ Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
}
}
@@ -101,7 +99,7 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
default:
str = "<unknown>";
}
- log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ LLDB_LOGF(log, "ptrace() failed; errno=%d (%s)", errno, str);
}
if (log) {
@@ -109,15 +107,15 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
if (req == PT_GETREGS) {
struct reg *r = (struct reg *)addr;
- log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
- r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
+ LLDB_LOGF(log, "PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
+ r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
}
if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
struct dbreg *r = (struct dbreg *)addr;
char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
for (int i = 0; i <= 7; i++)
- log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
+ LLDB_LOGF(log, "PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
}
#endif
}
@@ -136,9 +134,6 @@ extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
#define PTRACE(req, pid, addr, data) \
PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
-#else
-PtraceWrapper((req), (pid), (addr), (data))
-#endif
// Static implementations of ProcessMonitor::ReadMemory and
// ProcessMonitor::WriteMemory. This enables mutual recursion between these
@@ -708,7 +703,7 @@ ProcessMonitor::ProcessMonitor(
const lldb_private::ProcessLaunchInfo & /* launch_info */,
lldb_private::Status &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
+ m_operation_thread(), m_monitor_thread(), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
using namespace std::placeholders;
std::unique_ptr<LaunchArgs> args(
@@ -735,20 +730,22 @@ ProcessMonitor::ProcessMonitor(
}
// Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
+ llvm::Expected<lldb_private::HostThread> monitor_thread =
+ Host::StartMonitoringChildProcess(
std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
GetPID(), true);
- if (!m_monitor_thread->IsJoinable()) {
+ if (!monitor_thread || !monitor_thread->IsJoinable()) {
error.SetErrorToGenericError();
error.SetErrorString("Process launch failed.");
return;
}
+ m_monitor_thread = *monitor_thread;
}
ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
lldb_private::Status &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(nullptr), m_monitor_thread(nullptr), m_pid(pid), m_terminal_fd(-1), m_operation(0) {
+ m_operation_thread(), m_monitor_thread(), m_pid(pid), m_terminal_fd(-1), m_operation(0) {
using namespace std::placeholders;
sem_init(&m_operation_pending, 0, 0);
@@ -773,14 +770,16 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
}
// Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
+ llvm::Expected<lldb_private::HostThread> monitor_thread =
+ Host::StartMonitoringChildProcess(
std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
GetPID(), true);
- if (!m_monitor_thread->IsJoinable()) {
+ if (!monitor_thread || !monitor_thread->IsJoinable()) {
error.SetErrorToGenericError();
error.SetErrorString("Process attach failed.");
return;
}
+ m_monitor_thread = *monitor_thread;
}
ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
@@ -789,13 +788,15 @@ ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Status &error) {
static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread->IsJoinable())
+ if (m_operation_thread && m_operation_thread->IsJoinable())
return;
- m_operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
- if (!m_operation_thread)
- error = m_operation_thread.takeError();
+ llvm::Expected<lldb_private::HostThread> operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
+ if (operation_thread)
+ m_operation_thread = *operation_thread;
+ else
+ error = operation_thread.takeError();
}
void *ProcessMonitor::LaunchOpThread(void *arg) {
@@ -957,14 +958,15 @@ void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
lldb_private::Status &error) {
static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread->IsJoinable())
+ if (m_operation_thread && m_operation_thread->IsJoinable())
return;
- m_operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
-
- if (!m_operation_thread)
- error = m_operation_thread.takeError();
+ llvm::Expected<lldb_private::HostThread> operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
+ if (operation_thread)
+ m_operation_thread = *operation_thread;
+ else
+ error = operation_thread.takeError();
}
void *ProcessMonitor::AttachOpThread(void *arg) {
@@ -1037,9 +1039,8 @@ bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
if (exited) {
- if (log)
- log->Printf("ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log, "ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
+ __FUNCTION__, pid);
message = ProcessMessage::Exit(pid, status);
process->SendMessage(message);
return pid == process->GetID();
@@ -1087,10 +1088,10 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
unsigned long data = 0;
if (!monitor->GetEventMessage(tid, &data))
data = -1;
- if (log)
- log->Printf("ProcessMonitor::%s() received exit? event, data = %lx, tid "
- "= %" PRIu64,
- __FUNCTION__, data, tid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received exit? event, data = %lx, tid "
+ "= %" PRIu64,
+ __FUNCTION__, data, tid);
message = ProcessMessage::Limbo(tid, (data >> 8));
break;
}
@@ -1101,26 +1102,25 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
// Map TRAP_CAP to a trace trap in the absense of a more specific handler.
case TRAP_CAP:
#endif
- if (log)
- log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64
- " : si_code = %d",
- __FUNCTION__, tid, info->si_code);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received trace event, tid = %" PRIu64
+ " : si_code = %d",
+ __FUNCTION__, tid, info->si_code);
message = ProcessMessage::Trace(tid);
break;
case SI_KERNEL:
case TRAP_BRKPT:
if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) {
- if (log)
- log->Printf("ProcessMonitor::%s() received sw single step breakpoint "
- "event, tid = %" PRIu64,
- __FUNCTION__, tid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received sw single step breakpoint "
+ "event, tid = %" PRIu64,
+ __FUNCTION__, tid);
message = ProcessMessage::Trace(tid);
} else {
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
- __FUNCTION__, tid);
+ LLDB_LOGF(
+ log, "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
+ __FUNCTION__, tid);
message = ProcessMessage::Break(tid);
}
break;
@@ -1146,22 +1146,19 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
//
// Similarly, ACK signals generated by this monitor.
if (info->si_code == SI_USER) {
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
- __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
- "SI_USER", info->si_pid);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+ __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
+ "SI_USER", info->si_pid);
if (info->si_pid == getpid())
return ProcessMessage::SignalDelivered(tid, signo);
else
return ProcessMessage::Signal(tid, signo);
}
- if (log)
- log->Printf(
- "ProcessMonitor::%s() received signal %s", __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
+ LLDB_LOGF(log, "ProcessMonitor::%s() received signal %s", __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
switch (signo) {
case SIGSEGV:
@@ -1313,14 +1310,14 @@ bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
m_process->GetUnixSignals()->GetSignalAsCString(signo);
if (signame == nullptr)
signame = "<none>";
- log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
- __FUNCTION__, GetPID(), signame);
+ LLDB_LOGF(log,
+ "ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
+ __FUNCTION__, GetPID(), signame);
}
ResumeOperation op(signo, result);
DoOperation(&op);
- if (log)
- log->Printf("ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
- result ? "true" : "false");
+ LLDB_LOGF(log, "ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
+ result ? "true" : "false");
return result;
}
@@ -1384,7 +1381,7 @@ bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
}
void ProcessMonitor::StopMonitoringChildProcess() {
- if (m_monitor_thread->IsJoinable()) {
+ if (m_monitor_thread && m_monitor_thread->IsJoinable()) {
m_monitor_thread->Cancel();
m_monitor_thread->Join(nullptr);
m_monitor_thread->Reset();
@@ -1422,10 +1419,9 @@ void ProcessMonitor::StopMonitor() {
bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
void ProcessMonitor::StopOpThread() {
- if (!m_operation_thread->IsJoinable())
- return;
-
- m_operation_thread->Cancel();
- m_operation_thread->Join(nullptr);
- m_operation_thread->Reset();
+ if (m_operation_thread && m_operation_thread->IsJoinable()) {
+ m_operation_thread->Cancel();
+ m_operation_thread->Join(nullptr);
+ m_operation_thread->Reset();
+ }
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 2adcc449c5c6..c5edfc0be95a 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -183,8 +183,8 @@ public:
private:
ProcessFreeBSD *m_process;
- llvm::Expected<lldb_private::HostThread> m_operation_thread;
- llvm::Expected<lldb_private::HostThread> m_monitor_thread;
+ llvm::Optional<lldb_private::HostThread> m_operation_thread;
+ llvm::Optional<lldb_private::HostThread> m_monitor_thread;
lldb::pid_t m_pid;
int m_terminal_fd;
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 32d20d2b1215..8b6f9fbc33c3 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -140,7 +140,7 @@ NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
NativeDelegate &delegate,
const ArchSpec &arch,
MainLoop &mainloop)
- : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+ : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
if (m_terminal_fd != -1) {
Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
assert(status.Success());
@@ -195,6 +195,7 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
SIGSTOP, &info.psi_siginfo);
}
}
+ SetState(StateType::eStateStopped, true);
}
}
@@ -339,12 +340,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
}
Status error;
+ int signal =
+ action->signal != LLDB_INVALID_SIGNAL_NUMBER ? action->signal : 0;
switch (action->state) {
case eStateRunning: {
// Run the thread, possibly feeding it the signal.
error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
- action->signal);
+ signal);
if (!error.Success())
return error;
for (const auto &thread : m_threads)
@@ -355,7 +358,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
case eStateStepping:
// Run the thread, possibly feeding it the signal.
error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
- action->signal);
+ signal);
if (!error.Success())
return error;
for (const auto &thread : m_threads)
@@ -658,7 +661,7 @@ NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id));
+ m_threads.push_back(std::make_unique<NativeThreadNetBSD>(*this, thread_id));
return static_cast<NativeThreadNetBSD &>(*m_threads.back());
}
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index e85ca3b7a925..4e7f0a1c13ab 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -9,12 +9,12 @@
#ifndef liblldb_NativeProcessNetBSD_H_
#define liblldb_NativeProcessNetBSD_H_
+#include "Plugins/Process/POSIX/NativeProcessELF.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "NativeThreadNetBSD.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
namespace process_netbsd {
@@ -25,7 +25,7 @@ namespace process_netbsd {
/// for debugging.
///
/// Changes in the inferior process state are broadcasted.
-class NativeProcessNetBSD : public NativeProcessProtocol {
+class NativeProcessNetBSD : public NativeProcessELF {
public:
class Factory : public NativeProcessProtocol::Factory {
public:
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index a7cd637bf826..6cc2810fa235 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -906,8 +906,8 @@ uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
return wp_index;
}
if (error.Fail() && log) {
- log->Printf("NativeRegisterContextNetBSD_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
}
}
return LLDB_INVALID_INDEX32;
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
index 70c2687e3b8c..9678e48436e7 100644
--- a/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -229,11 +229,6 @@ std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
}
const char *CrashReasonAsString(CrashReason reason) {
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
const char *str = nullptr;
switch (reason) {
@@ -315,8 +310,6 @@ const char *CrashReasonAsString(CrashReason reason) {
str = "eFloatSubscriptRange";
break;
}
-#endif
-
return str;
}
diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/source/Plugins/Process/POSIX/NativeProcessELF.cpp
index 559b16c8fd69..058dc5ae2338 100644
--- a/source/Plugins/Process/POSIX/NativeProcessELF.cpp
+++ b/source/Plugins/Process/POSIX/NativeProcessELF.cpp
@@ -21,7 +21,7 @@ NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) {
DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(),
buffer_or_error.get()->getBufferSize(),
GetByteOrder(), GetAddressByteSize());
- m_aux_vector = llvm::make_unique<AuxVector>(auxv_data);
+ m_aux_vector = std::make_unique<AuxVector>(auxv_data);
}
return m_aux_vector->GetAuxValue(type);
@@ -107,4 +107,72 @@ lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() {
return LLDB_INVALID_ADDRESS;
}
-} // namespace lldb_private \ No newline at end of file
+template <typename T>
+llvm::Expected<SVR4LibraryInfo>
+NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) {
+ ELFLinkMap<T> link_map;
+ size_t bytes_read;
+ auto error =
+ ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read);
+ if (!error.Success())
+ return error.ToError();
+
+ char name_buffer[PATH_MAX];
+ llvm::Expected<llvm::StringRef> string_or_error = ReadCStringFromMemory(
+ link_map.l_name, &name_buffer[0], sizeof(name_buffer), bytes_read);
+ if (!string_or_error)
+ return string_or_error.takeError();
+
+ SVR4LibraryInfo info;
+ info.name = string_or_error->str();
+ info.link_map = link_map_addr;
+ info.base_addr = link_map.l_addr;
+ info.ld_addr = link_map.l_ld;
+ info.next = link_map.l_next;
+
+ return info;
+}
+
+llvm::Expected<std::vector<SVR4LibraryInfo>>
+NativeProcessELF::GetLoadedSVR4Libraries() {
+ // Address of DT_DEBUG.d_ptr which points to r_debug
+ lldb::addr_t info_address = GetSharedLibraryInfoAddress();
+ if (info_address == LLDB_INVALID_ADDRESS)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid shared library info address");
+ // Address of r_debug
+ lldb::addr_t address = 0;
+ size_t bytes_read;
+ auto status =
+ ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid r_debug address");
+ // Read r_debug.r_map
+ lldb::addr_t link_map = 0;
+ status = ReadMemory(address + GetAddressByteSize(), &link_map,
+ GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid link_map address");
+
+ std::vector<SVR4LibraryInfo> library_list;
+ while (link_map) {
+ llvm::Expected<SVR4LibraryInfo> info =
+ GetAddressByteSize() == 8 ? ReadSVR4LibraryInfo<uint64_t>(link_map)
+ : ReadSVR4LibraryInfo<uint32_t>(link_map);
+ if (!info)
+ return info.takeError();
+ if (!info->name.empty() && info->base_addr != 0)
+ library_list.push_back(*info);
+ link_map = info->next;
+ }
+
+ return library_list;
+}
+
+} // namespace lldb_private
diff --git a/source/Plugins/Process/POSIX/NativeProcessELF.h b/source/Plugins/Process/POSIX/NativeProcessELF.h
index 84dc8d08a340..4fb513baebf0 100644
--- a/source/Plugins/Process/POSIX/NativeProcessELF.h
+++ b/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -37,6 +37,13 @@ protected:
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
lldb::addr_t GetELFImageInfoAddress();
+ llvm::Expected<std::vector<SVR4LibraryInfo>>
+ GetLoadedSVR4Libraries() override;
+
+ template <typename T>
+ llvm::Expected<SVR4LibraryInfo>
+ ReadSVR4LibraryInfo(lldb::addr_t link_map_addr);
+
std::unique_ptr<AuxVector> m_aux_vector;
llvm::Optional<lldb::addr_t> m_shared_library_info_addr;
};
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index aa8449131a68..66286dd3d9e3 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -15,11 +15,6 @@ const char *ProcessMessage::PrintCrashReason() const {
}
const char *ProcessMessage::PrintKind(Kind kind) {
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
const char *str = nullptr;
switch (kind) {
@@ -60,8 +55,6 @@ const char *ProcessMessage::PrintKind(Kind kind) {
str = "eExecMessage";
break;
}
-#endif
-
return str;
}
diff --git a/source/Plugins/Process/Utility/AuxVector.cpp b/source/Plugins/Process/Utility/AuxVector.cpp
index aab164ff93a6..25a1d0b5af06 100644
--- a/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/source/Plugins/Process/Utility/AuxVector.cpp
@@ -43,9 +43,9 @@ void AuxVector::DumpToLog(lldb_private::Log *log) const {
log->PutCString("AuxVector: ");
for (auto entry : m_auxv_entries) {
- log->Printf(" %s [%" PRIu64 "]: %" PRIx64,
- GetEntryName(static_cast<EntryType>(entry.first)), entry.first,
- entry.second);
+ LLDB_LOGF(log, " %s [%" PRIu64 "]: %" PRIx64,
+ GetEntryName(static_cast<EntryType>(entry.first)), entry.first,
+ entry.second);
}
}
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1afe4d920599..a86880af2260 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -137,76 +137,67 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
// ends at
static RegularExpression g_bitfield_regex(
llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
- RegularExpression::Match regex_match(3);
- if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
- llvm::StringRef reg_name_str;
- std::string msbit_str;
- std::string lsbit_str;
- if (regex_match.GetMatchAtIndex(slice_str, 1, reg_name_str) &&
- regex_match.GetMatchAtIndex(slice_str, 2, msbit_str) &&
- regex_match.GetMatchAtIndex(slice_str, 3, lsbit_str)) {
- const uint32_t msbit =
- StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit =
- StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
- if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
- if (msbit > lsbit) {
- const uint32_t msbyte = msbit / 8;
- const uint32_t lsbyte = lsbit / 8;
-
- ConstString containing_reg_name(reg_name_str);
-
- const RegisterInfo *containing_reg_info =
- GetRegisterInfo(containing_reg_name);
- if (containing_reg_info) {
- const uint32_t max_bit = containing_reg_info->byte_size * 8;
- if (msbit < max_bit && lsbit < max_bit) {
- m_invalidate_regs_map[containing_reg_info
- ->kinds[eRegisterKindLLDB]]
- .push_back(i);
- m_value_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[i].push_back(
- containing_reg_info->kinds[eRegisterKindLLDB]);
-
- if (byte_order == eByteOrderLittle) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + lsbyte;
- } else if (byte_order == eByteOrderBig) {
- success = true;
- reg_info.byte_offset =
- containing_reg_info->byte_offset + msbyte;
- } else {
- llvm_unreachable("Invalid byte order");
- }
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (g_bitfield_regex.Execute(slice_str, &matches)) {
+ std::string reg_name_str = matches[1].str();
+ std::string msbit_str = matches[2].str();
+ std::string lsbit_str = matches[3].str();
+ const uint32_t msbit =
+ StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit =
+ StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
+ if (msbit > lsbit) {
+ const uint32_t msbyte = msbit / 8;
+ const uint32_t lsbyte = lsbit / 8;
+
+ ConstString containing_reg_name(reg_name_str);
+
+ const RegisterInfo *containing_reg_info =
+ GetRegisterInfo(containing_reg_name);
+ if (containing_reg_info) {
+ const uint32_t max_bit = containing_reg_info->byte_size * 8;
+ if (msbit < max_bit && lsbit < max_bit) {
+ m_invalidate_regs_map[containing_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_value_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+
+ if (byte_order == eByteOrderLittle) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + lsbyte;
+ } else if (byte_order == eByteOrderBig) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + msbyte;
} else {
- if (msbit > max_bit)
- printf("error: msbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- msbit, max_bit);
- else
- printf("error: lsbit (%u) must be less than the bitsize "
- "of the register (%u)\n",
- lsbit, max_bit);
+ llvm_unreachable("Invalid byte order");
}
} else {
- printf("error: invalid concrete register \"%s\"\n",
- containing_reg_name.GetCString());
+ if (msbit > max_bit)
+ printf("error: msbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ msbit, max_bit);
+ else
+ printf("error: lsbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ lsbit, max_bit);
}
} else {
- printf("error: msbit (%u) must be greater than lsbit (%u)\n",
- msbit, lsbit);
+ printf("error: invalid concrete register \"%s\"\n",
+ containing_reg_name.GetCString());
}
} else {
- printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
- lsbit);
+ printf("error: msbit (%u) must be greater than lsbit (%u)\n",
+ msbit, lsbit);
}
} else {
- // TODO: print error invalid slice string that doesn't follow the
- // format
- printf("error: failed to extract regex matches for parsing the "
- "register bitfield regex\n");
+ printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
+ lsbit);
}
} else {
// TODO: print error invalid slice string that doesn't follow the
@@ -545,6 +536,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
if (!generic_regs_specified) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::aarch64_be:
for (auto &reg : m_regs) {
if (strcmp(reg.name, "pc") == 0)
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
index 3cb583172623..295c17e474fb 100644
--- a/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -32,17 +32,15 @@ HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
m_queue_id(LLDB_INVALID_QUEUE_ID) {
m_unwinder_up.reset(new HistoryUnwind(*this, pcs));
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
// Destructor
HistoryThread::~HistoryThread() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
- static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
+ static_cast<void *>(this), GetID());
DestroyThread();
}
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 7d473bff8200..83fdb011f5a1 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -51,13 +51,15 @@ HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
}
bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) {
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) {
// FIXME do not throw away the lock after we acquire it..
std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
guard.unlock();
if (frame_idx < m_pcs.size()) {
cfa = frame_idx;
pc = m_pcs[frame_idx];
+ behaves_like_zeroth_frame = (frame_idx == 0);
return true;
}
return false;
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 6c4522e6b35b..4d16608bd8c2 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -29,7 +29,8 @@ protected:
DoCreateRegisterContextForFrame(StackFrame *frame) override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
uint32_t DoGetFrameCount() override;
private:
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 9beaf2fc7ac8..2ccbeacc4960 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -12,7 +12,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
-#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
@@ -41,13 +41,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
if (thread == nullptr)
return false;
- const bool append = true;
const bool include_symbols = true;
const bool include_inlines = false;
SymbolContextList sc_list;
- const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ process->GetTarget().GetImages().FindFunctions(
ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
+ const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
if (sc_list.GetContextAtIndex(0, sc)) {
@@ -79,17 +79,23 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
AddressRange mmap_range;
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
mmap_range)) {
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ auto type_system_or_err =
+ process->GetTarget().GetScratchTypeSystemForLanguage(
+ eLanguageTypeC);
+ if (!type_system_or_err) {
+ llvm::consumeError(type_system_or_err.takeError());
+ return false;
+ }
+ CompilerType void_ptr_type =
+ type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid)
+ .GetPointerType();
const ArchSpec arch = process->GetTarget().GetArchitecture();
MmapArgList args =
process->GetTarget().GetPlatform()->GetMmapArgumentList(
arch, addr, length, prot_arg, flags, fd, offset);
lldb::ThreadPlanSP call_plan_sp(
new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
- clang_void_ptr_type, args, options));
+ void_ptr_type, args, options));
if (call_plan_sp) {
DiagnosticManager diagnostics;
@@ -129,13 +135,13 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
if (thread == nullptr)
return false;
- const bool append = true;
const bool include_symbols = true;
const bool include_inlines = false;
SymbolContextList sc_list;
- const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ process->GetTarget().GetImages().FindFunctions(
ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
- include_inlines, append, sc_list);
+ include_inlines, sc_list);
+ const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
if (sc_list.GetContextAtIndex(0, sc)) {
@@ -178,60 +184,3 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
return false;
}
-
-// FIXME: This has nothing to do with Posix, it is just a convenience function
-// that calls a
-// function of the form "void * (*)(void)". We should find a better place to
-// put this.
-
-bool lldb_private::InferiorCall(Process *process, const Address *address,
- addr_t &returned_func, bool trap_exceptions) {
- Thread *thread =
- process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == nullptr || address == nullptr)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug(false);
- options.SetTimeout(process->GetUtilityExpressionTimeout());
- options.SetTrapExceptions(trap_exceptions);
-
- ClangASTContext *clang_ast_context =
- process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type =
- clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type,
- llvm::ArrayRef<addr_t>(), options));
- if (call_plan_sp) {
- DiagnosticManager diagnostics;
-
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame) {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext(exe_ctx);
- ExpressionResults result =
- process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted) {
- returned_func =
- call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
- LLDB_INVALID_ADDRESS);
-
- if (process->GetAddressByteSize() == 4) {
- if (returned_func == UINT32_MAX)
- return false;
- } else if (process->GetAddressByteSize() == 8) {
- if (returned_func == UINT64_MAX)
- return false;
- }
- return true;
- }
- }
- }
-
- return false;
-}
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index 04316801b351..2008c5fe0b91 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -30,9 +30,6 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr,
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
-bool InferiorCall(Process *proc, const Address *address,
- lldb::addr_t &returned_func, bool trap_exceptions = false);
-
} // namespace lldb_private
#endif // lldb_InferiorCallPOSIX_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index e804a4d251f7..4ca33c248c6f 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -1111,9 +1111,10 @@ int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
if (log) {
for (uint32_t i = 0; i < 16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
- "0x%8.8x, 0x%8.8x }",
- i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ LLDB_LOGF(log,
+ "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
+ "0x%8.8x, 0x%8.8x }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
}
}
@@ -1514,8 +1515,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
// Zero is reserved for the BRP count, so don't increment it if it is zero
if (g_num_supported_hw_breakpoints > 0)
g_num_supported_hw_breakpoints++;
- // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
- // register_DBGDIDR, g_num_supported_hw_breakpoints);
}
return g_num_supported_hw_breakpoints;
#else
@@ -1642,8 +1641,6 @@ uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
uint32_t register_DBGDIDR;
asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
- // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
- // register_DBGDIDR, g_num_supported_hw_watchpoints);
}
return g_num_supported_hw_watchpoints;
#else
@@ -1656,10 +1653,6 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
size_t size,
bool read,
bool write) {
- // if (log) log->Printf
- // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
- // = %u, read = %u, write = %u)", addr, size, read, write);
-
const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
// Can't watch zero bytes
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 85d518a487bf..b3ec24d8905d 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -25,6 +25,11 @@
#include <memory>
+#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
// Support building against older versions of LLVM, this macro was added
// recently.
#ifndef LLVM_EXTENSION
@@ -285,10 +290,11 @@ int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {
void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {
if (log) {
for (uint32_t i = 0; i < 16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64
- " } WVR%-2u/WCR%-2u "
- "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",
- i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ LLDB_LOGF(log,
+ "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64
+ " } WVR%-2u/WCR%-2u "
+ "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
}
}
@@ -423,7 +429,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- value.SetBytes(fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size,
+ value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size,
endian::InlHostByteOrder());
break;
@@ -502,7 +508,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_d31: {
ProcessSP process_sp(m_thread.GetProcess());
if (process_sp.get()) {
- DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(),
+ DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(),
process_sp->GetAddressByteSize());
offset_t offset = 0;
value.SetDouble(regdata.GetDouble(&offset));
@@ -615,7 +621,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- ::memcpy(fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(),
+ ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(),
value.GetByteSize());
break;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index 2f691c807d50..abb87e3c2348 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -73,7 +73,7 @@ public:
};
struct VReg {
- llvm::AlignedCharArray<16, 16> bytes;
+ alignas(16) char bytes[16];
};
// mirrors <mach/arm/thread_status.h> arm_neon_state64_t
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 820d280c37f7..873713fd8373 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -496,11 +496,11 @@ int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
if (log) {
if (title)
- log->Printf("%s", title);
+ LLDB_LOGF(log, "%s", title);
for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name,
- (&gpr.eax)[reg]);
+ LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name,
+ (&gpr.eax)[reg]);
}
}
}
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 62e512adc9f7..47758ce85eb2 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -554,22 +554,6 @@ int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
return -1;
}
-void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) {
- if (log) {
- if (format) {
- va_list args;
- va_start(args, format);
- log->VAPrintf(format, args);
- va_end(args);
- }
- for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
- uint32_t reg = gpr_rax + i;
- log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name,
- (&gpr.rax)[reg]);
- }
- }
-}
-
int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
int set = GPRRegSet;
if (force || !RegisterSetIsCached(set)) {
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 76646d8897d1..49a589f14989 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -12,12 +12,14 @@
#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"
@@ -150,15 +152,8 @@ void RegisterContextLLDB::InitializeZerothFrame() {
UnwindLogMsg("using architectural default unwind method");
}
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx) &
- resolve_scope)) {
- m_sym_ctx_valid = true;
- }
+ 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'",
@@ -172,9 +167,6 @@ void RegisterContextLLDB::InitializeZerothFrame() {
current_pc);
}
- AddressRange addr_range;
- m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range);
-
if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
m_frame_type = eTrapHandlerFrame;
} else {
@@ -436,24 +428,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
return;
}
- bool resolve_tail_call_address = false; // m_current_pc can be one past the
- // address range of the function...
- // If the saved pc does not point to a function/symbol because it is beyond
- // the bounds of the correct function and there's no symbol there, we do
- // *not* want ResolveSymbolContextForAddress to back up the pc by 1, because
- // then we might not find the correct unwind information later. Instead, let
- // ResolveSymbolContextForAddress fail, and handle the case via
- // decr_pc_and_recompute_addr_range below.
- const SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
- m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
-
- // We require either a symbol or function in the symbols context to be
- // successfully filled in or this context is of no use to us.
- if (resolve_scope & resolved_scope) {
- m_sym_ctx_valid = true;
- }
+ 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,
@@ -467,25 +443,30 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
pc);
}
- AddressRange addr_range;
- if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) {
- m_sym_ctx_valid = false;
- }
+ bool decr_pc_and_recompute_addr_range;
- bool decr_pc_and_recompute_addr_range = false;
-
- // If the symbol lookup failed...
- if (!m_sym_ctx_valid)
+ if (!m_sym_ctx_valid) {
+ // Always decrement and recompute if the symbol lookup failed
decr_pc_and_recompute_addr_range = true;
-
- // Or if we're in the middle of the stack (and not "above" an asynchronous
- // event like sigtramp), and our "current" pc is the start of a function...
- if (GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
- GetNextFrame()->m_frame_type != eDebuggerFrame &&
- (!m_sym_ctx_valid ||
- (addr_range.GetBaseAddress().IsValid() &&
- addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() &&
- addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()))) {
+ } 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;
}
@@ -502,18 +483,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
Address temporary_pc;
temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
- SymbolContextItem resolve_scope =
- eSymbolContextFunction | eSymbolContextSymbol;
-
- ModuleSP temporary_module_sp = temporary_pc.GetModule();
- if (temporary_module_sp &&
- temporary_module_sp->ResolveSymbolContextForAddress(
- temporary_pc, resolve_scope, m_sym_ctx) &
- resolve_scope) {
- if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range))
- m_sym_ctx_valid = true;
- }
+ m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx, &addr_range);
+
UnwindLogMsg("Symbol is now %s",
GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
}
@@ -563,6 +534,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
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,
@@ -575,6 +547,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
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(),
@@ -812,6 +785,16 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
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;
}
@@ -824,6 +807,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
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;
@@ -846,6 +832,9 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// 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",
@@ -1512,8 +1501,7 @@ RegisterContextLLDB::SavedLocationForRegister(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
- unwindplan_regloc.GetDWARFExpressionLength());
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
dwarfexpr.SetRegisterKind(unwindplan_registerkind);
Value cfa_val = Scalar(m_cfa);
cfa_val.SetValueType(Value::eValueTypeLoadAddress);
@@ -1698,6 +1686,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
// 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;
@@ -1741,6 +1730,8 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
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;
@@ -1748,6 +1739,53 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
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) {
@@ -1816,8 +1854,7 @@ bool RegisterContextLLDB::ReadFrameAddress(
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
- fa.GetDWARFExpressionLength());
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
@@ -1833,12 +1870,66 @@ bool RegisterContextLLDB::ReadFrameAddress(
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.
@@ -2077,8 +2168,9 @@ void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
}
va_end(args);
- log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
- "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ 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);
}
}
@@ -2098,8 +2190,9 @@ void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
}
va_end(args);
- log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
- "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ 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/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 64dd394d233b..114ac35591e7 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -120,6 +120,10 @@ private:
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,
@@ -197,6 +201,8 @@ private:
bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
int &valid_pc_offset);
+ lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
+
lldb_private::Thread &m_thread;
///
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 99b897d441b5..db1aa1b8b093 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -109,6 +109,7 @@ RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
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;
@@ -184,6 +185,7 @@ 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.");
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
new file mode 100644
index 000000000000..916d3233cde5
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp
@@ -0,0 +1,89 @@
+//===-- RegisterContextWindows_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 "RegisterContextWindows_i386.h"
+#include "RegisterContext_x86.h"
+#include "lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+// Declare our g_register_infos structure.
+typedef struct _GPR {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t fs;
+ uint32_t gs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t es;
+} GPR;
+
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
+
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_i386[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+};
+// clang-format on
+} // namespace
+
+RegisterContextWindows_i386::RegisterContextWindows_i386(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch) {
+ assert(target_arch.GetMachine() == llvm::Triple::x86);
+}
+
+const RegisterInfo *RegisterContextWindows_i386::GetRegisterInfo() const {
+ return g_register_infos_i386;
+}
+
+uint32_t RegisterContextWindows_i386::GetRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_i386);
+}
+
+uint32_t RegisterContextWindows_i386::GetUserRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_i386);
+}
+
+size_t RegisterContextWindows_i386::GetGPRSize() const { return sizeof(GPR); }
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_i386.h b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
new file mode 100644
index 000000000000..7779cc357526
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_i386.h
@@ -0,0 +1,27 @@
+//===-- RegisterContextWindows_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 liblldb_RegisterContextWindows_i386_H_
+#define liblldb_RegisterContextWindows_i386_H_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextWindows_i386 : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterContextWindows_i386(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
new file mode 100644
index 000000000000..e90584de1a44
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp
@@ -0,0 +1,152 @@
+//===-- RegisterContextWindows_x86_64.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 "RegisterContextWindows_x86_64.h"
+#include "RegisterContext_x86.h"
+#include "lldb-x86-register-enums.h"
+
+#include <vector>
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+typedef struct _GPR {
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint16_t cs;
+ uint16_t fs;
+ uint16_t gs;
+ uint16_t ss;
+ uint16_t ds;
+ uint16_t es;
+} GPR;
+
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+#reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+typedef struct _FPReg {
+ XMMReg xmm0;
+ XMMReg xmm1;
+ XMMReg xmm2;
+ XMMReg xmm3;
+ XMMReg xmm4;
+ XMMReg xmm5;
+ XMMReg xmm6;
+ XMMReg xmm7;
+ XMMReg xmm8;
+ XMMReg xmm9;
+ XMMReg xmm10;
+ XMMReg xmm11;
+ XMMReg xmm12;
+ XMMReg xmm13;
+ XMMReg xmm14;
+ XMMReg xmm15;
+} FPReg;
+
+#define FPR_OFFSET(regname) \
+ (sizeof(GPR) + LLVM_EXTENSION offsetof(FPReg, regname))
+
+#define DEFINE_XMM(reg) \
+ { \
+#reg, NULL, sizeof(((FPReg *)nullptr)->reg), FPR_OFFSET(reg), \
+ eEncodingUint, eFormatVectorOfUInt64, \
+ {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_x86_64[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_XMM(xmm0),
+ DEFINE_XMM(xmm1),
+ DEFINE_XMM(xmm2),
+ DEFINE_XMM(xmm3),
+ DEFINE_XMM(xmm4),
+ DEFINE_XMM(xmm5),
+ DEFINE_XMM(xmm6),
+ DEFINE_XMM(xmm7),
+ DEFINE_XMM(xmm8),
+ DEFINE_XMM(xmm9),
+ DEFINE_XMM(xmm10),
+ DEFINE_XMM(xmm11),
+ DEFINE_XMM(xmm12),
+ DEFINE_XMM(xmm13),
+ DEFINE_XMM(xmm14),
+ DEFINE_XMM(xmm15)
+};
+// clang-format on
+} // namespace
+
+RegisterContextWindows_x86_64::RegisterContextWindows_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch) {
+ assert(target_arch.GetMachine() == llvm::Triple::x86_64);
+}
+
+const RegisterInfo *RegisterContextWindows_x86_64::GetRegisterInfo() const {
+ return g_register_infos_x86_64;
+}
+
+uint32_t RegisterContextWindows_x86_64::GetRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_x86_64);
+}
+
+uint32_t RegisterContextWindows_x86_64::GetUserRegisterCount() const {
+ return llvm::array_lengthof(g_register_infos_x86_64);
+}
+
+size_t RegisterContextWindows_x86_64::GetGPRSize() const { return sizeof(GPR); }
diff --git a/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
new file mode 100644
index 000000000000..18198b5b25b3
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.h
@@ -0,0 +1,28 @@
+//===-- RegisterContextWindows_x86_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 liblldb_RegisterContextWindows_x86_64_H_
+#define liblldb_RegisterContextWindows_x86_64_H_
+
+#include "RegisterInfoInterface.h"
+
+class RegisterContextWindows_x86_64
+ : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterContextWindows_x86_64(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index f7471526d054..8b367bdc6448 100644
--- a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -57,6 +57,7 @@ static const lldb_private::RegisterInfo *
GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return g_register_infos_arm64_le;
default:
assert(false && "Unhandled target architecture.");
@@ -68,6 +69,7 @@ static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
sizeof(g_register_infos_arm64_le[0]));
default:
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index 4ee0b528f229..68c12aa6e529 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -456,188 +456,265 @@ 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) \
+ { \
+ arm64_ehframe::reg, arm64_dwarf::reg, generic_kind, LLDB_INVALID_REGNUM, \
+ gpr_##reg \
+ }
+
+// Generates register kinds array for registers with lldb kind
+#define MISC_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)
+
+// Defines a 64-bit general purpose register
+#define DEFINE_GPR64(reg, generic_kind) \
+ { \
+ #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// Defines a 64-bit general purpose register
+#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \
+ { \
+ #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+// Defines a 32-bit general purpose pseudo register
+#define DEFINE_GPR32(wreg, xreg) \
+ { \
+ #wreg, nullptr, 4, \
+ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \
+ lldb::eEncodingUint, lldb::eFormatHex, MISC_KIND(gpr_##wreg), \
+ g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \
+ }
+
+// Defines a vector register with 16-byte size
+#define DEFINE_VREG(reg) \
+ { \
+ #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \
+ 0 \
+ }
+
+// Defines S and D pseudo registers mapping over correspondig 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), \
+ g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \
+ }
+
+// Defines miscellaneous status and control registers like cpsr, fpsr etc
+#define DEFINE_MISC_REGS(reg, size, TYPE, lldb_kind) \
+ { \
+ #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
- // clang-format off
- // General purpose registers
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
- // ===== ======= == ============= =================== ================ ================= =============== ======================== =================== ====== ============== ======= ======= ==
- {"x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0}, nullptr, nullptr, nullptr, 0},
- {"x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1}, nullptr, nullptr, nullptr, 0},
- {"x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2}, nullptr, nullptr, nullptr, 0},
- {"x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3}, nullptr, nullptr, nullptr, 0},
- {"x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4}, nullptr, nullptr, nullptr, 0},
- {"x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5}, nullptr, nullptr, nullptr, 0},
- {"x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6}, nullptr, nullptr, nullptr, 0},
- {"x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7}, nullptr, nullptr, nullptr, 0},
- {"x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8}, nullptr, nullptr, nullptr, 0},
- {"x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9}, nullptr, nullptr, nullptr, 0},
- {"x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10}, nullptr, nullptr, nullptr, 0},
- {"x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11}, nullptr, nullptr, nullptr, 0},
- {"x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12}, nullptr, nullptr, nullptr, 0},
- {"x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13}, nullptr, nullptr, nullptr, 0},
- {"x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14}, nullptr, nullptr, nullptr, 0},
- {"x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15}, nullptr, nullptr, nullptr, 0},
- {"x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16}, nullptr, nullptr, nullptr, 0},
- {"x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17}, nullptr, nullptr, nullptr, 0},
- {"x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18}, nullptr, nullptr, nullptr, 0},
- {"x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19}, nullptr, nullptr, nullptr, 0},
- {"x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20}, nullptr, nullptr, nullptr, 0},
- {"x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21}, nullptr, nullptr, nullptr, 0},
- {"x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22}, nullptr, nullptr, nullptr, 0},
- {"x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23}, nullptr, nullptr, nullptr, 0},
- {"x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24}, nullptr, nullptr, nullptr, 0},
- {"x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25}, nullptr, nullptr, nullptr, 0},
- {"x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26}, nullptr, nullptr, nullptr, 0},
- {"x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27}, nullptr, nullptr, nullptr, 0},
- {"x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28}, nullptr, nullptr, nullptr, 0},
- {"fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp}, nullptr, nullptr, nullptr, 0},
- {"lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr}, nullptr, nullptr, nullptr, 0},
- {"sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp}, nullptr, nullptr, nullptr, 0},
- {"pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc}, nullptr, nullptr, nullptr, 0},
-
- {"cpsr",nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE INVALIDATES DYNEXPR SZ
- // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
- {"w0", nullptr, 4, GPR_OFFSET(0) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w0}, g_contained_x0, g_w0_invalidates, nullptr, 0},
- {"w1", nullptr, 4, GPR_OFFSET(1) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w1}, g_contained_x1, g_w1_invalidates, nullptr, 0},
- {"w2", nullptr, 4, GPR_OFFSET(2) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w2}, g_contained_x2, g_w2_invalidates, nullptr, 0},
- {"w3", nullptr, 4, GPR_OFFSET(3) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w3}, g_contained_x3, g_w3_invalidates, nullptr, 0},
- {"w4", nullptr, 4, GPR_OFFSET(4) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w4}, g_contained_x4, g_w4_invalidates, nullptr, 0},
- {"w5", nullptr, 4, GPR_OFFSET(5) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w5}, g_contained_x5, g_w5_invalidates, nullptr, 0},
- {"w6", nullptr, 4, GPR_OFFSET(6) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w6}, g_contained_x6, g_w6_invalidates, nullptr, 0},
- {"w7", nullptr, 4, GPR_OFFSET(7) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w7}, g_contained_x7, g_w7_invalidates, nullptr, 0},
- {"w8", nullptr, 4, GPR_OFFSET(8) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w8}, g_contained_x8, g_w8_invalidates, nullptr, 0},
- {"w9", nullptr, 4, GPR_OFFSET(9) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w9}, g_contained_x9, g_w9_invalidates, nullptr, 0},
- {"w10", nullptr, 4, GPR_OFFSET(10) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w10}, g_contained_x10, g_w10_invalidates, nullptr, 0},
- {"w11", nullptr, 4, GPR_OFFSET(11) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w11}, g_contained_x11, g_w11_invalidates, nullptr, 0},
- {"w12", nullptr, 4, GPR_OFFSET(12) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w12}, g_contained_x12, g_w12_invalidates, nullptr, 0},
- {"w13", nullptr, 4, GPR_OFFSET(13) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w13}, g_contained_x13, g_w13_invalidates, nullptr, 0},
- {"w14", nullptr, 4, GPR_OFFSET(14) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w14}, g_contained_x14, g_w14_invalidates, nullptr, 0},
- {"w15", nullptr, 4, GPR_OFFSET(15) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w15}, g_contained_x15, g_w15_invalidates, nullptr, 0},
- {"w16", nullptr, 4, GPR_OFFSET(16) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w16}, g_contained_x16, g_w16_invalidates, nullptr, 0},
- {"w17", nullptr, 4, GPR_OFFSET(17) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w17}, g_contained_x17, g_w17_invalidates, nullptr, 0},
- {"w18", nullptr, 4, GPR_OFFSET(18) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w18}, g_contained_x18, g_w18_invalidates, nullptr, 0},
- {"w19", nullptr, 4, GPR_OFFSET(19) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w19}, g_contained_x19, g_w19_invalidates, nullptr, 0},
- {"w20", nullptr, 4, GPR_OFFSET(20) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w20}, g_contained_x20, g_w20_invalidates, nullptr, 0},
- {"w21", nullptr, 4, GPR_OFFSET(21) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w21}, g_contained_x21, g_w21_invalidates, nullptr, 0},
- {"w22", nullptr, 4, GPR_OFFSET(22) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w22}, g_contained_x22, g_w22_invalidates, nullptr, 0},
- {"w23", nullptr, 4, GPR_OFFSET(23) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w23}, g_contained_x23, g_w23_invalidates, nullptr, 0},
- {"w24", nullptr, 4, GPR_OFFSET(24) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w24}, g_contained_x24, g_w24_invalidates, nullptr, 0},
- {"w25", nullptr, 4, GPR_OFFSET(25) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w25}, g_contained_x25, g_w25_invalidates, nullptr, 0},
- {"w26", nullptr, 4, GPR_OFFSET(26) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w26}, g_contained_x26, g_w26_invalidates, nullptr, 0},
- {"w27", nullptr, 4, GPR_OFFSET(27) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w27}, g_contained_x27, g_w27_invalidates, nullptr, 0},
- {"w28", nullptr, 4, GPR_OFFSET(28) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w28}, g_contained_x28, g_w28_invalidates, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
- // ===== ======= == ============= =================== ================ ================= =============== =================== =================== ====== ============== ======= ======= ==
- {"v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0}, nullptr, nullptr, nullptr, 0},
- {"v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1}, nullptr, nullptr, nullptr, 0},
- {"v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2}, nullptr, nullptr, nullptr, 0},
- {"v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3}, nullptr, nullptr, nullptr, 0},
- {"v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4}, nullptr, nullptr, nullptr, 0},
- {"v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5}, nullptr, nullptr, nullptr, 0},
- {"v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6}, nullptr, nullptr, nullptr, 0},
- {"v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7}, nullptr, nullptr, nullptr, 0},
- {"v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8}, nullptr, nullptr, nullptr, 0},
- {"v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9}, nullptr, nullptr, nullptr, 0},
- {"v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10}, nullptr, nullptr, nullptr, 0},
- {"v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11}, nullptr, nullptr, nullptr, 0},
- {"v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12}, nullptr, nullptr, nullptr, 0},
- {"v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13}, nullptr, nullptr, nullptr, 0},
- {"v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14}, nullptr, nullptr, nullptr, 0},
- {"v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15}, nullptr, nullptr, nullptr, 0},
- {"v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16}, nullptr, nullptr, nullptr, 0},
- {"v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17}, nullptr, nullptr, nullptr, 0},
- {"v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18}, nullptr, nullptr, nullptr, 0},
- {"v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19}, nullptr, nullptr, nullptr, 0},
- {"v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20}, nullptr, nullptr, nullptr, 0},
- {"v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21}, nullptr, nullptr, nullptr, 0},
- {"v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22}, nullptr, nullptr, nullptr, 0},
- {"v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23}, nullptr, nullptr, nullptr, 0},
- {"v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24}, nullptr, nullptr, nullptr, 0},
- {"v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25}, nullptr, nullptr, nullptr, 0},
- {"v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26}, nullptr, nullptr, nullptr, 0},
- {"v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27}, nullptr, nullptr, nullptr, 0},
- {"v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28}, nullptr, nullptr, nullptr, 0},
- {"v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29}, nullptr, nullptr, nullptr, 0},
- {"v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30}, nullptr, nullptr, nullptr, 0},
- {"v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31}, nullptr, nullptr, nullptr, 0},
-
- // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATES DYNEXPR SZ
- // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
- {"s0", nullptr, 4, FPU_OFFSET(0) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0}, g_contained_v0, g_s0_invalidates, nullptr, 0},
- {"s1", nullptr, 4, FPU_OFFSET(1) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1}, g_contained_v1, g_s1_invalidates, nullptr, 0},
- {"s2", nullptr, 4, FPU_OFFSET(2) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2}, g_contained_v2, g_s2_invalidates, nullptr, 0},
- {"s3", nullptr, 4, FPU_OFFSET(3) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3}, g_contained_v3, g_s3_invalidates, nullptr, 0},
- {"s4", nullptr, 4, FPU_OFFSET(4) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4}, g_contained_v4, g_s4_invalidates, nullptr, 0},
- {"s5", nullptr, 4, FPU_OFFSET(5) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5}, g_contained_v5, g_s5_invalidates, nullptr, 0},
- {"s6", nullptr, 4, FPU_OFFSET(6) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6}, g_contained_v6, g_s6_invalidates, nullptr, 0},
- {"s7", nullptr, 4, FPU_OFFSET(7) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7}, g_contained_v7, g_s7_invalidates, nullptr, 0},
- {"s8", nullptr, 4, FPU_OFFSET(8) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8}, g_contained_v8, g_s8_invalidates, nullptr, 0},
- {"s9", nullptr, 4, FPU_OFFSET(9) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9}, g_contained_v9, g_s9_invalidates, nullptr, 0},
- {"s10", nullptr, 4, FPU_OFFSET(10) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10}, g_contained_v10, g_s10_invalidates, nullptr, 0},
- {"s11", nullptr, 4, FPU_OFFSET(11) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11}, g_contained_v11, g_s11_invalidates, nullptr, 0},
- {"s12", nullptr, 4, FPU_OFFSET(12) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12}, g_contained_v12, g_s12_invalidates, nullptr, 0},
- {"s13", nullptr, 4, FPU_OFFSET(13) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13}, g_contained_v13, g_s13_invalidates, nullptr, 0},
- {"s14", nullptr, 4, FPU_OFFSET(14) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14}, g_contained_v14, g_s14_invalidates, nullptr, 0},
- {"s15", nullptr, 4, FPU_OFFSET(15) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15}, g_contained_v15, g_s15_invalidates, nullptr, 0},
- {"s16", nullptr, 4, FPU_OFFSET(16) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16}, g_contained_v16, g_s16_invalidates, nullptr, 0},
- {"s17", nullptr, 4, FPU_OFFSET(17) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17}, g_contained_v17, g_s17_invalidates, nullptr, 0},
- {"s18", nullptr, 4, FPU_OFFSET(18) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18}, g_contained_v18, g_s18_invalidates, nullptr, 0},
- {"s19", nullptr, 4, FPU_OFFSET(19) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19}, g_contained_v19, g_s19_invalidates, nullptr, 0},
- {"s20", nullptr, 4, FPU_OFFSET(20) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20}, g_contained_v20, g_s20_invalidates, nullptr, 0},
- {"s21", nullptr, 4, FPU_OFFSET(21) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21}, g_contained_v21, g_s21_invalidates, nullptr, 0},
- {"s22", nullptr, 4, FPU_OFFSET(22) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22}, g_contained_v22, g_s22_invalidates, nullptr, 0},
- {"s23", nullptr, 4, FPU_OFFSET(23) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23}, g_contained_v23, g_s23_invalidates, nullptr, 0},
- {"s24", nullptr, 4, FPU_OFFSET(24) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24}, g_contained_v24, g_s24_invalidates, nullptr, 0},
- {"s25", nullptr, 4, FPU_OFFSET(25) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25}, g_contained_v25, g_s25_invalidates, nullptr, 0},
- {"s26", nullptr, 4, FPU_OFFSET(26) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26}, g_contained_v26, g_s26_invalidates, nullptr, 0},
- {"s27", nullptr, 4, FPU_OFFSET(27) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27}, g_contained_v27, g_s27_invalidates, nullptr, 0},
- {"s28", nullptr, 4, FPU_OFFSET(28) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28}, g_contained_v28, g_s28_invalidates, nullptr, 0},
- {"s29", nullptr, 4, FPU_OFFSET(29) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29}, g_contained_v29, g_s29_invalidates, nullptr, 0},
- {"s30", nullptr, 4, FPU_OFFSET(30) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30}, g_contained_v30, g_s30_invalidates, nullptr, 0},
- {"s31", nullptr, 4, FPU_OFFSET(31) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31}, g_contained_v31, g_s31_invalidates, nullptr, 0},
-
- {"d0", nullptr, 8, FPU_OFFSET(0) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0}, g_contained_v0, g_d0_invalidates, nullptr, 0},
- {"d1", nullptr, 8, FPU_OFFSET(1) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1}, g_contained_v1, g_d1_invalidates, nullptr, 0},
- {"d2", nullptr, 8, FPU_OFFSET(2) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2}, g_contained_v2, g_d2_invalidates, nullptr, 0},
- {"d3", nullptr, 8, FPU_OFFSET(3) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3}, g_contained_v3, g_d3_invalidates, nullptr, 0},
- {"d4", nullptr, 8, FPU_OFFSET(4) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4}, g_contained_v4, g_d4_invalidates, nullptr, 0},
- {"d5", nullptr, 8, FPU_OFFSET(5) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5}, g_contained_v5, g_d5_invalidates, nullptr, 0},
- {"d6", nullptr, 8, FPU_OFFSET(6) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6}, g_contained_v6, g_d6_invalidates, nullptr, 0},
- {"d7", nullptr, 8, FPU_OFFSET(7) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7}, g_contained_v7, g_d7_invalidates, nullptr, 0},
- {"d8", nullptr, 8, FPU_OFFSET(8) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8}, g_contained_v8, g_d8_invalidates, nullptr, 0},
- {"d9", nullptr, 8, FPU_OFFSET(9) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9}, g_contained_v9, g_d9_invalidates, nullptr, 0},
- {"d10", nullptr, 8, FPU_OFFSET(10) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10}, g_contained_v10, g_d10_invalidates, nullptr, 0},
- {"d11", nullptr, 8, FPU_OFFSET(11) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11}, g_contained_v11, g_d11_invalidates, nullptr, 0},
- {"d12", nullptr, 8, FPU_OFFSET(12) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12}, g_contained_v12, g_d12_invalidates, nullptr, 0},
- {"d13", nullptr, 8, FPU_OFFSET(13) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13}, g_contained_v13, g_d13_invalidates, nullptr, 0},
- {"d14", nullptr, 8, FPU_OFFSET(14) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14}, g_contained_v14, g_d14_invalidates, nullptr, 0},
- {"d15", nullptr, 8, FPU_OFFSET(15) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15}, g_contained_v15, g_d15_invalidates, nullptr, 0},
- {"d16", nullptr, 8, FPU_OFFSET(16) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16}, g_contained_v16, g_d16_invalidates, nullptr, 0},
- {"d17", nullptr, 8, FPU_OFFSET(17) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17}, g_contained_v17, g_d17_invalidates, nullptr, 0},
- {"d18", nullptr, 8, FPU_OFFSET(18) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18}, g_contained_v18, g_d18_invalidates, nullptr, 0},
- {"d19", nullptr, 8, FPU_OFFSET(19) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19}, g_contained_v19, g_d19_invalidates, nullptr, 0},
- {"d20", nullptr, 8, FPU_OFFSET(20) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20}, g_contained_v20, g_d20_invalidates, nullptr, 0},
- {"d21", nullptr, 8, FPU_OFFSET(21) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21}, g_contained_v21, g_d21_invalidates, nullptr, 0},
- {"d22", nullptr, 8, FPU_OFFSET(22) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22}, g_contained_v22, g_d22_invalidates, nullptr, 0},
- {"d23", nullptr, 8, FPU_OFFSET(23) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23}, g_contained_v23, g_d23_invalidates, nullptr, 0},
- {"d24", nullptr, 8, FPU_OFFSET(24) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24}, g_contained_v24, g_d24_invalidates, nullptr, 0},
- {"d25", nullptr, 8, FPU_OFFSET(25) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25}, g_contained_v25, g_d25_invalidates, nullptr, 0},
- {"d26", nullptr, 8, FPU_OFFSET(26) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26}, g_contained_v26, g_d26_invalidates, nullptr, 0},
- {"d27", nullptr, 8, FPU_OFFSET(27) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27}, g_contained_v27, g_d27_invalidates, nullptr, 0},
- {"d28", nullptr, 8, FPU_OFFSET(28) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28}, g_contained_v28, g_d28_invalidates, nullptr, 0},
- {"d29", nullptr, 8, FPU_OFFSET(29) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29}, g_contained_v29, g_d29_invalidates, nullptr, 0},
- {"d30", nullptr, 8, FPU_OFFSET(30) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30}, g_contained_v30, g_d30_invalidates, nullptr, 0},
- {"d31", nullptr, 8, FPU_OFFSET(31) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31}, g_contained_v31, g_d31_invalidates, nullptr, 0},
-
- {"fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr}, nullptr, nullptr, nullptr, 0},
- {"fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr}, nullptr, nullptr, nullptr, 0},
-
- {"far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, nullptr, 0},
- {"esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr}, nullptr, nullptr, nullptr, 0},
- {"exception", nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, nullptr, 0},
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR64(x1, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR64(x2, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR64(x3, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR64(x4, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR64(x5, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GPR64(x6, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GPR64(x7, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_GPR64(x8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x9, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x10, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x11, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x12, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x13, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x14, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x15, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x16, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x17, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x18, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x19, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x20, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x21, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x22, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x23, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x24, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x25, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x26, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x27, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x28, LLDB_INVALID_REGNUM),
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64_ALT(fp, x29, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR64_ALT(lr, x30, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GPR64_ALT(sp, x31, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(cpsr, 4, GPR, gpr_cpsr),
+
+ // DEFINE_GPR32(name, parent name)
+ DEFINE_GPR32(w0, x0),
+ DEFINE_GPR32(w1, x1),
+ DEFINE_GPR32(w2, x2),
+ DEFINE_GPR32(w3, x3),
+ DEFINE_GPR32(w4, x4),
+ DEFINE_GPR32(w5, x5),
+ DEFINE_GPR32(w6, x6),
+ DEFINE_GPR32(w7, x7),
+ DEFINE_GPR32(w8, x8),
+ DEFINE_GPR32(w9, x9),
+ DEFINE_GPR32(w10, x10),
+ DEFINE_GPR32(w11, x11),
+ DEFINE_GPR32(w12, x12),
+ DEFINE_GPR32(w13, x13),
+ DEFINE_GPR32(w14, x14),
+ DEFINE_GPR32(w15, x15),
+ DEFINE_GPR32(w16, x16),
+ DEFINE_GPR32(w17, x17),
+ DEFINE_GPR32(w18, x18),
+ DEFINE_GPR32(w19, x19),
+ DEFINE_GPR32(w20, x20),
+ DEFINE_GPR32(w21, x21),
+ DEFINE_GPR32(w22, x22),
+ DEFINE_GPR32(w23, x23),
+ DEFINE_GPR32(w24, x24),
+ DEFINE_GPR32(w25, x25),
+ DEFINE_GPR32(w26, x26),
+ DEFINE_GPR32(w27, x27),
+ DEFINE_GPR32(w28, x28),
+
+ // DEFINE_VREG(name)
+ DEFINE_VREG(v0),
+ DEFINE_VREG(v1),
+ DEFINE_VREG(v2),
+ DEFINE_VREG(v3),
+ DEFINE_VREG(v4),
+ DEFINE_VREG(v5),
+ DEFINE_VREG(v6),
+ DEFINE_VREG(v7),
+ DEFINE_VREG(v8),
+ DEFINE_VREG(v9),
+ DEFINE_VREG(v10),
+ DEFINE_VREG(v11),
+ DEFINE_VREG(v12),
+ DEFINE_VREG(v13),
+ DEFINE_VREG(v14),
+ DEFINE_VREG(v15),
+ DEFINE_VREG(v16),
+ DEFINE_VREG(v17),
+ DEFINE_VREG(v18),
+ DEFINE_VREG(v19),
+ DEFINE_VREG(v20),
+ DEFINE_VREG(v21),
+ DEFINE_VREG(v22),
+ DEFINE_VREG(v23),
+ DEFINE_VREG(v24),
+ DEFINE_VREG(v25),
+ DEFINE_VREG(v26),
+ DEFINE_VREG(v27),
+ DEFINE_VREG(v28),
+ DEFINE_VREG(v29),
+ DEFINE_VREG(v30),
+ DEFINE_VREG(v31),
+
+ // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register)
+ DEFINE_FPU_PSEUDO(s0, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v0),
+ DEFINE_FPU_PSEUDO(s1, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v1),
+ DEFINE_FPU_PSEUDO(s2, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v2),
+ DEFINE_FPU_PSEUDO(s3, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v3),
+ DEFINE_FPU_PSEUDO(s4, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v4),
+ DEFINE_FPU_PSEUDO(s5, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v5),
+ DEFINE_FPU_PSEUDO(s6, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v6),
+ DEFINE_FPU_PSEUDO(s7, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v7),
+ DEFINE_FPU_PSEUDO(s8, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v8),
+ DEFINE_FPU_PSEUDO(s9, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v9),
+ DEFINE_FPU_PSEUDO(s10, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v10),
+ DEFINE_FPU_PSEUDO(s11, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v11),
+ DEFINE_FPU_PSEUDO(s12, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v12),
+ DEFINE_FPU_PSEUDO(s13, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v13),
+ DEFINE_FPU_PSEUDO(s14, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v14),
+ DEFINE_FPU_PSEUDO(s15, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v15),
+ DEFINE_FPU_PSEUDO(s16, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v16),
+ DEFINE_FPU_PSEUDO(s17, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v17),
+ DEFINE_FPU_PSEUDO(s18, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v18),
+ DEFINE_FPU_PSEUDO(s19, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v19),
+ DEFINE_FPU_PSEUDO(s20, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v20),
+ DEFINE_FPU_PSEUDO(s21, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v21),
+ DEFINE_FPU_PSEUDO(s22, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v22),
+ DEFINE_FPU_PSEUDO(s23, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v23),
+ DEFINE_FPU_PSEUDO(s24, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v24),
+ DEFINE_FPU_PSEUDO(s25, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v25),
+ DEFINE_FPU_PSEUDO(s26, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v26),
+ DEFINE_FPU_PSEUDO(s27, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v27),
+ DEFINE_FPU_PSEUDO(s28, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v28),
+ DEFINE_FPU_PSEUDO(s29, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v29),
+ DEFINE_FPU_PSEUDO(s30, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v30),
+ DEFINE_FPU_PSEUDO(s31, 4, FPU_S_PSEUDO_REG_ENDIAN_OFFSET, v31),
+
+ DEFINE_FPU_PSEUDO(d0, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v0),
+ DEFINE_FPU_PSEUDO(d1, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v1),
+ DEFINE_FPU_PSEUDO(d2, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v2),
+ DEFINE_FPU_PSEUDO(d3, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v3),
+ DEFINE_FPU_PSEUDO(d4, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v4),
+ DEFINE_FPU_PSEUDO(d5, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v5),
+ DEFINE_FPU_PSEUDO(d6, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v6),
+ DEFINE_FPU_PSEUDO(d7, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v7),
+ DEFINE_FPU_PSEUDO(d8, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v8),
+ DEFINE_FPU_PSEUDO(d9, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v9),
+ DEFINE_FPU_PSEUDO(d10, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v10),
+ DEFINE_FPU_PSEUDO(d11, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v11),
+ DEFINE_FPU_PSEUDO(d12, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v12),
+ DEFINE_FPU_PSEUDO(d13, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v13),
+ DEFINE_FPU_PSEUDO(d14, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v14),
+ DEFINE_FPU_PSEUDO(d15, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v15),
+ DEFINE_FPU_PSEUDO(d16, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v16),
+ DEFINE_FPU_PSEUDO(d17, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v17),
+ DEFINE_FPU_PSEUDO(d18, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v18),
+ DEFINE_FPU_PSEUDO(d19, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v19),
+ DEFINE_FPU_PSEUDO(d20, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v20),
+ DEFINE_FPU_PSEUDO(d21, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v21),
+ DEFINE_FPU_PSEUDO(d22, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v22),
+ DEFINE_FPU_PSEUDO(d23, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v23),
+ DEFINE_FPU_PSEUDO(d24, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v24),
+ DEFINE_FPU_PSEUDO(d25, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v25),
+ DEFINE_FPU_PSEUDO(d26, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v26),
+ DEFINE_FPU_PSEUDO(d27, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v27),
+ DEFINE_FPU_PSEUDO(d28, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v28),
+ DEFINE_FPU_PSEUDO(d29, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v29),
+ DEFINE_FPU_PSEUDO(d30, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v30),
+ DEFINE_FPU_PSEUDO(d31, 8, FPU_D_PSEUDO_REG_ENDIAN_OFFSET, v31),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(fpsr, 4, FPU, fpu_fpsr),
+ DEFINE_MISC_REGS(fpcr, 4, FPU, fpu_fpcr),
+ DEFINE_MISC_REGS(far, 8, EXC, exc_far),
+ DEFINE_MISC_REGS(esr, 4, EXC, exc_esr),
+ DEFINE_MISC_REGS(exception, 4, EXC, exc_exception),
{DEFINE_DBG(bvr, 0)},
{DEFINE_DBG(bvr, 1)},
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 588015a51ef1..6d03bd534f37 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -30,331 +30,266 @@ using namespace lldb;
using namespace lldb_private;
const char *StopInfoMachException::GetDescription() {
- if (m_description.empty() && m_value != 0) {
- ExecutionContext exe_ctx(m_thread_wp.lock());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu =
- target ? target->GetArchitecture().GetMachine()
- : llvm::Triple::UnknownArch;
-
- const char *exc_desc = nullptr;
- const char *code_label = "code";
- const char *code_desc = nullptr;
- const char *subcode_label = "subcode";
- const char *subcode_desc = nullptr;
+ if (!m_description.empty())
+ return m_description.c_str();
+ if (GetValue() == eStopReasonInvalid)
+ return "invalid stop reason!";
+
+ ExecutionContext exe_ctx(m_thread_wp.lock());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ const char *exc_desc = nullptr;
+ const char *code_label = "code";
+ const char *code_desc = nullptr;
+ const char *subcode_label = "subcode";
+ const char *subcode_desc = nullptr;
#if defined(__APPLE__)
- char code_desc_buf[32];
- char subcode_desc_buf[32];
+ char code_desc_buf[32];
+ char subcode_desc_buf[32];
#endif
- switch (m_value) {
- case 1: // EXC_BAD_ACCESS
- exc_desc = "EXC_BAD_ACCESS";
- subcode_label = "address";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 0xd:
- code_desc = "EXC_I386_GPFLT";
- m_exc_data_count = 1;
- break;
- }
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_ARM_DA_ALIGN";
- break;
- case 0x102:
- code_desc = "EXC_ARM_DA_DEBUG";
- break;
- }
+ switch (m_value) {
+ case 1: // EXC_BAD_ACCESS
+ exc_desc = "EXC_BAD_ACCESS";
+ subcode_label = "address";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 0xd:
+ code_desc = "EXC_I386_GPFLT";
+ m_exc_data_count = 1;
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_PPC_VM_PROT_READ";
- break;
- case 0x102:
- code_desc = "EXC_PPC_BADSPACE";
- break;
- case 0x103:
- code_desc = "EXC_PPC_UNALIGNED";
- break;
- }
+ }
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
break;
-
- default:
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
break;
}
break;
- case 2: // EXC_BAD_INSTRUCTION
- exc_desc = "EXC_BAD_INSTRUCTION";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (m_exc_code == 1)
- code_desc = "EXC_I386_INVOP";
- break;
+ default:
+ break;
+ }
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ exc_desc = "EXC_BAD_INSTRUCTION";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (m_exc_code == 1)
+ code_desc = "EXC_I386_INVOP";
+ break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_INVALID_SYSCALL";
- break;
- case 2:
- code_desc = "EXC_PPC_UNIPL_INST";
- break;
- case 3:
- code_desc = "EXC_PPC_PRIVINST";
- break;
- case 4:
- code_desc = "EXC_PPC_PRIVREG";
- break;
- case 5:
- code_desc = "EXC_PPC_TRACE";
- break;
- case 6:
- code_desc = "EXC_PPC_PERFMON";
- break;
- }
- break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (m_exc_code == 1)
+ code_desc = "EXC_ARM_UNDEFINED";
+ break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (m_exc_code == 1)
- code_desc = "EXC_ARM_UNDEFINED";
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ exc_desc = "EXC_ARITHMETIC";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_DIV";
break;
-
- default:
+ case 2:
+ code_desc = "EXC_I386_INTO";
break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- exc_desc = "EXC_ARITHMETIC";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_I386_DIV";
- break;
- case 2:
- code_desc = "EXC_I386_INTO";
- break;
- case 3:
- code_desc = "EXC_I386_NOEXT";
- break;
- case 4:
- code_desc = "EXC_I386_EXTOVR";
- break;
- case 5:
- code_desc = "EXC_I386_EXTERR";
- break;
- case 6:
- code_desc = "EXC_I386_EMERR";
- break;
- case 7:
- code_desc = "EXC_I386_BOUND";
- break;
- case 8:
- code_desc = "EXC_I386_SSEEXTERR";
- break;
- }
+ case 3:
+ code_desc = "EXC_I386_NOEXT";
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_OVERFLOW";
- break;
- case 2:
- code_desc = "EXC_PPC_ZERO_DIVIDE";
- break;
- case 3:
- code_desc = "EXC_PPC_FLT_INEXACT";
- break;
- case 4:
- code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
- break;
- case 5:
- code_desc = "EXC_PPC_FLT_UNDERFLOW";
- break;
- case 6:
- code_desc = "EXC_PPC_FLT_OVERFLOW";
- break;
- case 7:
- code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
- break;
- }
+ case 4:
+ code_desc = "EXC_I386_EXTOVR";
break;
-
- default:
+ case 5:
+ code_desc = "EXC_I386_EXTERR";
+ break;
+ case 6:
+ code_desc = "EXC_I386_EMERR";
+ break;
+ case 7:
+ code_desc = "EXC_I386_BOUND";
+ break;
+ case 8:
+ code_desc = "EXC_I386_SSEEXTERR";
break;
}
break;
- case 4: // EXC_EMULATION
- exc_desc = "EXC_EMULATION";
+ default:
break;
+ }
+ break;
- case 5: // EXC_SOFTWARE
- exc_desc = "EXC_SOFTWARE";
- if (m_exc_code == 0x10003) {
- subcode_desc = "EXC_SOFT_SIGNAL";
- subcode_label = "signo";
+ case 4: // EXC_EMULATION
+ exc_desc = "EXC_EMULATION";
+ break;
+
+ case 5: // EXC_SOFTWARE
+ exc_desc = "EXC_SOFTWARE";
+ if (m_exc_code == 0x10003) {
+ subcode_desc = "EXC_SOFT_SIGNAL";
+ subcode_label = "signo";
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ exc_desc = "EXC_BREAKPOINT";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_SGL";
+ break;
+ case 2:
+ code_desc = "EXC_I386_BPT";
+ break;
}
break;
- case 6: // EXC_BREAKPOINT
- {
- exc_desc = "EXC_BREAKPOINT";
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_I386_SGL";
- break;
- case 2:
- code_desc = "EXC_I386_BPT";
- break;
- }
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code) {
- case 1:
- code_desc = "EXC_PPC_BREAKPOINT";
- break;
- }
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code) {
- case 0x101:
- code_desc = "EXC_ARM_DA_ALIGN";
- break;
- case 0x102:
- code_desc = "EXC_ARM_DA_DEBUG";
- break;
- case 1:
- code_desc = "EXC_ARM_BREAKPOINT";
- break;
- // FIXME temporary workaround, exc_code 0 does not really mean
- // EXC_ARM_BREAKPOINT
- case 0:
- code_desc = "EXC_ARM_BREAKPOINT";
- break;
- }
+ case 1:
+ code_desc = "EXC_ARM_BREAKPOINT";
break;
-
- default:
+ // FIXME temporary workaround, exc_code 0 does not really mean
+ // EXC_ARM_BREAKPOINT
+ case 0:
+ code_desc = "EXC_ARM_BREAKPOINT";
break;
}
- } break;
-
- case 7:
- exc_desc = "EXC_SYSCALL";
break;
- case 8:
- exc_desc = "EXC_MACH_SYSCALL";
+ default:
break;
+ }
+ } break;
- case 9:
- exc_desc = "EXC_RPC_ALERT";
- break;
+ case 7:
+ exc_desc = "EXC_SYSCALL";
+ break;
- case 10:
- exc_desc = "EXC_CRASH";
- break;
- case 11:
- exc_desc = "EXC_RESOURCE";
+ case 8:
+ exc_desc = "EXC_MACH_SYSCALL";
+ break;
+
+ case 9:
+ exc_desc = "EXC_RPC_ALERT";
+ break;
+
+ case 10:
+ exc_desc = "EXC_CRASH";
+ break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
#if defined(__APPLE__)
- {
- int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
-
- code_label = "limit";
- code_desc = code_desc_buf;
- subcode_label = "observed";
- subcode_desc = subcode_desc_buf;
-
- switch (resource_type) {
- case RESOURCE_TYPE_CPU:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode));
- break;
- case RESOURCE_TYPE_WAKEUPS:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s",
+ {
+ int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
+
+ code_label = "limit";
+ code_desc = code_desc_buf;
+ subcode_label = "observed";
+ subcode_desc = subcode_desc_buf;
+
+ switch (resource_type) {
+ case RESOURCE_TYPE_CPU:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(
+ m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_WAKEUPS:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
+ snprintf(
+ code_desc_buf, sizeof(code_desc_buf), "%d w/s",
(int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
- (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode));
- break;
- case RESOURCE_TYPE_MEMORY:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
- (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
- subcode_desc = nullptr;
- subcode_label = "unused";
- break;
- case RESOURCE_TYPE_IO:
- exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
- snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
- (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
- snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
- (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));;
- break;
- }
- }
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(
+ m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_MEMORY:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
+ subcode_desc = nullptr;
+ subcode_label = "unused";
+ break;
+#if defined(RESOURCE_TYPE_IO)
+ // RESOURCE_TYPE_IO is introduced in macOS SDK 10.12.
+ case RESOURCE_TYPE_IO:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));
+ ;
+ break;
#endif
- break;
- case 12:
- exc_desc = "EXC_GUARD";
- break;
+ }
}
+#endif
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
+ }
- StreamString strm;
+ StreamString strm;
- if (exc_desc)
- strm.PutCString(exc_desc);
- else
- strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
+ if (exc_desc)
+ strm.PutCString(exc_desc);
+ else
+ strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
- if (m_exc_data_count >= 1) {
- if (code_desc)
- strm.Printf(" (%s=%s", code_label, code_desc);
- else
- strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
- }
+ if (m_exc_data_count >= 1) {
+ if (code_desc)
+ strm.Printf(" (%s=%s", code_label, code_desc);
+ else
+ strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
+ }
- if (m_exc_data_count >= 2) {
- if (subcode_desc)
- strm.Printf(", %s=%s", subcode_label, subcode_desc);
- else
- strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
- }
+ if (m_exc_data_count >= 2) {
+ if (subcode_desc)
+ strm.Printf(", %s=%s", subcode_label, subcode_desc);
+ else
+ strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
+ }
- if (m_exc_data_count > 0)
- strm.PutChar(')');
+ if (m_exc_data_count > 0)
+ strm.PutChar(')');
- m_description = strm.GetString();
- }
+ m_description = strm.GetString();
return m_description.c_str();
}
@@ -362,141 +297,62 @@ 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,
bool pc_already_adjusted, bool adjust_pc_if_needed) {
- if (exc_type != 0) {
- uint32_t pc_decrement = 0;
- ExecutionContext exe_ctx(thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu =
- target ? target->GetArchitecture().GetMachine()
- : llvm::Triple::UnknownArch;
-
- switch (exc_type) {
- case 1: // EXC_BAD_ACCESS
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- switch (cpu) {
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (exc_code) {
- case 1: // EXC_PPC_INVALID_SYSCALL
- case 2: // EXC_PPC_UNIPL_INST
- case 3: // EXC_PPC_PRIVINST
- case 4: // EXC_PPC_PRIVREG
- break;
- case 5: // EXC_PPC_TRACE
- return StopInfo::CreateStopReasonToTrace(thread);
- case 6: // EXC_PPC_PERFMON
- break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- case 4: // EXC_EMULATION
- break;
-
- case 5: // EXC_SOFTWARE
- if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
- {
- if (exc_sub_code == 5) {
- // On MacOSX, a SIGTRAP can signify that a process has called exec,
- // so we should check with our dynamic loader to verify.
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp) {
- DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
- if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
- // The program was re-exec'ed
- return StopInfo::CreateStopReasonWithExec(thread);
- }
- // if (!process_did_exec)
- // {
- // // We have a SIGTRAP, make sure we
- // didn't exec by checking
- // // for the PC being at
- // "_dyld_start"...
- // lldb::StackFrameSP frame_sp
- // (thread.GetStackFrameAtIndex(0));
- // if (frame_sp)
- // {
- // const Symbol *symbol =
- // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- // if (symbol)
- // {
- // if (symbol->GetName() ==
- // ConstString("_dyld_start"))
- // process_did_exec = true;
- // }
- // }
- // }
+ if (exc_type == 0)
+ return StopInfoSP();
+
+ uint32_t pc_decrement = 0;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ switch (exc_type) {
+ case 1: // EXC_BAD_ACCESS
+ case 2: // EXC_BAD_INSTRUCTION
+ case 3: // EXC_ARITHMETIC
+ case 4: // EXC_EMULATION
+ break;
+
+ case 5: // EXC_SOFTWARE
+ if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
+ {
+ if (exc_sub_code == 5) {
+ // On MacOSX, a SIGTRAP can signify that a process has called exec,
+ // so we should check with our dynamic loader to verify.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
+ if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
+ // The program was re-exec'ed
+ return StopInfo::CreateStopReasonWithExec(thread);
}
}
- return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
}
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- bool is_actual_breakpoint = false;
- bool is_trace_if_actual_breakpoint_missing = false;
- switch (cpu) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (exc_code == 1) // EXC_I386_SGL
- {
- if (!exc_sub_code) {
- // This looks like a plain trap.
- // Have to check if there is a breakpoint here as well. When you
- // single-step onto a trap, the single step stops you not to trap.
- // Since we also do that check below, let's just use that logic.
- 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());
- }
- }
- } else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3) // EXC_I386_BPTFLT
- {
- // KDP returns EXC_I386_BPTFLT for trace breakpoints
- if (exc_code == 3)
- is_trace_if_actual_breakpoint_missing = true;
-
+ return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (exc_code == 1) // EXC_I386_SGL
+ {
+ if (!exc_sub_code) {
+ // This looks like a plain trap.
+ // Have to check if there is a breakpoint here as well. When you
+ // single-step onto a trap, the single step stops you not to trap.
+ // Since we also do that check below, let's just use that logic.
is_actual_breakpoint = true;
- if (!pc_already_adjusted)
- pc_decrement = 1;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
- break;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else {
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled data break address from our watchpoint list.
+ // 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(
@@ -509,116 +365,148 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
return StopInfo::CreateStopReasonWithWatchpointID(thread,
wp_sp->GetID());
- } else {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
}
- } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
- // is currently returning this so accept it
- // as indicating a breakpoint until the
- // kernel is fixed
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
}
- break;
+ } else if (exc_code == 2 || // EXC_I386_BPT
+ exc_code == 3) // EXC_I386_BPTFLT
+ {
+ // KDP returns EXC_I386_BPTFLT for trace breakpoints
+ if (exc_code == 3)
+ is_trace_if_actual_breakpoint_missing = true;
- case llvm::Triple::aarch64: {
- if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
- {
- // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
- // is set
- is_actual_breakpoint = false;
+ is_actual_breakpoint = true;
+ if (!pc_already_adjusted)
+ pc_decrement = 1;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled data break address from our watchpoint list.
+ 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());
+ } else {
+ is_actual_breakpoint = true;
is_trace_if_actual_breakpoint_missing = true;
}
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a
- // known/enabled data break address from our watchpoint list.
- 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());
- }
- // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
- // EXC_BAD_ACCESS
- if (thread.GetTemporaryResumeState() == eStateStepping)
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- // It looks like exc_sub_code has the 4 bytes of the instruction that
- // triggered the exception, i.e. our breakpoint opcode
- is_actual_breakpoint = exc_code == 1;
- break;
+ } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
+ // is currently returning this so accept it
+ // as indicating a breakpoint until the
+ // kernel is fixed
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
}
+ break;
- default:
- break;
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64: {
+ if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
+ {
+ // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
+ // is set
+ is_actual_breakpoint = false;
+ is_trace_if_actual_breakpoint_missing = true;
}
-
- if (is_actual_breakpoint) {
- RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
- addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
-
- ProcessSP process_sp(thread.CalculateProcess());
-
- lldb::BreakpointSiteSP bp_site_sp;
- if (process_sp)
- bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp && bp_site_sp->IsEnabled()) {
- // Update the PC if we were asked to do so, but only do so if we find
- // a breakpoint that we know about cause this could be a trap
- // instruction in the code
- if (pc_decrement > 0 && adjust_pc_if_needed)
- reg_ctx_sp->SetPC(pc);
-
- // If the breakpoint is for this thread, then we'll report the hit,
- // but if it is for another thread, we can just report no reason. We
- // don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that
- // there's a breakpoint under the pc. If we have an operating system
- // plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about
- // the thread ID so we must always report the breakpoint regardless
- // of the thread.
- if (bp_site_sp->ValidForThisThread(&thread) ||
- thread.GetProcess()->GetOperatingSystem() != nullptr)
- return StopInfo::CreateStopReasonWithBreakpointSiteID(
- thread, bp_site_sp->GetID());
- else if (is_trace_if_actual_breakpoint_missing)
- return StopInfo::CreateStopReasonToTrace(thread);
- else
- return StopInfoSP();
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled data break address from our watchpoint list.
+ 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());
}
-
- // Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_actual_breakpoint_missing &&
- thread.GetTemporaryResumeState() == eStateStepping) {
+ // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
+ // EXC_BAD_ACCESS
+ if (thread.GetTemporaryResumeState() == eStateStepping)
return StopInfo::CreateStopReasonToTrace(thread);
- }
}
- } break;
+ // It looks like exc_sub_code has the 4 bytes of the instruction that
+ // triggered the exception, i.e. our breakpoint opcode
+ is_actual_breakpoint = exc_code == 1;
+ break;
+ }
- case 7: // EXC_SYSCALL
- case 8: // EXC_MACH_SYSCALL
- case 9: // EXC_RPC_ALERT
- case 10: // EXC_CRASH
+ default:
break;
}
- return StopInfoSP(new StopInfoMachException(
- thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ if (is_actual_breakpoint) {
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
+
+ ProcessSP process_sp(thread.CalculateProcess());
+
+ lldb::BreakpointSiteSP bp_site_sp;
+ if (process_sp)
+ bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp && bp_site_sp->IsEnabled()) {
+ // Update the PC if we were asked to do so, but only do so if we find
+ // a breakpoint that we know about cause this could be a trap
+ // instruction in the code
+ if (pc_decrement > 0 && adjust_pc_if_needed)
+ reg_ctx_sp->SetPC(pc);
+
+ // If the breakpoint is for this thread, then we'll report the hit,
+ // but if it is for another thread, we can just report no reason. We
+ // don't need to worry about stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that
+ // there's a breakpoint under the pc. If we have an operating system
+ // plug-in, we might have set a thread specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about
+ // the thread ID so we must always report the breakpoint regardless
+ // of the thread.
+ if (bp_site_sp->ValidForThisThread(&thread) ||
+ thread.GetProcess()->GetOperatingSystem() != nullptr)
+ return StopInfo::CreateStopReasonWithBreakpointSiteID(
+ thread, bp_site_sp->GetID());
+ else if (is_trace_if_actual_breakpoint_missing)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ else
+ return StopInfoSP();
+ }
+
+ // Don't call this a trace if we weren't single stepping this thread.
+ if (is_trace_if_actual_breakpoint_missing &&
+ thread.GetTemporaryResumeState() == eStateStepping) {
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ }
+ } break;
+
+ case 7: // EXC_SYSCALL
+ case 8: // EXC_MACH_SYSCALL
+ case 9: // EXC_RPC_ALERT
+ case 10: // EXC_CRASH
+ break;
}
- return StopInfoSP();
+
+ return StopInfoSP(new StopInfoMachException(thread, exc_type, exc_data_count,
+ exc_code, exc_sub_code));
}
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 38209fb24948..74fc90e88547 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -104,8 +104,8 @@ bool UnwindLLDB::AddFirstFrame() {
unwind_done:
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
if (log) {
- log->Printf("th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
+ LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
}
m_unwind_complete = true;
return false;
@@ -140,10 +140,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
// 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) {
- if (log)
- log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
- "gone astray, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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;
}
@@ -161,9 +161,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a RegisterContext, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
}
@@ -181,10 +180,10 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d invalid RegisterContext for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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)) {
@@ -201,10 +200,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf(
- "%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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)) {
@@ -230,17 +228,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, "
- "stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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 {
- if (log)
- log->Printf("%*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);
+ 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);
}
}
}
@@ -258,10 +256,9 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf(
- "%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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)) {
@@ -278,18 +275,17 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
return GetOneMoreFrame(abi);
}
- if (log)
- log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ 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) {
- if (log)
- log->Printf("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());
+ 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;
}
@@ -337,9 +333,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
new_frame = GetOneMoreFrame(abi);
if (new_frame == nullptr) {
- if (log)
- log->Printf("th%d Unwind of this thread is complete.",
- m_thread.GetIndexID());
+ LLDB_LOGF(log, "th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
m_unwind_complete = true;
return false;
}
@@ -395,7 +390,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
return true;
}
-bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
+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;
@@ -410,6 +406,24 @@ bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
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;
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index c512929c185b..ff5db39730b5 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -73,7 +73,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &start_pc) override;
+ lldb::addr_t &start_pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index 7dc5a5f5fdd1..558edeec1a37 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -43,9 +43,8 @@ uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
return m_cursors.size();
}
-bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
- addr_t &cfa,
- addr_t &pc) {
+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)
@@ -55,6 +54,7 @@ bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
pc = m_cursors[idx].pc;
cfa = m_cursors[idx].fp;
+ behaves_like_zeroth_frame = (idx == 0);
return true;
}
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index 2208bcc2f2e4..f0bde90a53be 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -26,7 +26,8 @@ protected:
uint32_t DoGetFrameCount() override;
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
- lldb::addr_t &pc) override;
+ lldb::addr_t &pc,
+ bool &behaves_like_zeroth_frame) override;
lldb::RegisterContextSP
DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 980169e16c51..ab23589ae9a9 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -33,6 +33,7 @@
#include "ThreadElfCore.h"
using namespace lldb_private;
+namespace ELF = llvm::ELF;
ConstString ProcessElfCore::GetPluginNameStatic() {
static ConstString g_name("elf-core");
@@ -117,16 +118,20 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
FileRange file_range(header.p_offset, header.p_filesz);
VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
- if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
- last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
- last_entry->SetRangeEnd(range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
- } else {
- m_core_aranges.Append(range_entry);
+ // Only add to m_core_aranges if the file size is non zero. Some core files
+ // have PT_LOAD segments for all address ranges, but set f_filesz to zero for
+ // the .text sections since they can be retrieved from the object files.
+ if (header.p_filesz > 0) {
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
+ last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
}
-
// Keep a separate map of permissions that that isn't coalesced so all ranges
// are maintained.
const uint32_t permissions =
@@ -417,7 +422,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
if (pr_version > 1)
- log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
+ LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version);
}
// Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
@@ -521,8 +526,8 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
if (note.info.n_name != "FreeBSD")
continue;
- if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) ||
- (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) {
+ if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
m_thread_data.push_back(thread_data);
@@ -532,19 +537,19 @@ llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
}
switch (note.info.n_type) {
- case FREEBSD::NT_PRSTATUS:
+ case ELF::NT_PRSTATUS:
have_prstatus = true;
ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
break;
- case FREEBSD::NT_PRPSINFO:
+ case ELF::NT_PRPSINFO:
have_prpsinfo = true;
break;
- case FREEBSD::NT_THRMISC: {
+ case ELF::NT_FREEBSD_THRMISC: {
lldb::offset_t offset = 0;
thread_data.name = note.data.GetCStr(&offset, 20);
break;
}
- case FREEBSD::NT_PROCSTAT_AUXV:
+ case ELF::NT_FREEBSD_PROCSTAT_AUXV:
// FIXME: FreeBSD sticks an int at the beginning of the note
m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
break;
@@ -771,8 +776,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
continue;
- if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) ||
- (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) {
+ if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
m_thread_data.push_back(thread_data);
@@ -782,7 +787,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
}
switch (note.info.n_type) {
- case LINUX::NT_PRSTATUS: {
+ case ELF::NT_PRSTATUS: {
have_prstatus = true;
ELFLinuxPrStatus prstatus;
Status status = prstatus.Parse(note.data, arch);
@@ -795,7 +800,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
thread_data.gpregset = DataExtractor(note.data, header_size, len);
break;
}
- case LINUX::NT_PRPSINFO: {
+ case ELF::NT_PRPSINFO: {
have_prpsinfo = true;
ELFLinuxPrPsInfo prpsinfo;
Status status = prpsinfo.Parse(note.data, arch);
@@ -805,7 +810,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
SetID(prpsinfo.pr_pid);
break;
}
- case LINUX::NT_SIGINFO: {
+ case ELF::NT_SIGINFO: {
ELFLinuxSigInfo siginfo;
Status status = siginfo.Parse(note.data, arch);
if (status.Fail())
@@ -813,7 +818,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
thread_data.signo = siginfo.si_signo;
break;
}
- case LINUX::NT_FILE: {
+ case ELF::NT_FILE: {
m_nt_file_entries.clear();
lldb::offset_t offset = 0;
const uint64_t count = note.data.GetAddress(&offset);
@@ -832,7 +837,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
}
break;
}
- case LINUX::NT_AUXV:
+ case ELF::NT_AUXV:
m_auxv = note.data;
break;
default:
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.h b/source/Plugins/Process/elf-core/RegisterUtilities.h
index d3b3373150f8..49ad425db445 100644
--- a/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -11,21 +11,11 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Utility/DataExtractor.h"
+#include "llvm/BinaryFormat/ELF.h"
namespace lldb_private {
/// Core files PT_NOTE segment descriptor types
-namespace FREEBSD {
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
-};
-}
-
namespace NETBSD {
enum { NT_PROCINFO = 1, NT_AUXV = 2 };
@@ -76,22 +66,6 @@ enum {
};
}
-namespace LINUX {
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45,
- NT_SIGINFO = 0x53494749,
- NT_PPC_VMX = 0x100,
- NT_PPC_VSX = 0x102,
- NT_PRXFPREG = 0x46e62b7f,
-};
-}
-
struct CoreNote {
ELFNote info;
DataExtractor data;
@@ -122,24 +96,24 @@ DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
llvm::ArrayRef<RegsetDesc> RegsetDescs);
constexpr RegsetDesc FPR_Desc[] = {
- {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET},
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
// In a i386 core file NT_FPREGSET is present, but it's not the result
// of the FXSAVE instruction like in 64 bit files.
// The result from FXSAVE is in NT_PRXFPREG for i386 core files
- {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG},
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET},
+ {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
{llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
{llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
{llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
};
constexpr RegsetDesc PPC_VMX_Desc[] = {
- {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX},
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX},
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
};
constexpr RegsetDesc PPC_VSX_Desc[] = {
- {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VSX},
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index a5d1fc4a7bff..508c8a3108a6 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -181,9 +181,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
}
if (!reg_interface) {
- if (log)
- log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
- __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
+ 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");
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index fe7ef6b3acea..064bbde8442e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -63,18 +63,16 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
case PacketResult::Success:
break;
default:
- if (log)
- log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () ReadPacket(...) => false",
+ __FUNCTION__);
return eStateInvalid;
}
if (response.Empty())
return eStateInvalid;
const char stop_type = response.GetChar();
- if (log)
- log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
- response.GetStringRef().c_str());
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+ response.GetStringRef().data());
switch (stop_type) {
case 'W':
@@ -84,9 +82,8 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
// ERROR
return eStateInvalid;
default:
- if (log)
- log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::%s () unrecognized async packet",
+ __FUNCTION__);
return eStateInvalid;
case 'O': {
std::string inferior_stdout;
@@ -162,10 +159,10 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
- log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(),
- send_async);
+ LLDB_LOGF(log,
+ "GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(), send_async);
return PacketResult::ErrorSendFailed;
}
@@ -181,10 +178,10 @@ GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
if (!lock) {
if (Log *log =
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
- log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
- "packet '%.*s' (send_async=%d)",
- __FUNCTION__, int(payload.size()), payload.data(),
- send_async);
+ LLDB_LOGF(log,
+ "GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(), send_async);
return PacketResult::ErrorSendFailed;
}
@@ -214,13 +211,13 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
return packet_result;
// Response says it wasn't valid
Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
- if (log)
- log->Printf(
- "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
- int(payload.size()), payload.data(), response.GetStringRef().c_str(),
- (i == (max_response_retries - 1))
- ? "using invalid response and giving up"
- : "ignoring response and waiting for another");
+ LLDB_LOGF(
+ log,
+ "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
+ int(payload.size()), payload.data(), response.GetStringRef().data(),
+ (i == (max_response_retries - 1))
+ ? "using invalid response and giving up"
+ : "ignoring response and waiting for another");
}
return packet_result;
}
@@ -228,16 +225,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
StringExtractorGDBRemote &response) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
// we want to lock down packet sending while we continue
Lock lock(*this, true);
- if (log)
- log->Printf(
- "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
- __FUNCTION__, int(payload.size()), payload.data());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
+ __FUNCTION__, int(payload.size()), payload.data());
if (SendPacketNoLock(payload) != PacketResult::Success)
return false;
@@ -315,18 +310,16 @@ void GDBRemoteClientBase::ContinueLock::unlock() {
GDBRemoteClientBase::ContinueLock::LockResult
GDBRemoteClientBase::ContinueLock::lock() {
Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
- if (log)
- log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
- __FUNCTION__, m_comm.m_continue_packet.c_str());
+ LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
+ __FUNCTION__, m_comm.m_continue_packet.c_str());
lldbassert(!m_acquired);
std::unique_lock<std::mutex> lock(m_comm.m_mutex);
m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
if (m_comm.m_should_stop) {
m_comm.m_should_stop = false;
- if (log)
- log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() cancelled",
+ __FUNCTION__);
return LockResult::Cancelled;
}
if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
@@ -368,9 +361,8 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, nullptr);
if (bytes_written == 0) {
--m_comm.m_async_count;
- if (log)
- log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
- "interrupt packet");
+ LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send "
+ "interrupt packet");
return;
}
if (log)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index 54f69e8caac6..ea294ffcef26 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -24,12 +24,10 @@ public:
virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
virtual void HandleStopReply() = 0;
- // =========================================================================
/// Process asynchronously-received structured data.
///
/// \param[in] data
/// The complete data packet, expected to start with JSON-async.
- // =========================================================================
virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
};
@@ -83,42 +81,48 @@ protected:
virtual void OnRunPacketSent(bool first);
private:
- // Variables handling synchronization between the Continue thread and any
- // other threads
- // wishing to send packets over the connection. Either the continue thread has
- // control over
- // the connection (m_is_running == true) or the connection is free for an
- // arbitrary number of
- // other senders to take which indicate their interest by incrementing
- // m_async_count.
- // Semantics of individual states:
- // - m_continue_packet == false, m_async_count == 0: connection is free
- // - m_continue_packet == true, m_async_count == 0: only continue thread is
- // present
- // - m_continue_packet == true, m_async_count > 0: continue thread has
- // control, async threads
- // should interrupt it and wait for it to set m_continue_packet to false
- // - m_continue_packet == false, m_async_count > 0: async threads have
- // control, continue
- // thread needs to wait for them to finish (m_async_count goes down to 0).
+ /// Variables handling synchronization between the Continue thread and any
+ /// other threads wishing to send packets over the connection. Either the
+ /// continue thread has control over the connection (m_is_running == true) or
+ /// the connection is free for an arbitrary number of other senders to take
+ /// which indicate their interest by incrementing m_async_count.
+ ///
+ /// Semantics of individual states:
+ ///
+ /// - m_continue_packet == false, m_async_count == 0:
+ /// connection is free
+ /// - m_continue_packet == true, m_async_count == 0:
+ /// only continue thread is present
+ /// - m_continue_packet == true, m_async_count > 0:
+ /// continue thread has control, async threads should interrupt it and wait
+ /// for it to set m_continue_packet to false
+ /// - m_continue_packet == false, m_async_count > 0:
+ /// async threads have control, continue thread needs to wait for them to
+ /// finish (m_async_count goes down to 0).
+ /// @{
std::mutex m_mutex;
std::condition_variable m_cv;
- // Packet with which to resume after an async interrupt. Can be changed by an
- // async thread
- // e.g. to inject a signal.
+
+ /// Packet with which to resume after an async interrupt. Can be changed by
+ /// an async thread e.g. to inject a signal.
std::string m_continue_packet;
- // When was the interrupt packet sent. Used to make sure we time out if the
- // stub does not
- // respond to interrupt requests.
+
+ /// When was the interrupt packet sent. Used to make sure we time out if the
+ /// stub does not respond to interrupt requests.
std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+
+ /// Number of threads interested in sending.
uint32_t m_async_count;
+
+ /// Whether the continue thread has control.
bool m_is_running;
- bool m_should_stop; // Whether we should resume after a stop.
- // end of continue thread synchronization block
- // This handles the synchronization between individual async threads. For now
- // they just use a
- // simple mutex.
+ /// Whether we should resume after a stop.
+ bool m_should_stop;
+ /// @}
+
+ /// This handles the synchronization between individual async threads. For
+ /// now they just use a simple mutex.
std::recursive_mutex m_async_mutex;
bool ShouldStop(const UnixSignals &signals,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 11052eff948f..144ae103faa4 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
@@ -38,6 +39,8 @@
#if defined(__APPLE__)
#define DEBUGSERVER_BASENAME "debugserver"
+#elif defined(_WIN32)
+#define DEBUGSERVER_BASENAME "lldb-server.exe"
#else
#define DEBUGSERVER_BASENAME "lldb-server"
#endif
@@ -99,10 +102,8 @@ size_t GDBRemoteCommunication::SendAck() {
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '+';
const size_t bytes_written = Write(&ch, 1, status, nullptr);
- if (log)
- log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
return bytes_written;
}
@@ -111,10 +112,8 @@ size_t GDBRemoteCommunication::SendNack() {
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '-';
const size_t bytes_written = Write(&ch, 1, status, nullptr);
- if (log)
- log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
return bytes_written;
}
@@ -172,13 +171,12 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
strm.Printf("%*s", (int)3, p);
log->PutString(strm.GetString());
} else
- log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
- (int)packet_length, packet_data);
+ LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %.*s",
+ (uint64_t)bytes_written, (int)packet_length, packet_data);
}
m_history.AddPacket(packet.str(), packet_length,
- GDBRemoteCommunicationHistory::ePacketTypeSend,
- bytes_written);
+ GDBRemotePacket::ePacketTypeSend, bytes_written);
if (bytes_written == packet_length) {
if (!skip_ack && GetSendAcks())
@@ -186,9 +184,8 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
else
return PacketResult::Success;
} else {
- if (log)
- log->Printf("error: failed to send packet: %.*s", (int)packet_length,
- packet_data);
+ LLDB_LOGF(log, "error: failed to send packet: %.*s", (int)packet_length,
+ packet_data);
}
}
return PacketResult::ErrorSendFailed;
@@ -332,11 +329,12 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
std::string regex_str = "^";
regex_str += echo_packet;
regex_str += "$";
- response_regex.Compile(regex_str);
+ response_regex = RegularExpression(regex_str);
} else {
echo_packet_len =
::snprintf(echo_packet, sizeof(echo_packet), "qC");
- response_regex.Compile(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
+ response_regex =
+ RegularExpression(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
}
PacketResult echo_packet_result =
@@ -489,11 +487,10 @@ bool GDBRemoteCommunication::DecompressPacket() {
llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
bool success = packet_checksum == actual_checksum;
if (!success) {
- if (log)
- log->Printf(
- "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
+ LLDB_LOGF(log,
+ "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+ (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
+ (uint8_t)actual_checksum);
}
// Send the ack or nack if needed
if (!success) {
@@ -651,8 +648,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
if (src && src_len > 0) {
if (log && log->GetVerbose()) {
StreamString s;
- log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s",
- __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s adding %u bytes: %.*s",
+ __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
}
m_bytes.append((const char *)src, src_len);
}
@@ -733,9 +730,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
break;
}
}
- if (log)
- log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
- __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
+ __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
m_bytes.erase(0, idx - 1);
} break;
}
@@ -752,7 +748,6 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
size_t content_end = content_start + content_length;
bool success = true;
- std::string &packet_str = packet.GetStringRef();
if (log) {
// If logging was just enabled and we have history, then dump out what
// we have to the log so we get the historical context. The Dump() call
@@ -800,25 +795,23 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
log->PutString(strm.GetString());
} else {
if (CompressionIsEnabled())
- log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
- (uint64_t)original_packet_size, (uint64_t)total_length,
- (int)(total_length), m_bytes.c_str());
+ LLDB_LOGF(log, "<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ (int)(total_length), m_bytes.c_str());
else
- log->Printf("<%4" PRIu64 "> read packet: %.*s",
- (uint64_t)total_length, (int)(total_length),
- m_bytes.c_str());
+ LLDB_LOGF(log, "<%4" PRIu64 "> read packet: %.*s",
+ (uint64_t)total_length, (int)(total_length),
+ m_bytes.c_str());
}
}
m_history.AddPacket(m_bytes, total_length,
- GDBRemoteCommunicationHistory::ePacketTypeRecv,
- total_length);
+ GDBRemotePacket::ePacketTypeRecv, total_length);
- // Clear packet_str in case there is some existing data in it.
- packet_str.clear();
// 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) {
@@ -841,6 +834,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
packet_str.push_back(*c);
}
}
+ packet = StringExtractorGDBRemote(packet_str);
if (m_bytes[0] == '$' || m_bytes[0] == '%') {
assert(checksum_idx < m_bytes.size());
@@ -853,11 +847,11 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
llvm::StringRef(m_bytes).slice(content_start, content_end));
success = packet_checksum == actual_checksum;
if (!success) {
- if (log)
- log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, "
- "got 0x%2.2x",
- (int)(total_length), m_bytes.c_str(),
- (uint8_t)packet_checksum, (uint8_t)actual_checksum);
+ LLDB_LOGF(log,
+ "error: checksum mismatch: %.*s expected 0x%2.2x, "
+ "got 0x%2.2x",
+ (int)(total_length), m_bytes.c_str(),
+ (uint8_t)packet_checksum, (uint8_t)actual_checksum);
}
// Send the ack or nack if needed
if (!success)
@@ -867,9 +861,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
}
} else {
success = false;
- if (log)
- log->Printf("error: invalid checksum in packet: '%s'\n",
- m_bytes.c_str());
+ LLDB_LOGF(log, "error: invalid checksum in packet: '%s'\n",
+ m_bytes.c_str());
}
}
@@ -933,10 +926,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
const char *url, Platform *platform, ProcessLaunchInfo &launch_info,
uint16_t *port, const Args *inferior_args, int pass_comm_fd) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
- __FUNCTION__, url ? url : "<empty>",
- port ? *port : uint16_t(0));
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
+ __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
Status error;
// If we locate debugserver, keep that located version around
@@ -953,10 +944,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (!env_debugserver_path.empty()) {
debugserver_file_spec.SetFile(env_debugserver_path,
FileSpec::Style::native);
- if (log)
- log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
- "from environment variable: %s",
- __FUNCTION__, env_debugserver_path.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() gdb-remote stub exe path set "
+ "from environment variable: %s",
+ __FUNCTION__, env_debugserver_path.c_str());
} else
debugserver_file_spec = g_debugserver_file_spec;
bool debugserver_exists =
@@ -968,10 +959,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec);
if (debugserver_exists) {
- if (log)
- log->Printf(
- "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
- __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
g_debugserver_file_spec = debugserver_file_spec;
} else {
@@ -985,10 +975,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// exist
debugserver_exists = true;
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() could not find "
- "gdb-remote stub exe '%s'",
- __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() could not find "
+ "gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
}
// Don't cache the platform specific GDB server binary as it could
// change from platform to platform
@@ -1052,10 +1042,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe",
false, named_pipe_path);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "named pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "named pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
debugserver_args.AppendArgument(llvm::StringRef("--named-pipe"));
@@ -1065,10 +1055,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// using using an unnamed pipe...
error = socket_pipe.CreateNew(true);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "unnamed pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "unnamed pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
pipe_t write = socket_pipe.GetWritePipe();
@@ -1081,10 +1071,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// debugserver connect to us..
error = StartListenThread("127.0.0.1", 0);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() unable to start listen "
- "thread: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() unable to start listen "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
@@ -1104,9 +1094,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
*port = port_;
} else {
error.SetErrorString("failed to bind to port 0 on 127.0.0.1");
- if (log)
- log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s",
+ __FUNCTION__, error.AsCString());
return error;
}
}
@@ -1148,10 +1137,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (has_env_var) {
debugserver_args.AppendArgument(llvm::StringRef(extra_arg));
- if (log)
- log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
- "to stub command line (%s)",
- __FUNCTION__, env_var_name, extra_arg.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s adding env var %s contents "
+ "to stub command line (%s)",
+ __FUNCTION__, env_var_name, extra_arg.c_str());
}
} while (has_env_var);
@@ -1177,8 +1166,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
StreamString string_stream;
Platform *const platform = nullptr;
launch_info.Dump(string_stream, platform);
- log->Printf("launch info for gdb-remote stub:\n%s",
- string_stream.GetData());
+ LLDB_LOGF(log, "launch info for gdb-remote stub:\n%s",
+ string_stream.GetData());
}
error = Host::LaunchProcess(launch_info);
@@ -1188,11 +1177,10 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (named_pipe_path.size() > 0) {
error = socket_pipe.OpenAsReader(named_pipe_path, false);
if (error.Fail())
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to open named pipe %s for reading: %s",
- __FUNCTION__, named_pipe_path.c_str(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "failed to open named pipe %s for reading: %s",
+ __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
if (socket_pipe.CanWrite())
@@ -1209,24 +1197,22 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
uint16_t child_port = StringConvert::ToUInt32(port_cstr, 0);
if (*port == 0 || *port == child_port) {
*port = child_port;
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listens %u port",
- __FUNCTION__, *port);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "debugserver listens %u port",
+ __FUNCTION__, *port);
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listening on port "
- "%d but requested port was %d",
- __FUNCTION__, (uint32_t)child_port,
- (uint32_t)(*port));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "debugserver listening on port "
+ "%d but requested port was %d",
+ __FUNCTION__, (uint32_t)child_port, (uint32_t)(*port));
}
} else {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to read a port value from pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s() "
+ "failed to read a port value from pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
socket_pipe.Close();
}
@@ -1234,10 +1220,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (named_pipe_path.size() > 0) {
const auto err = socket_pipe.Delete(named_pipe_path);
if (err.Fail()) {
- if (log)
- log->Printf(
- "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
}
}
@@ -1249,9 +1234,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
}
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
}
return error;
@@ -1351,7 +1335,7 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
if (type == PacketType::Notify) {
// put this packet into an event
- const char *pdata = packet.GetStringRef().c_str();
+ const char *pdata = packet.GetStringRef().data();
// as the communication class, we are a broadcaster and the async thread
// is tuned to listen to us
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 9797184026e0..feb9f0589cee 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -23,7 +23,6 @@
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
@@ -35,17 +34,15 @@
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/JSON.h"
-#if defined(__APPLE__)
-#ifndef HAVE_LIBCOMPRESSION
-#define HAVE_LIBCOMPRESSION
-#endif
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
using namespace std::chrono;
// GDBRemoteCommunicationClient constructor
@@ -342,7 +339,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
// not, we assume no limit
// build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
StreamString packet;
packet.PutCString("qSupported");
for (uint32_t i = 0; i < features.size(); ++i) {
@@ -354,7 +351,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
if (SendPacketAndWaitForResponse(packet.GetString(), response,
/*send_async=*/false) ==
PacketResult::Success) {
- const char *response_cstr = response.GetStringRef().c_str();
+ const char *response_cstr = response.GetStringRef().data();
// Hang on to the qSupported packet, so that platforms can do custom
// configuration of the transport before attaching/launching the process.
@@ -439,8 +436,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_max_packet_size = UINT64_MAX; // Must have been a garbled response
Log *log(
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("Garbled PacketSize spec in qSupported response");
+ LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
}
}
}
@@ -469,7 +465,7 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
m_supports_vCont_S = eLazyBoolNo;
if (SendPacketAndWaitForResponse("vCont?", response, false) ==
PacketResult::Success) {
- const char *response_cstr = response.GetStringRef().c_str();
+ const char *response_cstr = response.GetStringRef().data();
if (::strstr(response_cstr, ";c"))
m_supports_vCont_c = eLazyBoolYes;
@@ -525,9 +521,10 @@ GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
if (!lock) {
if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
- log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
- "for %s packet.",
- __FUNCTION__, payload.GetData());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
+ "for %s packet.",
+ __FUNCTION__, payload.GetData());
return PacketResult::ErrorNoSequenceLock;
}
@@ -660,10 +657,10 @@ GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
if (!lock) {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "packets with prefix '%s'",
- payload_prefix);
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "packets with prefix '%s'",
+ payload_prefix);
return PacketResult::ErrorNoSequenceLock;
}
@@ -934,6 +931,11 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
return m_os_version;
}
+llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
+ GetHostInfo();
+ return m_maccatalyst_version;
+}
+
bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
if (GetHostInfo()) {
if (!m_os_build.empty()) {
@@ -1136,6 +1138,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
uint32_t sub = 0;
std::string arch_name;
std::string os_name;
+ std::string environment;
std::string vendor_name;
std::string triple;
std::string distribution_id;
@@ -1175,7 +1178,11 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
extractor.GetHexByteString(m_os_kernel);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- os_name = value;
+ if (value.equals("maccatalyst")) {
+ os_name = "ios";
+ environment = "macabi";
+ } else
+ os_name = value;
++num_keys_decoded;
} else if (name.equals("vendor")) {
vendor_name = value;
@@ -1199,6 +1206,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
{
if (!m_os_version.tryParse(value))
++num_keys_decoded;
+ } else if (name.equals("maccatalyst_version")) {
+ if (!m_maccatalyst_version.tryParse(value))
+ ++num_keys_decoded;
} else if (name.equals("watchpoint_exceptions_received")) {
m_watchpoints_trigger_after_instruction =
llvm::StringSwitch<LazyBool>(value)
@@ -1236,6 +1246,8 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
llvm::StringRef(vendor_name));
if (!os_name.empty())
m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ if (!environment.empty())
+ m_host_arch.GetTriple().setEnvironmentName(environment);
}
} else {
std::string triple;
@@ -1259,6 +1271,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
host_triple.getOS() == llvm::Triple::Darwin) {
switch (m_host_arch.GetMachine()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::arm:
case llvm::Triple::thumb:
host_triple.setOS(llvm::Triple::IOS);
@@ -1284,14 +1297,15 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
assert(byte_order == m_host_arch.GetByteOrder());
}
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s parsed host "
- "architecture as %s, triple as %s from triple text %s",
- __FUNCTION__, m_host_arch.GetArchitectureName()
- ? m_host_arch.GetArchitectureName()
- : "<null-arch-name>",
- m_host_arch.GetTriple().getTriple().c_str(),
- triple.c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s parsed host "
+ "architecture as %s, triple as %s from triple text %s",
+ __FUNCTION__,
+ m_host_arch.GetArchitectureName()
+ ? m_host_arch.GetArchitectureName()
+ : "<null-arch-name>",
+ m_host_arch.GetTriple().getTriple().c_str(),
+ triple.c_str());
}
if (!distribution_id.empty())
m_host_arch.SetDistributionId(distribution_id.c_str());
@@ -1893,7 +1907,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
} else if (name.equals("euid")) {
uint32_t uid = UINT32_MAX;
value.getAsInteger(0, uid);
- process_info.SetEffectiveGroupID(uid);
+ process_info.SetEffectiveUserID(uid);
} else if (name.equals("gid")) {
uint32_t gid = UINT32_MAX;
value.getAsInteger(0, gid);
@@ -1914,6 +1928,26 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
std::string name;
extractor.GetHexByteString(name);
process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
+ } else if (name.equals("args")) {
+ llvm::StringRef encoded_args(value), hex_arg;
+
+ bool is_arg0 = true;
+ while (!encoded_args.empty()) {
+ std::tie(hex_arg, encoded_args) = encoded_args.split('-');
+ std::string arg;
+ StringExtractor extractor(hex_arg);
+ if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
+ // In case of wrong encoding, we discard all the arguments
+ process_info.GetArguments().Clear();
+ process_info.SetArg0("");
+ break;
+ }
+ if (is_arg0)
+ process_info.SetArg0(arg);
+ else
+ process_info.GetArguments().AppendArgument(arg);
+ is_arg0 = false;
+ }
} else if (name.equals("cputype")) {
value.getAsInteger(0, cpu);
} else if (name.equals("cpusubtype")) {
@@ -1987,6 +2021,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
uint32_t sub = 0;
std::string arch_name;
std::string os_name;
+ std::string environment;
std::string vendor_name;
std::string triple;
std::string elf_abi;
@@ -2007,7 +2042,11 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
extractor.GetHexByteString(triple);
++num_keys_decoded;
} else if (name.equals("ostype")) {
- os_name = value;
+ if (value.equals("maccatalyst")) {
+ os_name = "ios";
+ environment = "macabi";
+ } else
+ os_name = value;
++num_keys_decoded;
} else if (name.equals("vendor")) {
vendor_name = value;
@@ -2048,6 +2087,8 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
} else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
!vendor_name.empty()) {
llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
+ if (!environment.empty())
+ triple.setEnvironmentName(environment);
assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
assert(triple.getObjectFormat() != llvm::Triple::Wasm);
@@ -2064,12 +2105,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
break;
case llvm::Triple::Wasm:
case llvm::Triple::XCOFF:
- if (log)
- log->Printf("error: not supported target architecture");
+ LLDB_LOGF(log, "error: not supported target architecture");
return false;
case llvm::Triple::UnknownObjectFormat:
- if (log)
- log->Printf("error: failed to determine target architecture");
+ LLDB_LOGF(log, "error: failed to determine target architecture");
return false;
}
@@ -2081,8 +2120,10 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
}
m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
}
return true;
}
@@ -2156,8 +2197,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
packet.Printf("egid:%u;",
match_info.GetProcessInfo().GetEffectiveGroupID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
+ packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
const ArchSpec &match_arch =
match_info.GetProcessInfo().GetArchitecture();
@@ -2178,8 +2218,7 @@ uint32_t GDBRemoteCommunicationClient::FindProcesses(
if (!DecodeProcessInfoResponse(response, process_info))
break;
process_infos.Append(process_info);
- response.GetStringRef().clear();
- response.SetFilePos(0);
+ response = StringExtractorGDBRemote();
} while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
PacketResult::Success);
} else {
@@ -2641,9 +2680,8 @@ bool GDBRemoteCommunicationClient::GetThreadStopInfo(
uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
- __FUNCTION__, insert ? "add" : "remove", addr);
+ LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
+ __FUNCTION__, insert ? "add" : "remove", addr);
// Check if the stub is known not to support this breakpoint type
if (!SupportsGDBStoppointPacket(type))
@@ -2745,9 +2783,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
#if !defined(LLDB_CONFIGURATION_DEBUG)
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "packet 'qfThreadInfo'");
+ LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending "
+ "packet 'qfThreadInfo'");
#endif
sequence_mutex_unavailable = true;
}
@@ -2879,7 +2916,7 @@ static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
}
lldb::user_id_t
GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
- uint32_t flags, mode_t mode,
+ File::OpenOptions flags, mode_t mode,
Status &error) {
std::string path(file_spec.GetPath(false));
lldb_private::StreamString stream;
@@ -3146,7 +3183,8 @@ bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
if (arch.IsValid() &&
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
arch.GetTriple().getOS() == llvm::Triple::IOS &&
- arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
m_avoid_g_packets = eLazyBoolYes;
uint32_t gdb_server_version = GetGDBServerProgramVersion();
if (gdb_server_version != 0) {
@@ -3592,21 +3630,21 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
llvm::Optional<std::vector<ModuleSpec>>
GDBRemoteCommunicationClient::GetModulesInfo(
llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ namespace json = llvm::json;
+
if (!m_supports_jModulesInfo)
return llvm::None;
- JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
+ json::Array module_array;
for (const FileSpec &module_file_spec : module_file_specs) {
- JSONObject::SP module_sp = std::make_shared<JSONObject>();
- module_array_sp->AppendObject(module_sp);
- module_sp->SetObject(
- "file", std::make_shared<JSONString>(module_file_spec.GetPath(false)));
- module_sp->SetObject("triple",
- std::make_shared<JSONString>(triple.getTriple()));
+ module_array.push_back(
+ json::Object{{"file", module_file_spec.GetPath(false)},
+ {"triple", triple.getTriple()}});
}
StreamString unescaped_payload;
unescaped_payload.PutCString("jModulesInfo:");
- module_array_sp->Write(unescaped_payload);
+ unescaped_payload.AsRawOstream() << std::move(module_array);
+
StreamGDBRemote payload;
payload.PutEscapedBytes(unescaped_payload.GetString().data(),
unescaped_payload.GetSize());
@@ -3796,8 +3834,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
lldb_private::SymbolContextList sc_list;
- if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
- ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
+ process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ ConstString(symbol_name), eSymbolTypeAny, sc_list);
+ if (!sc_list.IsEmpty()) {
const size_t num_scs = sc_list.GetSize();
for (size_t sc_idx = 0;
sc_idx < num_scs &&
@@ -3873,9 +3912,9 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
} else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
- log->Printf(
- "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
+ __FUNCTION__);
}
}
}
@@ -3899,26 +3938,27 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
!m_supported_async_json_packets_sp->GetAsArray()) {
// We were returned something other than a JSON array. This is
// invalid. Clear it out.
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s(): "
- "QSupportedAsyncJSONPackets returned invalid "
- "result: %s",
- __FUNCTION__, response.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets returned invalid "
+ "result: %s",
+ __FUNCTION__, response.GetStringRef().data());
m_supported_async_json_packets_sp.reset();
}
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s(): "
- "QSupportedAsyncJSONPackets unsupported",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets unsupported",
+ __FUNCTION__);
}
if (log && m_supported_async_json_packets_sp) {
StreamString stream;
m_supported_async_json_packets_sp->Dump(stream);
- log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
- "JSON packets: %s",
- __FUNCTION__, stream.GetData());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationClient::%s(): supported async "
+ "JSON packets: %s",
+ __FUNCTION__, stream.GetData());
}
}
@@ -3980,14 +4020,14 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
if (result == PacketResult::Success) {
// We failed if the config result comes back other than OK.
- if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
+ if (strcmp(response.GetStringRef().data(), "OK") == 0) {
// Okay!
error.Clear();
} else {
error.SetErrorStringWithFormat("configuring StructuredData feature "
"%s failed with error %s",
type_name.AsCString(),
- response.GetStringRef().c_str());
+ response.GetStringRef().data());
}
} else {
// Can we get more data here on the failure?
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index de85c9f8b67b..574cd0fd70c5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -17,8 +17,9 @@
#include <string>
#include <vector>
+#include "lldb/Host/File.h"
#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/StreamGDBRemote.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/StructuredData.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
@@ -248,6 +249,8 @@ public:
llvm::VersionTuple GetOSVersion();
+ llvm::VersionTuple GetMacCatalystVersion();
+
bool GetOSBuildString(std::string &s);
bool GetOSKernelDescription(std::string &s);
@@ -348,7 +351,7 @@ public:
size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
bool &sequence_mutex_unavailable);
- lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
mode_t mode, Status &error);
bool CloseFile(lldb::user_id_t fd, Status &error);
@@ -548,6 +551,7 @@ protected:
ArchSpec m_host_arch;
ArchSpec m_process_arch;
llvm::VersionTuple m_os_version;
+ llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
std::string m_os_kernel;
std::string m_hostname;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index bcddb4faf863..d2cc32f63f20 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -18,12 +18,6 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
- yaml::Output yout(strm);
- yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
- strm.flush();
-}
-
GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
: m_packets(), m_curr_idx(0), m_total_packet_count(0),
m_dumped_to_log(false) {
@@ -33,7 +27,8 @@ GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
-void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
+void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
+ GDBRemotePacket::Type type,
uint32_t bytes_transmitted) {
const size_t size = m_packets.size();
if (size == 0)
@@ -50,7 +45,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
}
void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
- uint32_t src_len, PacketType type,
+ uint32_t src_len,
+ GDBRemotePacket::Type type,
uint32_t bytes_transmitted) {
const size_t size = m_packets.size();
if (size == 0)
@@ -72,13 +68,12 @@ void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
const uint32_t stop_idx = m_curr_idx + size;
for (uint32_t i = first_idx; i < stop_idx; ++i) {
const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ const GDBRemotePacket &entry = m_packets[idx];
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
+ entry.packet.data.empty())
break;
- strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.data.c_str());
+ strm.Printf("history[%u] ", entry.packet_idx);
+ entry.Dump(strm);
}
}
@@ -92,51 +87,15 @@ void GDBRemoteCommunicationHistory::Dump(Log *log) const {
const uint32_t stop_idx = m_curr_idx + size;
for (uint32_t i = first_idx; i < stop_idx; ++i) {
const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ const GDBRemotePacket &entry = m_packets[idx];
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
+ entry.packet.data.empty())
break;
- log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.data.c_str());
+ LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
+ : "read",
+ entry.packet.data.c_str());
}
}
-void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
- enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
- io.enumCase(value, "Invalid",
- GDBRemoteCommunicationHistory::ePacketTypeInvalid);
- io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
- io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
-}
-
-void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
- output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
- raw_ostream &Out) {
- Out << toHex(Val.data);
-}
-
-StringRef
-yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
- StringRef Scalar, void *,
- GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
- Val.data = fromHex(Scalar);
- return {};
-}
-
-void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
- IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
- io.mapRequired("packet", Entry.packet);
- io.mapRequired("type", Entry.type);
- io.mapRequired("bytes", Entry.bytes_transmitted);
- io.mapRequired("index", Entry.packet_idx);
- io.mapRequired("tid", Entry.tid);
-}
-
-StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
- IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
- if (Entry.bytes_transmitted != Entry.packet.data.size())
- return "BinaryData size doesn't match bytes transmitted";
-
- return {};
-}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index 85f112b50623..c006fbd34a4b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/lldb-public.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
@@ -25,46 +26,17 @@ class GDBRemoteCommunicationHistory {
public:
friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>;
- enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
-
- /// Entry in the ring buffer containing the packet data, its type, size and
- /// index. Entries can be serialized to file.
- struct Entry {
- Entry()
- : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
- packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
-
- void Clear() {
- packet.data.clear();
- type = ePacketTypeInvalid;
- bytes_transmitted = 0;
- packet_idx = 0;
- tid = LLDB_INVALID_THREAD_ID;
- }
-
- struct BinaryData {
- std::string data;
- };
-
- void Serialize(llvm::raw_ostream &strm) const;
-
- BinaryData packet;
- PacketType type;
- uint32_t bytes_transmitted;
- uint32_t packet_idx;
- lldb::tid_t tid;
- };
-
GDBRemoteCommunicationHistory(uint32_t size = 0);
~GDBRemoteCommunicationHistory();
// For single char packets for ack, nack and /x03
- void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted);
-
- void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+ void AddPacket(char packet_char, GDBRemotePacket::Type type,
uint32_t bytes_transmitted);
+ void AddPacket(const std::string &src, uint32_t src_len,
+ GDBRemotePacket::Type type, uint32_t bytes_transmitted);
+
void Dump(Stream &strm) const;
void Dump(Log *log) const;
bool DidDumpToLog() const { return m_dumped_to_log; }
@@ -97,7 +69,7 @@ private:
return m_packets.empty() ? 0 : i % m_packets.size();
}
- std::vector<Entry> m_packets;
+ std::vector<GDBRemotePacket> m_packets;
uint32_t m_curr_idx;
uint32_t m_total_packet_count;
mutable bool m_dumped_to_log;
@@ -107,49 +79,4 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry)
-
-namespace llvm {
-namespace yaml {
-
-template <>
-struct ScalarEnumerationTraits<lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::PacketType> {
- static void enumeration(IO &io,
- lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::PacketType &value);
-};
-
-template <>
-struct ScalarTraits<lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::Entry::BinaryData> {
- static void output(const lldb_private::process_gdb_remote::
- GDBRemoteCommunicationHistory::Entry::BinaryData &,
- void *, raw_ostream &);
-
- static StringRef
- input(StringRef, void *,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry::
- BinaryData &);
-
- static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
-};
-
-template <>
-struct MappingTraits<
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> {
- static void
- mapping(IO &io,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry
- &Entry);
-
- static StringRef validate(
- IO &io,
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &);
-};
-
-} // namespace yaml
-} // namespace llvm
-
#endif // liblldb_GDBRemoteCommunicationHistory_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 417f5737a30f..2d26c550dc76 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -9,6 +9,7 @@
#include <errno.h>
#include "lldb/Host/Config.h"
+#include "llvm/ADT/ScopeExit.h"
#include "GDBRemoteCommunicationReplayServer.h"
#include "ProcessGDBRemoteLog.h"
@@ -127,7 +128,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
while (!m_packet_history.empty()) {
// Pop last packet from the history.
- GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
+ GDBRemotePacket entry = m_packet_history.back();
m_packet_history.pop_back();
// We've handled the handshake implicitly before. Skip the packet and move
@@ -135,7 +136,7 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
if (entry.packet.data == "+")
continue;
- if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeSend) {
+ if (entry.type == GDBRemotePacket::ePacketTypeSend) {
if (unexpected(entry.packet.data, packet.GetStringRef())) {
LLDB_LOG(log,
"GDBRemoteCommunicationReplayServer expected packet: '{0}'",
@@ -149,14 +150,14 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
// Ignore QEnvironment packets as they're handled earlier.
if (entry.packet.data.find("QEnvironment") == 1) {
assert(m_packet_history.back().type ==
- GDBRemoteCommunicationHistory::ePacketTypeRecv);
+ GDBRemotePacket::ePacketTypeRecv);
m_packet_history.pop_back();
}
continue;
}
- if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeInvalid) {
+ if (entry.type == GDBRemotePacket::ePacketTypeInvalid) {
LLDB_LOG(
log,
"GDBRemoteCommunicationReplayServer skipped invalid packet: '{0}'",
@@ -175,10 +176,6 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
return packet_result;
}
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
- std::vector<
- lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>)
-
llvm::Error
GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
auto error_or_file = MemoryBuffer::getFile(path.GetPath());
@@ -256,11 +253,10 @@ void GDBRemoteCommunicationReplayServer::ReceivePacket(
thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
GDBRemoteCommunicationReplayServer *server =
(GDBRemoteCommunicationReplayServer *)arg;
-
+ auto D = make_scope_exit([&]() { server->Disconnect(); });
EventSP event_sp;
bool done = false;
-
- while (true) {
+ while (!done) {
if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index 26d65e265463..0b5e910f7c6a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -62,7 +62,7 @@ protected:
static lldb::thread_result_t AsyncThread(void *arg);
/// Replay history with the oldest packet at the end.
- std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history;
+ std::vector<GDBRemotePacket> m_packet_history;
/// Server thread.
Broadcaster m_async_broadcaster;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 49cbeb023fd5..ac6ecffcf854 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -59,14 +59,13 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse(
break;
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
break;
default:
auto handler_it = m_packet_handlers.find(packet_type);
if (handler_it == m_packet_handlers.end())
- packet_result =
- SendUnimplementedResponse(packet.GetStringRef().c_str());
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
else
packet_result = handler_it->second(packet, error, interrupt, quit);
break;
@@ -139,10 +138,9 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendIllFormedResponse(
const StringExtractorGDBRemote &failed_packet, const char *message) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (log)
- log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
- __FUNCTION__, failed_packet.GetStringRef().c_str(),
- message ? message : "");
+ LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
+ __FUNCTION__, failed_packet.GetStringRef().data(),
+ message ? message : "");
return SendErrorResponse(0x03);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index d095c7a057ad..37980d914dc2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -29,12 +29,13 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/JSON.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
@@ -43,11 +44,10 @@
#include "lldb/Host/android/HostInfoAndroid.h"
#endif
-#include "llvm/ADT/StringSwitch.h"
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
#ifdef __ANDROID__
const static uint32_t g_default_packet_timeout_sec = 20; // seconds
@@ -231,6 +231,7 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
#else
if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
+ host_arch.GetMachine() == llvm::Triple::aarch64_32 ||
host_arch.GetMachine() == llvm::Triple::aarch64_be ||
host_arch.GetMachine() == llvm::Triple::arm ||
host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
@@ -260,6 +261,15 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
response.PutChar(';');
}
+#if defined(__APPLE__)
+ llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
+ if (!maccatalyst_version.empty()) {
+ response.Format("maccatalyst_version:{0}",
+ maccatalyst_version.getAsString());
+ response.PutChar(';');
+ }
+#endif
+
std::string s;
if (HostInfo::GetOSBuildString(s)) {
response.PutCString("os_build:");
@@ -421,8 +431,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
// Packet format: "qUserName:%i" where %i is the uid
packet.SetFilePos(::strlen("qUserName:"));
@@ -435,8 +444,7 @@ GDBRemoteCommunicationServerCommon::Handle_qUserName(
return SendPacketNoLock(response.GetString());
}
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
#endif
return SendErrorResponse(5);
}
@@ -500,19 +508,32 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
packet.GetHexByteStringTerminatedBy(path, ',');
if (!path.empty()) {
if (packet.GetChar() == ',') {
- uint32_t flags = packet.GetHexMaxU32(false, 0);
+ // FIXME
+ // The flag values for OpenOptions do not match the values used by GDB
+ // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
+ // * rdar://problem/46788934
+ auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
if (packet.GetChar() == ',') {
mode_t mode = packet.GetHexMaxU32(false, 0600);
FileSpec path_spec(path);
FileSystem::Instance().Resolve(path_spec);
- File file;
// Do not close fd.
- Status error =
- FileSystem::Instance().Open(file, path_spec, flags, mode, false);
- const int save_errno = error.GetError();
+ auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);
+
+ int save_errno = 0;
+ int descriptor = File::kInvalidDescriptor;
+ if (file) {
+ descriptor = file.get()->GetDescriptor();
+ } else {
+ std::error_code code = errorToErrorCode(file.takeError());
+ if (code.category() == std::system_category()) {
+ save_errno = code.value();
+ }
+ }
+
StreamString response;
response.PutChar('F');
- response.Printf("%i", file.GetDescriptor());
+ response.Printf("%i", descriptor);
if (save_errno)
response.Printf(",%i", save_errno);
return SendPacketNoLock(response.GetString());
@@ -530,7 +551,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
int err = -1;
int save_errno = 0;
if (fd >= 0) {
- File file(fd, true);
+ NativeFile file(fd, File::OpenOptions(0), true);
Status error = file.Close();
err = 0;
save_errno = error.GetError();
@@ -552,16 +573,16 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
packet.SetFilePos(::strlen("vFile:pread:"));
int fd = packet.GetS32(-1);
if (packet.GetChar() == ',') {
- size_t count = packet.GetU64(UINT64_MAX);
+ size_t count = packet.GetU64(SIZE_MAX);
if (packet.GetChar() == ',') {
off_t offset = packet.GetU64(UINT32_MAX);
- if (count == UINT64_MAX) {
+ if (count == SIZE_MAX) {
response.Printf("F-1:%i", EINVAL);
return SendPacketNoLock(response.GetString());
}
std::string buffer(count, 0);
- File file(fd, false);
+ NativeFile file(fd, File::eOpenOptionRead, false);
Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
const ssize_t bytes_read = error.Success() ? count : -1;
const int save_errno = error.GetError();
@@ -593,7 +614,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
if (packet.GetChar() == ',') {
std::string buffer;
if (packet.GetEscapedBinaryData(buffer)) {
- File file(fd, false);
+ NativeFile file(fd, File::eOpenOptionWrite, false);
size_t count = buffer.size();
Status error =
file.Write(static_cast<const void *>(&buffer[0]), count, offset);
@@ -825,6 +846,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported(
#if defined(__linux__) || defined(__NetBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
+ response.PutCString(";qXfer:libraries-svr4:read+");
#endif
return SendPacketNoLock(response.GetString());
@@ -1016,9 +1038,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
m_process_launch_info.GetExecutableFile().SetFile(
arg, FileSpec::Style::native);
m_process_launch_info.GetArguments().AppendArgument(arg);
- if (log)
- log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
- __FUNCTION__, actual_arg_index, arg.c_str());
+ LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
+ __FUNCTION__, actual_arg_index, arg.c_str());
++actual_arg_index;
}
}
@@ -1104,6 +1125,8 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
StringExtractorGDBRemote &packet) {
+ namespace json = llvm::json;
+
packet.SetFilePos(::strlen("jModulesInfo:"));
StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
@@ -1114,7 +1137,7 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
if (!packet_array)
return SendErrorResponse(2);
- JSONArray::SP response_array_sp = std::make_shared<JSONArray>();
+ json::Array response_array;
for (size_t i = 0; i < packet_array->GetSize(); ++i) {
StructuredData::Dictionary *query =
packet_array->GetItemAtIndex(i)->GetAsDictionary();
@@ -1132,27 +1155,22 @@ GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
const auto file_offset = matched_module_spec.GetObjectOffset();
const auto file_size = matched_module_spec.GetObjectSize();
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
-
if (uuid_str.empty())
continue;
-
- JSONObject::SP response = std::make_shared<JSONObject>();
- response_array_sp->AppendObject(response);
- response->SetObject("uuid", std::make_shared<JSONString>(uuid_str));
- response->SetObject(
- "triple",
- std::make_shared<JSONString>(
- matched_module_spec.GetArchitecture().GetTriple().getTriple()));
- response->SetObject("file_path",
- std::make_shared<JSONString>(
- matched_module_spec.GetFileSpec().GetPath()));
- response->SetObject("file_offset",
- std::make_shared<JSONNumber>(file_offset));
- response->SetObject("file_size", std::make_shared<JSONNumber>(file_size));
+ const auto triple_str =
+ matched_module_spec.GetArchitecture().GetTriple().getTriple();
+ const auto file_path = matched_module_spec.GetFileSpec().GetPath();
+
+ json::Object response{{"uuid", uuid_str},
+ {"triple", triple_str},
+ {"file_path", file_path},
+ {"file_offset", static_cast<int64_t>(file_offset)},
+ {"file_size", static_cast<int64_t>(file_size)}};
+ response_array.push_back(std::move(response));
}
StreamString response;
- response_array_sp->Write(response);
+ response.AsRawOstream() << std::move(response_array);
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetString().data(),
response.GetSize());
@@ -1168,6 +1186,15 @@ void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
response.PutCString("name:");
response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+
+ response.PutChar(';');
+ response.PutCString("args:");
+ response.PutStringAsRawHex8(proc_info.GetArg0());
+ for (auto &arg : proc_info.GetArguments()) {
+ response.PutChar('-');
+ response.PutStringAsRawHex8(arg.ref());
+ }
+
response.PutChar(';');
const ArchSpec &proc_arch = proc_info.GetArchitecture();
if (proc_arch.IsValid()) {
@@ -1217,6 +1244,7 @@ void GDBRemoteCommunicationServerCommon::
case llvm::Triple::arm:
case llvm::Triple::thumb:
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
ostype = "ios";
break;
default:
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 196607665bba..ad1a39b57969 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -11,7 +11,7 @@
#include "lldb/Host/Config.h"
#include "GDBRemoteCommunicationServerLLGS.h"
-#include "lldb/Utility/StreamGDBRemote.h"
+#include "lldb/Utility/GDBRemote.h"
#include <chrono>
#include <cstring>
@@ -32,7 +32,6 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
@@ -40,6 +39,7 @@
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UriParser.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/ScopedPrinter.h"
#include "ProcessGDBRemote.h"
@@ -217,8 +217,13 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
if (should_forward_stdio) {
+ // Temporarily relax the following for Windows until we can take advantage
+ // of the recently added pty support. This doesn't really affect the use of
+ // lldb-server on Windows.
+#if !defined(_WIN32)
if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection())
return Status(std::move(Err));
+#endif
}
{
@@ -249,18 +254,18 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
// Setup stdout/stderr mapping from inferior to $O
auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
- "inferior STDIO fd to %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
Status status = SetSTDIOFileDescriptor(terminal_fd);
if (status.Fail())
return status;
} else {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
- "inferior STDIO since terminal fd reported as %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
} else {
LLDB_LOG(log,
@@ -278,9 +283,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
+ __FUNCTION__, pid);
// Before we try to attach, make sure we aren't already monitoring something
// else.
@@ -304,18 +308,18 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
// Setup stdout/stderr mapping from inferior.
auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
if (terminal_fd >= 0) {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
- "inferior STDIO fd to %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
Status status = SetSTDIOFileDescriptor(terminal_fd);
if (status.Fail())
return status;
} else {
- if (log)
- log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
- "inferior STDIO since terminal fd reported as %d",
- __FUNCTION__, terminal_fd);
+ LLDB_LOGF(log,
+ "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
printf("Attached to process %" PRIu64 "...\n", pid);
@@ -327,10 +331,11 @@ void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
- "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
- __FUNCTION__, process->GetID(),
- StateAsCString(process->GetState()));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
+ __FUNCTION__, process->GetID(),
+ StateAsCString(process->GetState()));
}
}
@@ -397,19 +402,21 @@ static void WriteRegisterValueInHexFixedWidth(
}
}
-static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
+static llvm::Expected<json::Object>
+GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
- JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+ json::Object register_object;
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
// Expedite all registers in the first register set (i.e. should be GPRs)
// that are not contained in other registers.
const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
if (!reg_set_p)
- return nullptr;
+ return llvm::make_error<llvm::StringError>("failed to get registers",
+ llvm::inconvertibleErrorCode());
for (const uint32_t *reg_num_p = reg_set_p->registers;
*reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
uint32_t reg_num = *reg_num_p;
@@ -431,10 +438,9 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
const RegisterInfo *const reg_info_p =
reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
- if (log)
- log->Printf(
- "%s failed to get register info for register index %" PRIu32,
- __FUNCTION__, reg_num);
+ LLDB_LOGF(log,
+ "%s failed to get register info for register index %" PRIu32,
+ __FUNCTION__, reg_num);
continue;
}
@@ -445,11 +451,10 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
RegisterValue reg_value;
Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
- reg_num, error.AsCString());
+ LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_num, error.AsCString());
continue;
}
@@ -457,12 +462,11 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
&reg_value, lldb::eByteOrderBig);
- register_object_sp->SetObject(
- llvm::to_string(reg_num),
- std::make_shared<JSONString>(stream.GetString()));
+ register_object.try_emplace(llvm::to_string(reg_num),
+ stream.GetString().str());
}
- return register_object_sp;
+ return register_object;
}
static const char *GetStopReasonString(StopReason stop_reason) {
@@ -489,11 +493,11 @@ static const char *GetStopReasonString(StopReason stop_reason) {
return nullptr;
}
-static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
- bool abridged) {
+static llvm::Expected<json::Array>
+GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
+ json::Array threads_array;
// Ensure we can get info on the given thread.
uint32_t thread_idx = 0;
@@ -507,61 +511,62 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
struct ThreadStopInfo tid_stop_info;
std::string description;
if (!thread->GetStopReason(tid_stop_info, description))
- return nullptr;
+ return llvm::make_error<llvm::StringError>(
+ "failed to get stop reason", llvm::inconvertibleErrorCode());
const int signum = tid_stop_info.details.signal.signo;
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " tid %" PRIu64
- " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
- __FUNCTION__, process.GetID(), tid, signum,
- tid_stop_info.reason, tid_stop_info.details.exception.type);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, process.GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
}
- JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
- threads_array_sp->AppendObject(thread_obj_sp);
+ json::Object thread_obj;
if (!abridged) {
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread))
- thread_obj_sp->SetObject("registers", registers_sp);
+ if (llvm::Expected<json::Object> registers =
+ GetRegistersAsJSON(*thread)) {
+ thread_obj.try_emplace("registers", std::move(*registers));
+ } else {
+ return registers.takeError();
+ }
}
- thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+ thread_obj.try_emplace("tid", static_cast<int64_t>(tid));
+
if (signum != 0)
- thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
+ thread_obj.try_emplace("signal", signum);
const std::string thread_name = thread->GetName();
if (!thread_name.empty())
- thread_obj_sp->SetObject("name",
- std::make_shared<JSONString>(thread_name));
+ thread_obj.try_emplace("name", thread_name);
- if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
- thread_obj_sp->SetObject("reason",
- std::make_shared<JSONString>(stop_reason_str));
+ const char *stop_reason = GetStopReasonString(tid_stop_info.reason);
+ if (stop_reason)
+ thread_obj.try_emplace("reason", stop_reason);
if (!description.empty())
- thread_obj_sp->SetObject("description",
- std::make_shared<JSONString>(description));
+ thread_obj.try_emplace("description", description);
if ((tid_stop_info.reason == eStopReasonException) &&
tid_stop_info.details.exception.type) {
- thread_obj_sp->SetObject(
- "metype",
- std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
+ thread_obj.try_emplace(
+ "metype", static_cast<int64_t>(tid_stop_info.details.exception.type));
- JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
+ json::Array medata_array;
for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
++i) {
- medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
- tid_stop_info.details.exception.data[i]));
+ medata_array.push_back(
+ static_cast<int64_t>(tid_stop_info.details.exception.data[i]));
}
- thread_obj_sp->SetObject("medata", medata_array_sp);
+ thread_obj.try_emplace("medata", std::move(medata_array));
}
-
- // TODO: Expedite interesting regions of inferior memory
+ threads_array.push_back(std::move(thread_obj));
}
-
- return threads_array_sp;
+ return threads_array;
}
GDBRemoteCommunication::PacketResult
@@ -653,19 +658,21 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
// is hex ascii JSON that contains the thread IDs thread stop info only for
// threads that have stop reasons. Only send this if we have more than one
// thread otherwise this packet has all the info it needs.
- if (thread_index > 0) {
+ if (thread_index > 1) {
const bool threads_with_valid_stop_info_only = true;
- JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
+ llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
*m_debugged_process_up, threads_with_valid_stop_info_only);
- if (threads_info_sp) {
+ if (threads_info) {
response.PutCString("jstopinfo:");
StreamString unescaped_response;
- threads_info_sp->Write(unescaped_response);
+ unescaped_response.AsRawOstream() << std::move(*threads_info);
response.PutStringAsRawHex8(unescaped_response.GetData());
response.PutChar(';');
- } else
- LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}",
- m_debugged_process_up->GetID());
+ } else {
+ LLDB_LOG(log, "failed to prepare a jstopinfo field for pid {0}:",
+ m_debugged_process_up->GetID(),
+ llvm::toString(threads_info.takeError()));
+ }
}
uint32_t i = 0;
@@ -684,12 +691,10 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
RegisterValue reg_value;
Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- reg_to_read, error.AsCString());
+ LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_to_read, error.AsCString());
continue;
}
@@ -713,25 +718,24 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
const RegisterSet *reg_set_p;
if (reg_ctx.GetRegisterSetCount() > 0 &&
((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
for (const uint32_t *reg_num_p = reg_set_p->registers;
*reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
const RegisterInfo *const reg_info_p =
reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
if (reg_info_p == nullptr) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
} else if (reg_info_p->value_regs == nullptr) {
// Only expediate registers that are not contained in other registers.
RegisterValue reg_value;
@@ -742,13 +746,12 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
&reg_value, lldb::eByteOrderBig);
response.PutChar(';');
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- *reg_num_p, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__,
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
}
}
}
@@ -787,15 +790,14 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
PacketResult result = SendStopReasonForState(StateType::eStateExited);
if (result != PacketResult::Success) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
- "notification for PID %" PRIu64 ", state: eStateExited",
- __FUNCTION__, process->GetID());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
}
// Close the pipe to the inferior terminal i/o if we launched it and set one
@@ -812,8 +814,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Send the stop reason unless this is the stop after the launch or attach.
switch (m_inferior_prev_state) {
@@ -825,10 +826,10 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
// In all other cases, send the stop reason.
PacketResult result = SendStopReasonForState(StateType::eStateStopped);
if (result != PacketResult::Success) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
- "notification for PID %" PRIu64 ", state: eStateExited",
- __FUNCTION__, process->GetID());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
}
break;
}
@@ -839,9 +840,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
assert(process && "process cannot be NULL");
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
- "NativeProcessProtocol pid %" PRIu64 ", state: %s",
- __FUNCTION__, process->GetID(), StateAsCString(state));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
switch (state) {
@@ -868,9 +870,10 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
default:
if (log) {
- log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
- "change for pid %" PRIu64 ", new state: %s",
- __FUNCTION__, process->GetID(), StateAsCString(state));
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+ "change for pid %" PRIu64 ", new state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
break;
}
@@ -888,10 +891,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
if (!m_handshake_completed) {
if (!HandshakeWithClient()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with "
- "client failed, exiting",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s handshake with "
+ "client failed, exiting",
+ __FUNCTION__);
m_mainloop.RequestTermination();
return;
}
@@ -908,10 +911,10 @@ void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
break; // No more packets in the queue
if ((result != PacketResult::Success)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet "
- "failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s processing a packet "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
m_mainloop.RequestTermination();
break;
}
@@ -982,9 +985,10 @@ void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
// Not much we can do about the failure. Log it and continue without
// forwarding.
if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
- "forwarding: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
+ "forwarding: %s",
+ __FUNCTION__, error.AsCString());
}
}
@@ -1008,10 +1012,11 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
case eConnectionStatusError:
case eConnectionStatusNoConnection:
if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
- "forwarding as communication returned status %d (error: "
- "%s)",
- __FUNCTION__, status, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
+ "forwarding as communication returned status %d (error: "
+ "%s)",
+ __FUNCTION__, status, error.AsCString());
m_stdio_handle_up.reset();
return;
@@ -1349,15 +1354,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
// Ensure we have a native process.
if (!m_debugged_process_up) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
- "shared pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
return SendErrorResponse(0x36);
}
@@ -1376,13 +1380,14 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
if (packet.GetBytesLeft() > 0) {
// FIXME add continue at address support for $C{signo}[;{continue-address}].
if (*packet.Peek() == ';')
- return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.GetStringRef().data());
else
return SendIllFormedResponse(
packet, "unexpected content after $C{signal-number}");
}
- ResumeActionList resume_actions(StateType::eStateRunning, 0);
+ ResumeActionList resume_actions(StateType::eStateRunning,
+ LLDB_INVALID_SIGNAL_NUMBER);
Status error;
// We have two branches: what to do if a continue thread is specified (in
@@ -1430,8 +1435,7 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
@@ -1440,20 +1444,21 @@ GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
if (has_continue_address) {
LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]",
packet.Peek());
- return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ return SendUnimplementedResponse(packet.GetStringRef().data());
}
// Ensure we have a native process.
if (!m_debugged_process_up) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
- "shared pointer",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
return SendErrorResponse(0x36);
}
// Build the ResumeActionList
- ResumeActionList actions(StateType::eStateRunning, 0);
+ ResumeActionList actions(StateType::eStateRunning,
+ LLDB_INVALID_SIGNAL_NUMBER);
Status error = m_debugged_process_up->Resume(actions);
if (error.Fail()) {
@@ -1480,17 +1485,16 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vCont(
StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
+ __FUNCTION__);
packet.SetFilePos(::strlen("vCont"));
if (packet.GetBytesLeft() == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from "
- "vCont package",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s missing action from "
+ "vCont package",
+ __FUNCTION__);
return SendIllFormedResponse(packet, "Missing action from vCont package");
}
@@ -1521,7 +1525,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont(
ResumeAction thread_action;
thread_action.tid = LLDB_INVALID_THREAD_ID;
thread_action.state = eStateInvalid;
- thread_action.signal = 0;
+ thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER;
const char action = packet.GetChar();
switch (action) {
@@ -1958,10 +1962,10 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
const uint32_t reg_index =
packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
if (reg_index == std::numeric_limits<uint32_t>::max()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse register number from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x15);
}
@@ -1978,20 +1982,19 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
// Return the end of registers response if we've iterated one past the end of
// the register set.
if (reg_index >= reg_context.GetUserRegisterCount()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index,
- reg_context.GetUserRegisterCount());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x15);
}
const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " returned NULL",
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x15);
}
@@ -2002,20 +2005,20 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
RegisterValue reg_value;
Status error = reg_context.ReadRegister(reg_info, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
- "requested register %" PRIu32 " (%s) failed: %s",
- __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, read of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
return SendErrorResponse(0x15);
}
const uint8_t *const data =
reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
if (!data) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data "
- "bytes from requested register %" PRIu32,
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to get data "
+ "bytes from requested register %" PRIu32,
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x15);
}
@@ -2039,10 +2042,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
const uint32_t reg_index =
packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
if (reg_index == std::numeric_limits<uint32_t>::max()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse register number from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x29);
}
@@ -2058,10 +2061,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Get the thread to use.
NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
if (!thread) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
- "available (thread index 0)",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no thread "
+ "available (thread index 0)",
+ __FUNCTION__);
return SendErrorResponse(0x28);
}
@@ -2069,20 +2072,20 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
NativeRegisterContext &reg_context = thread->GetRegisterContext();
const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " returned NULL",
- __FUNCTION__, reg_index);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
return SendErrorResponse(0x48);
}
// Return the end of registers response if we've iterated one past the end of
// the register set.
if (reg_index >= reg_context.GetUserRegisterCount()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
- "register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x47);
}
@@ -2101,10 +2104,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
m_debugged_process_up->GetArchitecture().GetByteOrder());
Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
- "requested register %" PRIu32 " (%s) failed: %s",
- __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, write of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
return SendErrorResponse(0x32);
}
@@ -2118,20 +2121,20 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
// Parse out which variant of $H is requested.
packet.SetFilePos(strlen("H"));
if (packet.GetBytesLeft() < 1) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command "
- "missing {g,c} variant",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, H command "
+ "missing {g,c} variant",
+ __FUNCTION__);
return SendIllFormedResponse(packet, "H command missing {g,c} variant");
}
@@ -2144,10 +2147,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
break;
default:
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
- __FUNCTION__, h_variant);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
+ __FUNCTION__, h_variant);
return SendIllFormedResponse(packet,
"H variant unsupported, should be c or g");
}
@@ -2162,10 +2165,10 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
if (!thread) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
- " not found",
- __FUNCTION__, tid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
+ " not found",
+ __FUNCTION__, tid);
return SendErrorResponse(0x15);
}
}
@@ -2196,10 +2199,10 @@ GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2257,10 +2260,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2284,10 +2287,10 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
if (byte_count == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
- "zero-length packet",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+ "zero-length packet",
+ __FUNCTION__);
return SendOKResponse();
}
@@ -2301,20 +2304,20 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
Status error = m_debugged_process_up->ReadMemoryWithoutTrap(
read_addr, &buf[0], byte_count, bytes_read);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " mem 0x%" PRIx64 ": failed to read. Error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to read. Error: %s",
+ __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+ error.AsCString());
return SendErrorResponse(0x08);
}
if (bytes_read == 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
- __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
- byte_count);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+ byte_count);
return SendErrorResponse(0x08);
}
@@ -2338,10 +2341,10 @@ GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2426,10 +2429,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
// since we won't have a NativeProcessProtocol.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2454,10 +2457,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
// Ensure we have a process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -2703,10 +2706,10 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Ensure we have a process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x32);
}
@@ -2725,7 +2728,7 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
return SendErrorResponse(0x33);
// Create the step action for the given thread.
- ResumeAction action = {tid, eStateStepping, 0};
+ ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER};
// Setup the actions list.
ResumeActionList actions;
@@ -2735,11 +2738,11 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
Status error = m_debugged_process_up->Resume(actions);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " tid %" PRIu64 " Resume() failed with error: %s",
- __FUNCTION__, m_debugged_process_up->GetID(), tid,
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64 " Resume() failed with error: %s",
+ __FUNCTION__, m_debugged_process_up->GetID(), tid,
+ error.AsCString());
return SendErrorResponse(0x49);
}
@@ -2765,6 +2768,24 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
return std::move(*buffer_or_error);
}
+ if (object == "libraries-svr4") {
+ auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries();
+ if (!library_list)
+ return library_list.takeError();
+
+ StreamString response;
+ response.Printf("<library-list-svr4 version=\"1.0\">");
+ for (auto const &library : *library_list) {
+ response.Printf("<library name=\"%s\" ",
+ XMLEncodeAttributeValue(library.name.c_str()).c_str());
+ response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map);
+ response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr);
+ response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr);
+ }
+ response.Printf("</library-list-svr4>");
+ return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
+ }
+
return llvm::make_error<PacketUnimplementedError>(
"Xfer object not supported");
}
@@ -2968,18 +2989,18 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
"vAttach failed to parse the process id");
// Attempt to attach.
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
- "pid %" PRIu64,
- __FUNCTION__, pid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
+ "pid %" PRIu64,
+ __FUNCTION__, pid);
Status error = AttachToProcess(pid);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
- "pid %" PRIu64 ": %s\n",
- __FUNCTION__, pid, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to attach to "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, pid, error.AsCString());
return SendErrorResponse(error);
}
@@ -2996,10 +3017,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
if (!m_debugged_process_up ||
(m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
- __FUNCTION__);
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
return SendErrorResponse(0x15);
}
@@ -3023,11 +3044,10 @@ GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
const Status error = m_debugged_process_up->Detach();
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
- "pid %" PRIu64 ": %s\n",
- __FUNCTION__, m_debugged_process_up->GetID(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString());
return SendErrorResponse(0x01);
}
@@ -3042,10 +3062,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
packet.SetFilePos(strlen("qThreadStopInfo"));
const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
if (tid == LLDB_INVALID_THREAD_ID) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
- "parse thread id from request \"%s\"",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse thread id from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().data());
return SendErrorResponse(0x15);
}
return SendStopReplyPacketForThread(tid);
@@ -3064,15 +3084,16 @@ GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
StreamString response;
const bool threads_with_valid_stop_info_only = false;
- JSONArray::SP threads_array_sp = GetJSONThreadsInfo(
+ llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo(
*m_debugged_process_up, threads_with_valid_stop_info_only);
- if (!threads_array_sp) {
- LLDB_LOG(log, "failed to prepare a packet for pid {0}",
- m_debugged_process_up->GetID());
+ if (!threads_info) {
+ LLDB_LOG(log, "failed to prepare a packet for pid {0}: {1}",
+ m_debugged_process_up->GetID(),
+ llvm::toString(threads_info.takeError()));
return SendErrorResponse(52);
}
- threads_array_sp->Write(response);
+ response.AsRawOstream() << *threads_info;
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
return SendPacketNoLock(escaped_response.GetString());
@@ -3177,15 +3198,15 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
connection->Disconnect(&error);
if (error.Success()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
- "terminal stdio - SUCCESS",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - SUCCESS",
+ __FUNCTION__);
} else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
- "terminal stdio - FAIL: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - FAIL: %s",
+ __FUNCTION__, error.AsCString());
}
}
}
@@ -3215,11 +3236,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
// Parse out the ';'.
if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
- "error: expected ';' prior to start of thread suffix: packet "
- "contents = '%s'",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected ';' prior to start of thread suffix: packet "
+ "contents = '%s'",
+ __FUNCTION__, packet.GetStringRef().data());
return nullptr;
}
@@ -3228,11 +3249,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
// Parse out thread: portion.
if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
- "error: expected 'thread:' but not found, packet contents = "
- "'%s'",
- __FUNCTION__, packet.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected 'thread:' but not found, packet contents = "
+ "'%s'",
+ __FUNCTION__, packet.GetStringRef().data());
return nullptr;
}
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
@@ -3283,3 +3304,28 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
}
+
+std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
+ llvm::StringRef value) {
+ std::string result;
+ for (const char &c : value) {
+ switch (c) {
+ case '\'':
+ result += "&apos;";
+ break;
+ case '"':
+ result += "&quot;";
+ break;
+ case '<':
+ result += "&lt;";
+ break;
+ case '>':
+ result += "&gt;";
+ break;
+ default:
+ result += c;
+ break;
+ }
+ }
+ return result;
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 068ea52caaaf..088ba92ad11a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -196,6 +196,8 @@ protected:
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
ReadXferObject(llvm::StringRef object, llvm::StringRef annex);
+ static std::string XMLEncodeAttributeValue(llvm::StringRef value);
+
private:
void HandleInferiorState_Exited(NativeProcessProtocol *process);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 6deb75f2f021..25cebbba8f7b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -15,8 +15,10 @@
#include <cstring>
#include <mutex>
#include <sstream>
+#include <thread>
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/Threading.h"
#include "lldb/Host/Config.h"
@@ -26,9 +28,8 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UriParser.h"
@@ -36,8 +37,8 @@
#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
-using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private;
// GDBRemoteCommunicationServerPlatform constructor
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
@@ -104,8 +105,8 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
hostname = "127.0.0.1";
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+ LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
+ port);
// Do not run in a new session so that it can not linger after the platform
// closes.
@@ -161,9 +162,8 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
// process...
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
- __FUNCTION__);
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerPlatform::%s() called",
+ __FUNCTION__);
ConnectionFileDescriptor file_conn;
std::string hostname;
@@ -183,17 +183,17 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
Status error =
LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
if (error.Fail()) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
- "launch failed: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launch failed: %s",
+ __FUNCTION__, error.AsCString());
return SendErrorResponse(9);
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
- "launched successfully as pid %" PRIu64,
- __FUNCTION__, debugserver_pid);
+ LLDB_LOGF(log,
+ "GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launched successfully as pid %" PRIu64,
+ __FUNCTION__, debugserver_pid);
StreamGDBRemote response;
response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
@@ -215,22 +215,21 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
StringExtractorGDBRemote &packet) {
+ namespace json = llvm::json;
+
if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
return SendErrorResponse(4);
- JSONObject::SP server_sp = std::make_shared<JSONObject>();
- server_sp->SetObject("port",
- std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+ json::Object server{{"port", m_pending_gdb_server.port}};
+
if (!m_pending_gdb_server.socket_name.empty())
- server_sp->SetObject(
- "socket_name",
- std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+ server.try_emplace("socket_name", m_pending_gdb_server.socket_name);
- JSONArray server_list;
- server_list.AppendObject(server_sp);
+ json::Array server_list;
+ server_list.push_back(std::move(server));
StreamGDBRemote response;
- server_list.Write(response);
+ response.AsRawOstream() << std::move(server_list);
StreamGDBRemote escaped_response;
escaped_response.PutEscapedBytes(response.GetString().data(),
@@ -281,10 +280,9 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
return true;
}
}
- usleep(10000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
- // check one more time after the final usleep
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
@@ -303,10 +301,10 @@ bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
return true;
}
}
- usleep(10000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
- // check one more time after the final usleep Scope for locker
+ // check one more time after the final sleep
{
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index a77e659a55fa..c06c9527708e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -206,11 +206,14 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
} else {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
GDBR_LOG_PACKETS));
- if (log)
- log->Printf ("error: GDBRemoteRegisterContext::ReadRegisterBytes tried to read the "
- "entire register context at once, expected at least %" PRId64 " bytes "
- "but only got %" PRId64 " bytes.", m_reg_data.GetByteSize(),
- buffer_sp->GetByteSize());
+ LLDB_LOGF(
+ log,
+ "error: GDBRemoteRegisterContext::ReadRegisterBytes tried "
+ "to read the "
+ "entire register context at once, expected at least %" PRId64
+ " bytes "
+ "but only got %" PRId64 " bytes.",
+ m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
}
}
return false;
@@ -390,13 +393,15 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write register for \"%s\":\n%s",
- reg_info->name, strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\":\n%s",
+ reg_info->name, strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write register for \"%s\"",
- reg_info->name);
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\"",
+ reg_info->name);
}
}
}
@@ -494,12 +499,14 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "read all registers:\n%s",
- strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "read all registers:\n%s",
+ strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "read all registers");
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "read all registers");
}
}
@@ -630,7 +637,9 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (m_thread.GetProcess().get()) {
const ArchSpec &arch =
m_thread.GetProcess()->GetTarget().GetArchitecture();
- if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
+ if (arch.IsValid() &&
+ (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::aarch64_32) &&
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
arch.GetTriple().getOS() == llvm::Triple::IOS) {
arm64_debugserver = true;
@@ -667,12 +676,14 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (log->GetVerbose()) {
StreamString strm;
gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write all registers:\n%s",
- strm.GetData());
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write all registers:\n%s",
+ strm.GetData());
} else
- log->Printf("error: failed to get packet sequence mutex, not sending "
- "write all registers");
+ LLDB_LOGF(log,
+ "error: failed to get packet sequence mutex, not sending "
+ "write all registers");
}
}
return false;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index a6fdd8dd0707..f1762abc55f8 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -63,7 +63,6 @@
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Utility/Args.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/State.h"
@@ -81,12 +80,12 @@
#include "lldb/Host/Host.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUGSERVER_BASENAME "debugserver"
-using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
@@ -99,51 +98,25 @@ namespace lldb {
// namespace. This allows you to attach with a debugger and call this function
// and get the packet history dumped to a file.
void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
- StreamFile strm;
- Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path),
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate);
- if (error.Success())
- ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
+ auto file = FileSystem::Instance().Open(
+ FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate);
+ if (!file) {
+ llvm::consumeError(file.takeError());
+ return;
+ }
+ StreamFile stream(std::move(file.get()));
+ ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream);
}
} // namespace lldb
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"packet-timeout",
- OptionValue::eTypeUInt64,
- true,
- 5
-#if defined(__has_feature)
-#if __has_feature(address_sanitizer)
- * 2
-#endif
-#endif
- ,
- nullptr,
- {},
- "Specify the default packet timeout in seconds."},
- {"target-definition-file",
- OptionValue::eTypeFileSpec,
- true,
- 0,
- nullptr,
- {},
- "The file that provides the description for remote target registers."},
- {"use-libraries-svr4",
- OptionValue::eTypeBoolean,
- true,
- false,
- nullptr,
- {},
- "If true, the libraries-svr4 feature will be used to get a hold of the "
- "process's loaded modules."}};
+#define LLDB_PROPERTIES_processgdbremote
+#include "ProcessGDBRemoteProperties.inc"
enum {
- ePropertyPacketTimeout,
- ePropertyTargetDefinitionFile,
- ePropertyUseSVR4
+#define LLDB_PROPERTIES_processgdbremote
+#include "ProcessGDBRemotePropertiesEnum.inc"
};
class PluginProperties : public Properties {
@@ -154,7 +127,7 @@ public:
PluginProperties() : Properties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_processgdbremote_properties);
}
~PluginProperties() override {}
@@ -162,7 +135,7 @@ public:
uint64_t GetPacketTimeout() {
const uint32_t idx = ePropertyPacketTimeout;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_processgdbremote_properties[idx].default_uint_value);
}
bool SetPacketTimeout(uint64_t timeout) {
@@ -178,7 +151,8 @@ public:
bool GetUseSVR4() const {
const uint32_t idx = ePropertyUseSVR4;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx,
+ g_processgdbremote_properties[idx].default_uint_value != 0);
}
};
@@ -191,45 +165,6 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-class ProcessGDBRemoteProvider
- : public repro::Provider<ProcessGDBRemoteProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
- }
-
- raw_ostream *GetHistoryStream() {
- FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
-
- std::error_code EC;
- m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
- sys::fs::OpenFlags::F_Text);
- return m_stream_up.get();
- }
-
- void SetCallback(std::function<void()> callback) {
- m_callback = std::move(callback);
- }
-
- void Keep() override { m_callback(); }
-
- void Discard() override { m_callback(); }
-
- static char ID;
-
-private:
- std::function<void()> m_callback;
- std::unique_ptr<raw_fd_ostream> m_stream_up;
-};
-
-char ProcessGDBRemoteProvider::ID = 0;
-const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
-const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
-
} // namespace
// TODO Randomly assigning a port is unsafe. We should get an unused
@@ -339,8 +274,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
"async thread did exit");
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
- ProcessGDBRemoteProvider &provider =
- g->GetOrCreate<ProcessGDBRemoteProvider>();
+ repro::ProcessGDBRemoteProvider &provider =
+ g->GetOrCreate<repro::ProcessGDBRemoteProvider>();
// Set the history stream to the stream owned by the provider.
m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
// Make sure to clear the stream again when we're finished.
@@ -354,10 +289,10 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
if (m_async_listener_sp->StartListeningForEvents(
&m_async_broadcaster, async_event_mask) != async_event_mask) {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for "
- "m_async_broadcaster events",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s failed to listen for "
+ "m_async_broadcaster events",
+ __FUNCTION__);
}
const uint32_t gdb_event_mask =
@@ -365,9 +300,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
if (m_async_listener_sp->StartListeningForEvents(
&m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
+ __FUNCTION__);
}
const uint64_t timeout_seconds =
@@ -785,15 +720,15 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
pid, remote_url.str().c_str());
}
- if (log)
- log->Printf("ProcessGDBRemote::%s pid %" PRIu64
- ": normalizing target architecture initial triple: %s "
- "(GetTarget().GetArchitecture().IsValid() %s, "
- "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
- __FUNCTION__, GetID(),
- GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
- GetTarget().GetArchitecture().IsValid() ? "true" : "false",
- m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s pid %" PRIu64
+ ": normalizing target architecture initial triple: %s "
+ "(GetTarget().GetArchitecture().IsValid() %s, "
+ "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
+ GetTarget().GetArchitecture().IsValid() ? "true" : "false",
+ m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
m_gdb_comm.GetHostArchitecture().IsValid()) {
@@ -805,11 +740,11 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
- if (log)
- log->Printf("ProcessGDBRemote::%s pid %" PRIu64
- ": normalized target architecture triple: %s",
- __FUNCTION__, GetID(),
- GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s pid %" PRIu64
+ ": normalized target architecture triple: %s",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
if (error.Success()) {
PlatformSP platform_sp = GetTarget().GetPlatform();
@@ -834,8 +769,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error;
- if (log)
- log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s() entered", __FUNCTION__);
uint32_t launch_flags = launch_info.GetFlags().Get();
FileSpec stdin_file_spec{};
@@ -862,15 +796,17 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
if (log) {
if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
- log->Printf("ProcessGDBRemote::%s provided with STDIO paths via "
- "launch_info: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s provided with STDIO paths via "
+ "launch_info: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
else
- log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s no STDIO paths given via launch_info",
+ __FUNCTION__);
}
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
@@ -925,24 +861,23 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
if (!stderr_file_spec)
stderr_file_spec = slave_name;
}
- if (log)
- log->Printf(
- "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
- "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ LLDB_LOGF(
+ log,
+ "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
+ "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
}
- if (log)
- log->Printf("ProcessGDBRemote::%s final STDIO paths after all "
- "adjustments: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString()
- : "<null>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s final STDIO paths after all "
+ "adjustments: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
if (stdin_file_spec)
m_gdb_comm.SetSTDIN(stdin_file_spec);
@@ -988,9 +923,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
}
if (GetID() == LLDB_INVALID_PROCESS_ID) {
- if (log)
- log->Printf("failed to connect to debugserver: %s",
- error.AsCString());
+ LLDB_LOGF(log, "failed to connect to debugserver: %s",
+ error.AsCString());
KillDebugserverProcess();
return error;
}
@@ -1020,8 +954,7 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
}
}
} else {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString());
}
} else {
// Set our user ID to an invalid process ID.
@@ -1040,9 +973,8 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (!connect_url.empty()) {
- if (log)
- log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
- connect_url.str().c_str());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
+ connect_url.str().c_str());
std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor());
if (conn_up) {
@@ -1062,7 +994,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
if (retry_count >= max_retry_count)
break;
- usleep(100000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
}
@@ -1116,8 +1048,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);
if (GetID() != LLDB_INVALID_PROCESS_ID) {
BuildDynamicRegisterInfo(false);
@@ -1130,43 +1061,42 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
if (remote_process_arch.IsValid()) {
process_arch = remote_process_arch;
- if (log)
- log->Printf("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>");
+ 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();
- if (log)
- log->Printf("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>");
+ 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()) {
- if (log)
- log->Printf(
- "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>");
+ 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
@@ -1180,16 +1110,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
process_arch.GetMachine() == llvm::Triple::thumb) &&
process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
GetTarget().SetArchitecture(process_arch);
- if (log)
- log->Printf("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>");
+ 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();
@@ -1211,16 +1141,16 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
}
}
- if (log)
- log->Printf("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>");
+ 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
@@ -1247,8 +1177,7 @@ Status ProcessGDBRemote::DoAttachToProcessWithID(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error;
- if (log)
- log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s()", __FUNCTION__);
// Clear out and clean up from any current state
Clear();
@@ -1359,8 +1288,7 @@ Status ProcessGDBRemote::WillResume() {
Status ProcessGDBRemote::DoResume() {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::Resume()");
+ LLDB_LOGF(log, "ProcessGDBRemote::Resume()");
ListenerSP listener_sp(
Listener::MakeListener("gdb-remote.resume-packet-sent"));
@@ -1547,9 +1475,8 @@ Status ProcessGDBRemote::DoResume() {
EventSP event_sp;
if (!m_async_thread.IsJoinable()) {
error.SetErrorString("Trying to resume but the async thread is dead.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the "
- "async thread is dead.");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Trying to resume but the "
+ "async thread is dead.");
return error;
}
@@ -1560,14 +1487,13 @@ Status ProcessGDBRemote::DoResume() {
if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {
error.SetErrorString("Resume timed out.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Resume timed out.");
} else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
error.SetErrorString("Broadcast continue, but the async thread was "
"killed before we got an ack back.");
- if (log)
- log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the "
- "async thread was killed before we got an ack back.");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoResume: Broadcast continue, but the "
+ "async thread was killed before we got an ack back.");
return error;
}
}
@@ -1864,8 +1790,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
}
for (const auto &pair : expedited_register_map) {
- StringExtractor reg_value_extractor;
- reg_value_extractor.GetStringRef() = pair.second;
+ StringExtractor reg_value_extractor(pair.second);
DataBufferSP buffer_sp(new DataBufferHeap(
reg_value_extractor.GetStringRef().size() / 2, 0));
reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
@@ -1979,8 +1904,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (watch_id == LLDB_INVALID_WATCH_ID) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf("failed to find watchpoint");
+ LLDB_LOGF(log, "failed to find watchpoint");
}
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
*thread_sp, watch_id, wp_hit_addr));
@@ -2400,7 +2324,12 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
description = ostr.GetString();
} else if (key.compare("library") == 0) {
- LoadModules();
+ auto error = LoadModules();
+ if (error) {
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG_ERROR(log, std::move(error), "Failed to load modules: {0}");
+ }
} else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
uint32_t reg = UINT32_MAX;
if (!key.getAsInteger(16, reg))
@@ -2474,7 +2403,7 @@ void ProcessGDBRemote::RefreshStateAfterStop() {
// Clear the thread stop stack
m_stop_packet_stack.clear();
}
-
+
// If we have queried for a default thread id
if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
m_thread_list.SetSelectedThreadByID(m_initial_tid);
@@ -2501,8 +2430,7 @@ Status ProcessGDBRemote::DoHalt(bool &caused_stop) {
Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
error = m_gdb_comm.Detach(keep_stopped);
if (log) {
@@ -2510,8 +2438,9 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
log->PutCString(
"ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s",
- error.AsCString() ? error.AsCString() : "<unknown error>");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDetach() detach packet send failed: %s",
+ error.AsCString() ? error.AsCString() : "<unknown error>");
}
if (!error.Success())
@@ -2530,8 +2459,7 @@ Status ProcessGDBRemote::DoDetach(bool keep_stopped) {
Status ProcessGDBRemote::DoDestroy() {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy()");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy()");
// There is a bug in older iOS debugservers where they don't shut down the
// process they are debugging properly. If the process is sitting at a
@@ -2586,11 +2514,11 @@ Status ProcessGDBRemote::DoDestroy() {
reason = stop_info_sp->GetStopReason();
if (reason == eStopReasonBreakpoint ||
reason == eStopReasonException) {
- if (log)
- log->Printf(
- "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
- " stopped with reason: %s.",
- thread_sp->GetProtocolID(), stop_info_sp->GetDescription());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
+ " stopped with reason: %s.",
+ thread_sp->GetProtocolID(),
+ stop_info_sp->GetDescription());
stop_looks_like_crash = true;
break;
}
@@ -2622,10 +2550,10 @@ Status ProcessGDBRemote::DoDestroy() {
reason = stop_info_sp->GetStopReason();
if (reason != eStopReasonBreakpoint &&
reason != eStopReasonException) {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy() - Suspending "
- "thread: 0x%4.4" PRIx64 " before running.",
- thread_sp->GetProtocolID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy() - Suspending "
+ "thread: 0x%4.4" PRIx64 " before running.",
+ thread_sp->GetProtocolID());
thread_sp->SetResumeState(eStateSuspended);
}
}
@@ -2669,30 +2597,28 @@ Status ProcessGDBRemote::DoDestroy() {
int status;
::pid_t reap_pid;
reap_pid = waitpid(GetID(), &status, WNOHANG);
- if (log)
- log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status);
+ LLDB_LOGF(log, "Reaped pid: %d, status: %d.\n", reap_pid, status);
}
#endif
SetLastStopPacket(response);
ClearThreadIDList();
exit_status = response.GetHexU8();
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response "
- "to k packet: %s",
- response.GetStringRef().c_str());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy - got unexpected response "
+ "to k packet: %s",
+ response.GetStringRef().data());
exit_string.assign("got unexpected response to k packet: ");
exit_string.append(response.GetStringRef());
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ LLDB_LOGF(log, "ProcessGDBRemote::DoDestroy - failed to send k packet");
exit_string.assign("failed to send the k packet");
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while "
- "attaching");
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DoDestroy - killed or interrupted while "
+ "attaching");
exit_string.assign("killed or interrupted while attaching.");
}
} else {
@@ -2715,8 +2641,7 @@ void ProcessGDBRemote::SetLastStopPacket(
response.GetStringRef().find(";reason:exec;") != std::string::npos;
if (did_exec) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+ LLDB_LOGF(log, "ProcessGDBRemote::SetLastStopPacket () - detected exec");
m_thread_list_real.Clear();
m_thread_list.Clear();
@@ -2756,9 +2681,13 @@ addr_t ProcessGDBRemote::GetImageInfoAddress() {
// the loaded module list can also provides a link map address
if (addr == LLDB_INVALID_ADDRESS) {
- LoadedModuleInfoList list;
- if (GetLoadedModuleList(list).Success())
- addr = list.m_link_map;
+ llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList();
+ if (!list) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}");
+ } else {
+ addr = list->m_link_map;
+ }
}
return addr;
@@ -2840,7 +2769,7 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
else
error.SetErrorStringWithFormat(
"unexpected response to GDB server memory read packet '%s': '%s'",
- packet, response.GetStringRef().c_str());
+ packet, response.GetStringRef().data());
} else {
error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
}
@@ -2950,7 +2879,7 @@ Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) {
else
status.SetErrorStringWithFormat(
"unexpected response to GDB server flash erase packet '%s': '%s'",
- packet.GetData(), response.GetStringRef().c_str());
+ packet.GetData(), response.GetStringRef().data());
}
} else {
status.SetErrorStringWithFormat("failed to send packet: '%s'",
@@ -2978,7 +2907,7 @@ Status ProcessGDBRemote::FlashDone() {
else
status.SetErrorStringWithFormat(
"unexpected response to GDB server flash done packet: '%s'",
- response.GetStringRef().c_str());
+ response.GetStringRef().data());
}
} else {
status.SetErrorStringWithFormat("failed to send flash done packet");
@@ -3041,7 +2970,7 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
else
error.SetErrorStringWithFormat(
"unexpected response to GDB server memory write packet '%s': '%s'",
- packet.GetData(), response.GetStringRef().c_str());
+ packet.GetData(), response.GetStringRef().data());
} else {
error.SetErrorStringWithFormat("failed to send packet: '%s'",
packet.GetData());
@@ -3078,11 +3007,11 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
m_addr_to_mmap_size[allocated_addr] = size;
else {
allocated_addr = LLDB_INVALID_ADDRESS;
- if (log)
- log->Printf("ProcessGDBRemote::%s no direct stub support for memory "
- "allocation, and InferiorCallMmap also failed - is stub "
- "missing register context save/restore capability?",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s no direct stub support for memory "
+ "allocation, and InferiorCallMmap also failed - is stub "
+ "missing register context save/restore capability?",
+ __FUNCTION__);
}
}
@@ -3173,17 +3102,17 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
const addr_t addr = bp_site->GetLoadAddress();
// Log that a breakpoint was requested
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
- ") address = 0x%" PRIx64,
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64,
+ site_id, (uint64_t)addr);
// Breakpoint already exists and is enabled
if (bp_site->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
- ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
+ site_id, (uint64_t)addr);
return error;
}
@@ -3231,8 +3160,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
// We reach here when software breakpoints have been found to be
// unsupported. For future calls to set a breakpoint, we will not attempt
// to set a breakpoint with a type that is known not to be supported.
- if (log)
- log->Printf("Software breakpoints are unsupported");
+ LLDB_LOGF(log, "Software breakpoints are unsupported");
// So we will fall through and try a hardware breakpoint
}
@@ -3270,8 +3198,7 @@ Status ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
// We will reach here when the stub gives an unsupported response to a
// hardware breakpoint
- if (log)
- log->Printf("Hardware breakpoints are unsupported");
+ LLDB_LOGF(log, "Hardware breakpoints are unsupported");
// Finally we will falling through to a #trap style breakpoint
}
@@ -3293,10 +3220,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
addr_t addr = bp_site->GetLoadAddress();
user_id_t site_id = bp_site->GetID();
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- if (log)
- log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ site_id, (uint64_t)addr);
if (bp_site->IsEnabled()) {
const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
@@ -3328,10 +3255,10 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
if (error.Success())
bp_site->SetEnabled(false);
} else {
- if (log)
- log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- site_id, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ site_id, (uint64_t)addr);
return error;
}
@@ -3363,14 +3290,13 @@ Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
addr_t addr = wp->GetLoadAddress();
Log *log(
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
+ LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
if (wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
return error;
}
@@ -3403,16 +3329,16 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
addr_t addr = wp->GetLoadAddress();
- if (log)
- log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
if (!wp->IsEnabled()) {
- if (log)
- log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- watchID, (uint64_t)addr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ watchID, (uint64_t)addr);
// See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
// attempt might come from the user-supplied actions, we'll route it in
// order for the watchpoint object to intelligently process this action.
@@ -3447,8 +3373,7 @@ void ProcessGDBRemote::Clear() {
Status ProcessGDBRemote::DoSignal(int signo) {
Status error;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo);
+ LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);
if (!m_gdb_comm.SendAsyncSignal(signo))
error.SetErrorStringWithFormat("failed to send signal %i", signo);
@@ -3460,7 +3385,8 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
return Status("No loader provided.");
// Construct replay history path.
- FileSpec history_file = loader->GetFile<ProcessGDBRemoteProvider::Info>();
+ FileSpec history_file =
+ loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
if (!history_file)
return Status("No provider for gdb-remote.");
@@ -3556,8 +3482,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
int our_socket = sockets[0];
int gdb_socket = sockets[1];
- CleanUp cleanup_our(close, our_socket);
- CleanUp cleanup_gdb(close, gdb_socket);
+ auto cleanup_our = llvm::make_scope_exit([&]() { close(our_socket); });
+ auto cleanup_gdb = llvm::make_scope_exit([&]() { close(gdb_socket); });
// Don't let any child processes inherit our communication socket
SetCloexecFlag(our_socket);
@@ -3577,7 +3503,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
// Our process spawned correctly, we can now set our connection to use
// our end of the socket pair
- cleanup_our.disable();
+ cleanup_our.release();
m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true));
#endif
StartAsyncThread();
@@ -3586,9 +3512,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
if (error.Fail()) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("failed to start debugserver process: %s",
- error.AsCString());
+ LLDB_LOGF(log, "failed to start debugserver process: %s",
+ error.AsCString());
return error;
}
@@ -3614,22 +3539,22 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
const bool handled = true;
- if (log)
- log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
- ", signo=%i (0x%x), exit_status=%i)",
- __FUNCTION__, debugserver_pid, signo, signo, exit_status);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
+ ", signo=%i (0x%x), exit_status=%i)",
+ __FUNCTION__, debugserver_pid, signo, signo, exit_status);
std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
- if (log)
- log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
- static_cast<void *>(process_sp.get()));
+ LLDB_LOGF(log, "ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
+ static_cast<void *>(process_sp.get()));
if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
return handled;
// Sleep for a half a second to make sure our inferior process has time to
// set its exit status before we set it incorrectly when both the debugserver
// and the inferior process shut down.
- usleep(500000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+
// If our process hasn't yet exited, debugserver might have died. If the
// process did exit, then we are reaping it.
const StateType state = process_sp->GetState();
@@ -3692,8 +3617,7 @@ void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {
bool ProcessGDBRemote::StartAsyncThread() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);
std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (!m_async_thread.IsJoinable()) {
@@ -3709,10 +3633,11 @@ bool ProcessGDBRemote::StartAsyncThread() {
return false;
}
m_async_thread = *async_thread;
- } else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
- "already running.",
- __FUNCTION__);
+ } else
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s () - Called when Async thread was "
+ "already running.",
+ __FUNCTION__);
return m_async_thread.IsJoinable();
}
@@ -3720,8 +3645,7 @@ bool ProcessGDBRemote::StartAsyncThread() {
void ProcessGDBRemote::StopAsyncThread() {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s ()", __FUNCTION__);
std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
if (m_async_thread.IsJoinable()) {
@@ -3733,8 +3657,9 @@ void ProcessGDBRemote::StopAsyncThread() {
// Stop the stdio thread
m_async_thread.Join(nullptr);
m_async_thread.Reset();
- } else if (log)
- log->Printf(
+ } else
+ LLDB_LOGF(
+ log,
"ProcessGDBRemote::%s () - Called when Async thread was not running.",
__FUNCTION__);
}
@@ -3768,25 +3693,25 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread starting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ __FUNCTION__, arg, process->GetID());
EventSP event_sp;
bool done = false;
while (!done) {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp)...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ __FUNCTION__, arg, process->GetID());
if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") Got an event of type: %d...",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") Got an event of type: %d...",
+ __FUNCTION__, arg, process->GetID(), event_type);
switch (event_type) {
case eBroadcastBitAsyncContinue: {
@@ -3797,10 +3722,10 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
const char *continue_cstr =
(const char *)continue_packet->GetBytes();
const size_t continue_cstr_len = continue_packet->GetByteSize();
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got eBroadcastBitAsyncContinue: %s",
- __FUNCTION__, arg, process->GetID(), continue_cstr);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncContinue: %s",
+ __FUNCTION__, arg, process->GetID(), continue_cstr);
if (::strstr(continue_cstr, "vAttach") == nullptr)
process->SetPrivateState(eStateRunning);
@@ -3891,18 +3816,18 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
break;
case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got eBroadcastBitAsyncThreadShouldExit...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ __FUNCTION__, arg, process->GetID());
done = true;
break;
default:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
@@ -3925,27 +3850,27 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
}
default:
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") got unknown event 0x%8.8x",
- __FUNCTION__, arg, process->GetID(), event_type);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
}
} else {
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp) => false",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ __FUNCTION__, arg, process->GetID());
done = true;
}
}
- if (log)
- log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- __FUNCTION__, arg, process->GetID());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ __FUNCTION__, arg, process->GetID());
return {};
}
@@ -3977,8 +3902,7 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
// thread when it starts to
// run so I can stop it if that's what I want to do.
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Hit New Thread Notification breakpoint.");
+ LLDB_LOGF(log, "Hit New Thread Notification breakpoint.");
return false;
}
@@ -4023,7 +3947,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf("Enabled noticing new thread breakpoint.");
+ LLDB_LOGF(log, "Enabled noticing new thread breakpoint.");
m_thread_create_bp_sp->SetEnabled(true);
} else {
PlatformSP platform_sp(GetTarget().GetPlatform());
@@ -4032,14 +3956,13 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
platform_sp->SetThreadCreationBreakpoint(GetTarget());
if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf(
- "Successfully created new thread notification breakpoint %i",
+ LLDB_LOGF(
+ log, "Successfully created new thread notification breakpoint %i",
m_thread_create_bp_sp->GetID());
m_thread_create_bp_sp->SetCallback(
ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
} else {
- if (log)
- log->Printf("Failed to create new thread notification breakpoint.");
+ LLDB_LOGF(log, "Failed to create new thread notification breakpoint.");
}
}
}
@@ -4049,7 +3972,7 @@ bool ProcessGDBRemote::StartNoticingNewThreads() {
bool ProcessGDBRemote::StopNoticingNewThreads() {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("Disabling new thread notification breakpoint.");
+ LLDB_LOGF(log, "Disabling new thread notification breakpoint.");
if (m_thread_create_bp_sp)
m_thread_create_bp_sp->SetEnabled(false);
@@ -4325,19 +4248,18 @@ bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
}
if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
- if (log)
- log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_file_spec.GetPath().c_str(),
- arch.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str());
return false;
}
if (log) {
StreamString stream;
module_spec.Dump(stream);
- log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_file_spec.GetPath().c_str(),
- arch.GetTriple().getTriple().c_str(), stream.GetData());
+ LLDB_LOGF(log, "ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
}
m_cached_module_specs[key] = module_spec;
@@ -4361,6 +4283,10 @@ llvm::VersionTuple ProcessGDBRemote::GetHostOSVersion() {
return m_gdb_comm.GetOSVersion();
}
+llvm::VersionTuple ProcessGDBRemote::GetHostMacCatalystVersion() {
+ return m_gdb_comm.GetMacCatalystVersion();
+}
+
namespace {
typedef std::vector<std::string> stringVec;
@@ -4492,14 +4418,13 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
} else if (name == "invalidate_regnums") {
SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
} else if (name == "dynamic_size_dwarf_expr_bytes") {
- StringExtractor opcode_extractor;
std::string opcode_string = value.str();
size_t dwarf_opcode_len = opcode_string.length() / 2;
assert(dwarf_opcode_len > 0);
dwarf_opcode_bytes.resize(dwarf_opcode_len);
reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
- opcode_extractor.GetStringRef().swap(opcode_string);
+ StringExtractor opcode_extractor(opcode_string);
uint32_t ret_val =
opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
assert(dwarf_opcode_len == ret_val);
@@ -4565,16 +4490,15 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
// information to the current process. It will call itself recursively
// for nested register definition files. It returns true if it was able
// to fetch and parse an xml file.
-bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
- std::string xml_filename,
- uint32_t &cur_reg_num,
- uint32_t &reg_offset) {
+bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
+ ArchSpec &arch_to_use, std::string xml_filename, uint32_t &cur_reg_num,
+ uint32_t &reg_offset) {
// request the target xml file
std::string raw;
lldb_private::Status lldberr;
- if (!m_gdb_comm.ReadExtFeature(ConstString("features"),
- ConstString(xml_filename.c_str()),
- raw, lldberr)) {
+ if (!m_gdb_comm.ReadExtFeature(ConstString("features"),
+ ConstString(xml_filename.c_str()), raw,
+ lldberr)) {
return false;
}
@@ -4676,8 +4600,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_u
}
for (const auto &include : target_info.includes) {
- GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,
- cur_reg_num, reg_offset);
+ GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num,
+ reg_offset);
}
}
} else {
@@ -4705,41 +4629,43 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
return m_register_info.GetNumRegisters() > 0;
}
-Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
+llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
// Make sure LLDB has an XML parser it can use first
if (!XMLDocument::XMLEnabled())
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "XML parsing not available");
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
+ LLDB_LOGF(log, "ProcessGDBRemote::%s", __FUNCTION__);
+ LoadedModuleInfoList list;
GDBRemoteCommunicationClient &comm = m_gdb_comm;
bool can_use_svr4 = GetGlobalPluginProperties()->GetUseSVR4();
// check that we have extended feature read support
if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) {
- list.clear();
-
// request the loaded library list
std::string raw;
lldb_private::Status lldberr;
if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""),
raw, lldberr))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error in libraries-svr4 packet");
// parse the xml file in memory
- if (log)
- log->Printf("parsing: %s", raw.c_str());
+ LLDB_LOGF(log, "parsing: %s", raw.c_str());
XMLDocument doc;
if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading noname.xml");
XMLNode root_element = doc.GetRootElement("library-list-svr4");
if (!root_element)
- return Status();
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Error finding library-list-svr4 xml element");
// main link map structure
llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
@@ -4791,10 +4717,11 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
module.get_base_is_offset(base_is_offset);
module.get_dynamic(ld);
- log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
- "[%s], ld:0x%08" PRIx64 ", name:'%s')",
- lm, base, (base_is_offset ? "offset" : "absolute"), ld,
- name.c_str());
+ LLDB_LOGF(log,
+ "found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
+ "[%s], ld:0x%08" PRIx64 ", name:'%s')",
+ lm, base, (base_is_offset ? "offset" : "absolute"), ld,
+ name.c_str());
}
list.add(module);
@@ -4803,29 +4730,30 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
});
if (log)
- log->Printf("found %" PRId32 " modules in total",
- (int)list.m_list.size());
+ LLDB_LOGF(log, "found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ return list;
} else if (comm.GetQXferLibrariesReadSupported()) {
- list.clear();
-
// request the loaded library list
std::string raw;
lldb_private::Status lldberr;
if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw,
lldberr))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error in libraries packet");
- if (log)
- log->Printf("parsing: %s", raw.c_str());
+ LLDB_LOGF(log, "parsing: %s", raw.c_str());
XMLDocument doc;
if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error reading noname.xml");
XMLNode root_element = doc.GetRootElement("library-list");
if (!root_element)
- return Status();
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Error finding library-list xml element");
root_element.ForEachChildElementWithName(
"library", [log, &list](const XMLNode &library) -> bool {
@@ -4853,8 +4781,8 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
module.get_base(base);
module.get_base_is_offset(base_is_offset);
- log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
- (base_is_offset ? "offset" : "absolute"), name.c_str());
+ LLDB_LOGF(log, "found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
+ (base_is_offset ? "offset" : "absolute"), name.c_str());
}
list.add(module);
@@ -4863,13 +4791,13 @@ Status ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
});
if (log)
- log->Printf("found %" PRId32 " modules in total",
- (int)list.m_list.size());
+ LLDB_LOGF(log, "found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ return list;
} else {
- return Status(0, ErrorType::eErrorTypeGeneric);
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Remote libraries not supported");
}
-
- return Status();
}
lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
@@ -4884,17 +4812,18 @@ lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
value_is_offset);
}
-size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
+llvm::Error ProcessGDBRemote::LoadModules() {
using lldb_private::process_gdb_remote::ProcessGDBRemote;
// request a list of loaded libraries from GDBServer
- if (GetLoadedModuleList(module_list).Fail())
- return 0;
+ llvm::Expected<LoadedModuleInfoList> module_list = GetLoadedModuleList();
+ if (!module_list)
+ return module_list.takeError();
// get a list of all the modules
ModuleList new_modules;
- for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) {
+ for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list->m_list) {
std::string mod_name;
lldb::addr_t mod_base;
lldb::addr_t link_map;
@@ -4961,12 +4890,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
m_process->GetTarget().ModulesDidLoad(new_modules);
}
- return new_modules.GetSize();
-}
-
-size_t ProcessGDBRemote::LoadModules() {
- LoadedModuleInfoList module_list;
- return LoadModules(module_list);
+ return llvm::ErrorSuccess();
}
Status ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
@@ -5149,7 +5073,8 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
if (!packet.consume_front(s_async_json_packet_prefix)) {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"GDBRemoteCommunicationClientBase::%s() received $J packet "
"but was not a StructuredData packet: packet starts with "
"%s",
@@ -5164,16 +5089,18 @@ ParseStructuredDataPacket(llvm::StringRef packet) {
if (log) {
if (json_sp) {
StreamString json_str;
- json_sp->Dump(json_str);
+ json_sp->Dump(json_str, true);
json_str.Flush();
- log->Printf("ProcessGDBRemote::%s() "
- "received Async StructuredData packet: %s",
- __FUNCTION__, json_str.GetData());
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s() "
+ "received Async StructuredData packet: %s",
+ __FUNCTION__, json_str.GetData());
} else {
- log->Printf("ProcessGDBRemote::%s"
- "() received StructuredData packet:"
- " parse failure",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::%s"
+ "() received StructuredData packet:"
+ " parse failure",
+ __FUNCTION__);
}
}
return json_sp;
@@ -5365,7 +5292,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 = response.GetStringRef();
if (strstr(packet_cstr, "qGetProfileData") != nullptr) {
response_str = process->HarmonizeThreadIdsForProfileData(response);
@@ -5374,7 +5301,7 @@ public:
if (response_str.empty())
output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
}
return true;
@@ -5423,7 +5350,7 @@ public:
if (response_str.empty())
output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
else
- output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ output_strm.Printf("response: %s\n", response.GetStringRef().data());
}
return true;
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 9c41fc2e5e98..0e3e3b39d9c8 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -24,8 +24,8 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StringList.h"
@@ -199,10 +199,11 @@ public:
const llvm::Triple &triple) override;
llvm::VersionTuple GetHostOSVersion() override;
+ llvm::VersionTuple GetHostMacCatalystVersion() override;
- size_t LoadModules(LoadedModuleInfoList &module_list) override;
+ llvm::Error LoadModules() override;
- size_t LoadModules() override;
+ llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() override;
Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
lldb::addr_t &load_addr) override;
@@ -391,9 +392,6 @@ protected:
// Query remote GDBServer for register information
bool GetGDBServerRegisterInfo(ArchSpec &arch);
- // Query remote GDBServer for a detailed loaded library list
- Status GetLoadedModuleList(LoadedModuleInfoList &);
-
lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,
lldb::addr_t link_map,
lldb::addr_t base_addr,
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
new file mode 100644
index 000000000000..16e7723e3061
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
@@ -0,0 +1,16 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "processgdbremote" in {
+ def PacketTimeout: Property<"packet-timeout", "UInt64">,
+ Global,
+ DefaultUnsignedValue<5>,
+ Desc<"Specify the default packet timeout in seconds.">;
+ def TargetDefinitionFile: Property<"target-definition-file", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ 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.">;
+}
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 6607bce4488b..8a6a58c55450 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -215,8 +215,7 @@ StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
StructuredData::ObjectSP object_sp;
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
- if (log)
- log->Printf("Fetching extended information for thread %4.4" PRIx64, tid);
+ LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
ProcessSP process_sp(GetProcess());
if (process_sp) {
ProcessGDBRemote *gdb_process =
@@ -230,9 +229,8 @@ void ThreadGDBRemote::WillResume(StateType resume_state) {
int signo = GetResumeSignal();
const lldb::user_id_t tid = GetProtocolID();
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
- if (log)
- log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
- StateAsCString(resume_state));
+ LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
+ StateAsCString(resume_state));
ProcessSP process_sp(GetProcess());
if (process_sp) {
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
index ff015aa54b76..70933f91fe51 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -188,6 +188,7 @@ ArchSpec MinidumpParser::GetArchitecture() {
case OSPlatform::Win32NT:
case OSPlatform::Win32CE:
triple.setOS(llvm::Triple::OSType::Win32);
+ triple.setVendor(llvm::Triple::VendorType::PC);
break;
case OSPlatform::Linux:
triple.setOS(llvm::Triple::OSType::Linux);
@@ -313,13 +314,15 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
return filtered_modules;
}
-const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() {
- llvm::ArrayRef<uint8_t> data = GetStream(StreamType::Exception);
+const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() {
+ auto ExpectedStream = GetMinidumpFile().getExceptionStream();
+ if (ExpectedStream)
+ return &*ExpectedStream;
- if (data.size() == 0)
- return nullptr;
-
- return MinidumpExceptionStream::Parse(data);
+ LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS),
+ ExpectedStream.takeError(),
+ "Failed to read minidump exception stream: {0}");
+ return nullptr;
}
llvm::Optional<minidump::Range>
@@ -426,23 +429,35 @@ CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser,
static bool
CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser,
std::vector<MemoryRegionInfo> &regions) {
- auto data = parser.GetStream(StreamType::MemoryInfoList);
- if (data.empty())
- return false;
- auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data);
- if (mem_info_list.empty())
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES);
+ auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList();
+ if (!ExpectedInfo) {
+ LLDB_LOG_ERROR(log, ExpectedInfo.takeError(),
+ "Failed to read memory info list: {0}");
return false;
+ }
constexpr auto yes = MemoryRegionInfo::eYes;
constexpr auto no = MemoryRegionInfo::eNo;
- regions.reserve(mem_info_list.size());
- for (const auto &entry : mem_info_list) {
+ for (const MemoryInfo &entry : *ExpectedInfo) {
MemoryRegionInfo region;
- region.GetRange().SetRangeBase(entry->base_address);
- region.GetRange().SetByteSize(entry->region_size);
- region.SetReadable(entry->isReadable() ? yes : no);
- region.SetWritable(entry->isWritable() ? yes : no);
- region.SetExecutable(entry->isExecutable() ? yes : no);
- region.SetMapped(entry->isMapped() ? yes : no);
+ region.GetRange().SetRangeBase(entry.BaseAddress);
+ region.GetRange().SetByteSize(entry.RegionSize);
+
+ MemoryProtection prot = entry.Protect;
+ region.SetReadable(bool(prot & MemoryProtection::NoAccess) ? no : yes);
+ region.SetWritable(
+ bool(prot & (MemoryProtection::ReadWrite | MemoryProtection::WriteCopy |
+ MemoryProtection::ExecuteReadWrite |
+ MemoryProtection::ExeciteWriteCopy))
+ ? yes
+ : no);
+ region.SetExecutable(
+ bool(prot & (MemoryProtection::Execute | MemoryProtection::ExecuteRead |
+ MemoryProtection::ExecuteReadWrite |
+ MemoryProtection::ExeciteWriteCopy))
+ ? yes
+ : no);
+ region.SetMapped(entry.State != MemoryState::Free ? yes : no);
regions.push_back(region);
}
return !regions.empty();
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index fce64f0ed5fc..d206fe6c9a00 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -82,7 +82,7 @@ public:
// have the same name, it keeps the copy with the lowest load address.
std::vector<const minidump::Module *> GetFilteredModuleList();
- const MinidumpExceptionStream *GetExceptionStream();
+ const llvm::minidump::ExceptionStream *GetExceptionStream();
llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
index d7fc6e43d090..ed00b1cc07db 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -57,17 +57,6 @@ LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
lldb::pid_t LinuxProcStatus::GetPid() const { return pid; }
-// Exception stuff
-const MinidumpExceptionStream *
-MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
- const MinidumpExceptionStream *exception_stream = nullptr;
- Status error = consumeObject(data, exception_stream);
- if (error.Fail())
- return nullptr;
-
- return exception_stream;
-}
-
std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
const llvm::support::ulittle64_t *mem_ranges_count;
@@ -87,29 +76,3 @@ MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
*mem_ranges_count),
*base_rva);
}
-
-std::vector<const MinidumpMemoryInfo *>
-MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
- const MinidumpMemoryInfoListHeader *header;
- Status error = consumeObject(data, header);
- if (error.Fail() ||
- header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) ||
- header->size_of_entry < sizeof(MinidumpMemoryInfo))
- return {};
-
- data = data.drop_front(header->size_of_header -
- sizeof(MinidumpMemoryInfoListHeader));
-
- if (header->size_of_entry * header->num_of_entries > data.size())
- return {};
-
- std::vector<const MinidumpMemoryInfo *> result;
- result.reserve(header->num_of_entries);
-
- for (uint64_t i = 0; i < header->num_of_entries; ++i) {
- result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>(
- data.data() + i * header->size_of_entry));
- }
-
- return result;
-}
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
index b4878e82de5d..a9c807930ebf 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -85,90 +85,6 @@ struct MinidumpMemoryDescriptor64 {
static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
"sizeof MinidumpMemoryDescriptor64 is not correct!");
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
-struct MinidumpMemoryInfoListHeader {
- llvm::support::ulittle32_t size_of_header;
- llvm::support::ulittle32_t size_of_entry;
- llvm::support::ulittle64_t num_of_entries;
-};
-static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
- "sizeof MinidumpMemoryInfoListHeader is not correct!");
-
-enum class MinidumpMemoryInfoState : uint32_t {
- MemCommit = 0x1000,
- MemFree = 0x10000,
- MemReserve = 0x2000,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
-};
-
-enum class MinidumpMemoryInfoType : uint32_t {
- MemImage = 0x1000000,
- MemMapped = 0x40000,
- MemPrivate = 0x20000,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
-};
-
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
-enum class MinidumpMemoryProtectionContants : uint32_t {
- PageExecute = 0x10,
- PageExecuteRead = 0x20,
- PageExecuteReadWrite = 0x40,
- PageExecuteWriteCopy = 0x80,
- PageNoAccess = 0x01,
- PageReadOnly = 0x02,
- PageReadWrite = 0x04,
- PageWriteCopy = 0x08,
- PageTargetsInvalid = 0x40000000,
- PageTargetsNoUpdate = 0x40000000,
-
- PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
- PageWriteCopy,
- PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
- PageExecuteWriteCopy,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
-};
-
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
-struct MinidumpMemoryInfo {
- llvm::support::ulittle64_t base_address;
- llvm::support::ulittle64_t allocation_base;
- llvm::support::ulittle32_t allocation_protect;
- llvm::support::ulittle32_t alignment1;
- llvm::support::ulittle64_t region_size;
- llvm::support::ulittle32_t state;
- llvm::support::ulittle32_t protect;
- llvm::support::ulittle32_t type;
- llvm::support::ulittle32_t alignment2;
-
- static std::vector<const MinidumpMemoryInfo *>
- ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
-
- bool isReadable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageNoAccess;
- return (static_cast<uint32_t>(mask) & protect) == 0;
- }
-
- bool isWritable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageWritable;
- return (static_cast<uint32_t>(mask) & protect) != 0;
- }
-
- bool isExecutable() const {
- const auto mask = MinidumpMemoryProtectionContants::PageExecutable;
- return (static_cast<uint32_t>(mask) & protect) != 0;
- }
-
- bool isMapped() const {
- return state != static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree);
- }
-};
-
-static_assert(sizeof(MinidumpMemoryInfo) == 48,
- "sizeof MinidumpMemoryInfo is not correct!");
-
// TODO misc2, misc3 ?
// Reference:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
@@ -202,35 +118,6 @@ private:
LinuxProcStatus() = default;
};
-// Exception stuff
-struct MinidumpException {
- enum : unsigned {
- ExceptonInfoMaxParams = 15,
- DumpRequested = 0xFFFFFFFF,
- };
-
- llvm::support::ulittle32_t exception_code;
- llvm::support::ulittle32_t exception_flags;
- llvm::support::ulittle64_t exception_record;
- llvm::support::ulittle64_t exception_address;
- llvm::support::ulittle32_t number_parameters;
- llvm::support::ulittle32_t unused_alignment;
- llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
-};
-static_assert(sizeof(MinidumpException) == 152,
- "sizeof MinidumpException is not correct!");
-
-struct MinidumpExceptionStream {
- llvm::support::ulittle32_t thread_id;
- llvm::support::ulittle32_t alignment;
- MinidumpException exception_record;
- LocationDescriptor thread_context;
-
- static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
-};
-static_assert(sizeof(MinidumpExceptionStream) == 168,
- "sizeof MinidumpExceptionStream is not correct!");
-
} // namespace minidump
} // namespace lldb_private
#endif // liblldb_MinidumpTypes_h_
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
index a7fc42cad16c..e30a3c82a887 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -49,16 +49,19 @@ namespace {
class PlaceholderObjectFile : public ObjectFile {
public:
PlaceholderObjectFile(const lldb::ModuleSP &module_sp,
- const ModuleSpec &module_spec, lldb::offset_t base,
- lldb::offset_t size)
+ const ModuleSpec &module_spec, lldb::addr_t base,
+ lldb::addr_t size)
: ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0,
/*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0),
m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()),
m_base(base), m_size(size) {
- m_symtab_up = llvm::make_unique<Symtab>(this);
+ m_symtab_up = std::make_unique<Symtab>(this);
}
- ConstString GetPluginName() override { return ConstString("placeholder"); }
+ static ConstString GetStaticPluginName() {
+ return ConstString("placeholder");
+ }
+ ConstString GetPluginName() override { return GetStaticPluginName(); }
uint32_t GetPluginVersion() override { return 1; }
bool ParseHeader() override { return true; }
Type CalculateType() override { return eTypeUnknown; }
@@ -80,7 +83,7 @@ public:
}
void CreateSections(SectionList &unified_section_list) override {
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
auto section_sp = std::make_shared<Section>(
GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"),
eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0,
@@ -109,11 +112,12 @@ public:
GetFileSpec(), m_base, m_base + m_size);
}
+ lldb::addr_t GetBaseImageAddress() const { return m_base; }
private:
ArchSpec m_arch;
UUID m_uuid;
- lldb::offset_t m_base;
- lldb::offset_t m_size;
+ lldb::addr_t m_base;
+ lldb::addr_t m_size;
};
} // namespace
@@ -215,6 +219,9 @@ Status ProcessMinidump::DoLoadCore() {
m_thread_list = m_minidump_parser->GetThreads();
m_active_exception = m_minidump_parser->GetExceptionStream();
+
+ SetUnixSignals(UnixSignals::Create(GetArchitecture()));
+
ReadModuleList();
llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid();
@@ -234,39 +241,56 @@ uint32_t ProcessMinidump::GetPluginVersion() { return 1; }
Status ProcessMinidump::DoDestroy() { return Status(); }
void ProcessMinidump::RefreshStateAfterStop() {
+
if (!m_active_exception)
return;
- if (m_active_exception->exception_record.exception_code ==
- MinidumpException::DumpRequested) {
+ constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF;
+ if (m_active_exception->ExceptionRecord.ExceptionCode ==
+ BreakpadDumpRequested) {
+ // This "ExceptionCode" value is a sentinel that is sometimes used
+ // when generating a dump for a process that hasn't crashed.
+
+ // 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
+ // to them as "simulated" exceptions; consider moving this check
+ // down to the OS-specific paths and checking each OS for its own
+ // constant.
return;
}
lldb::StopInfoSP stop_info;
lldb::ThreadSP stop_thread;
- Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id);
+ Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId);
stop_thread = Process::m_thread_list.GetSelectedThread();
ArchSpec arch = GetArchitecture();
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
+ uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode;
+
+ if (signo == 0) {
+ // No stop.
+ return;
+ }
+
stop_info = StopInfo::CreateStopReasonWithSignal(
- *stop_thread, m_active_exception->exception_record.exception_code);
+ *stop_thread, signo);
} else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
stop_info = StopInfoMachException::CreateStopReasonWithMachException(
- *stop_thread, m_active_exception->exception_record.exception_code, 2,
- m_active_exception->exception_record.exception_flags,
- m_active_exception->exception_record.exception_address, 0);
+ *stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2,
+ m_active_exception->ExceptionRecord.ExceptionFlags,
+ m_active_exception->ExceptionRecord.ExceptionAddress, 0);
} else {
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
desc_stream << "Exception "
<< llvm::format_hex(
- m_active_exception->exception_record.exception_code, 8)
+ m_active_exception->ExceptionRecord.ExceptionCode, 8)
<< " encountered at address "
<< llvm::format_hex(
- m_active_exception->exception_record.exception_address,
- 8);
+ m_active_exception->ExceptionRecord.ExceptionAddress, 8);
stop_info = StopInfo::CreateStopReasonWithException(
*stop_thread, desc_stream.str().c_str());
}
@@ -331,8 +355,8 @@ bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,
// If the minidump contains an exception context, use it
if (m_active_exception != nullptr &&
- m_active_exception->thread_id == thread.ThreadId) {
- context_location = m_active_exception->thread_context;
+ m_active_exception->ThreadId == thread.ThreadId) {
+ context_location = m_active_exception->ThreadContext;
}
llvm::ArrayRef<uint8_t> context;
@@ -351,14 +375,15 @@ void ProcessMinidump::ReadModuleList() {
std::vector<const minidump::Module *> filtered_modules =
m_minidump_parser->GetFilteredModuleList();
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
for (auto module : filtered_modules) {
std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
module->ModuleNameRVA));
+ const uint64_t load_addr = module->BaseOfImage;
+ const uint64_t load_size = module->SizeOfImage;
LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
- module->BaseOfImage, module->BaseOfImage + module->SizeOfImage,
- module->SizeOfImage);
+ load_addr, load_addr + load_size, load_size);
// check if the process is wow64 - a 32 bit windows process running on a
// 64 bit windows
@@ -373,7 +398,7 @@ void ProcessMinidump::ReadModuleList() {
Status error;
// Try and find a module with a full UUID that matches. This function will
// add the module to the target if it finds one.
- lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
+ lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
true /* notify */, &error);
if (!module_sp) {
// Try and find a module without specifying the UUID and only looking for
@@ -386,8 +411,8 @@ void ProcessMinidump::ReadModuleList() {
ModuleSpec basename_module_spec(module_spec);
basename_module_spec.GetUUID().Clear();
basename_module_spec.GetFileSpec().GetDirectory().Clear();
- module_sp = GetTarget().GetOrCreateModule(basename_module_spec,
- true /* notify */, &error);
+ module_sp = GetTarget().GetOrCreateModule(basename_module_spec,
+ true /* notify */, &error);
if (module_sp) {
// We consider the module to be a match if the minidump UUID is a
// prefix of the actual UUID, or if either of the UUIDs are empty.
@@ -401,6 +426,19 @@ void ProcessMinidump::ReadModuleList() {
}
}
}
+ if (module_sp) {
+ // Watch out for place holder modules that have different paths, but the
+ // same UUID. If the base address is different, create a new module. If
+ // we don't then we will end up setting the load address of a different
+ // PlaceholderObjectFile and an assertion will fire.
+ auto *objfile = module_sp->GetObjectFile();
+ if (objfile && objfile->GetPluginName() ==
+ PlaceholderObjectFile::GetStaticPluginName()) {
+ if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() !=
+ load_addr)
+ module_sp.reset();
+ }
+ }
if (!module_sp) {
// We failed to locate a matching local object file. Fortunately, the
// minidump format encodes enough information about each module's memory
@@ -415,12 +453,12 @@ void ProcessMinidump::ReadModuleList() {
name);
module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>(
- module_spec, module->BaseOfImage, module->SizeOfImage);
+ module_spec, load_addr, load_size);
GetTarget().GetImages().Append(module_sp, true /* notify */);
}
bool load_addr_changed = false;
- module_sp->SetLoadAddress(GetTarget(), module->BaseOfImage, false,
+ module_sp->SetLoadAddress(GetTarget(), load_addr, false,
load_addr_changed);
}
}
@@ -444,7 +482,7 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
// debug information than needed.
JITLoaderList &ProcessMinidump::GetJITLoaders() {
if (!m_jit_loaders_up) {
- m_jit_loaders_up = llvm::make_unique<JITLoaderList>();
+ m_jit_loaders_up = std::make_unique<JITLoaderList>();
}
return *m_jit_loaders_up;
}
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index c39040f61dc5..22dc24af7c0e 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -108,7 +108,7 @@ private:
FileSpec m_core_file;
lldb::DataBufferSP m_core_data;
llvm::ArrayRef<minidump::Thread> m_thread_list;
- const MinidumpExceptionStream *m_active_exception;
+ const minidump::ExceptionStream *m_active_exception;
lldb::CommandObjectSP m_command_sp;
bool m_is_wow64;
};
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
index f2e456097dfc..72dead07dcb4 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -9,6 +9,7 @@
#include "RegisterContextMinidump_ARM.h"
#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -29,14 +30,14 @@ using namespace minidump;
#define DEF_R(i) \
{ \
"r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
#define DEF_R_ARG(i, n) \
{ \
"r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
@@ -173,7 +174,7 @@ static RegisterInfo g_reg_info_apple_fp = {
OFFSET(r) + 7 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
nullptr,
nullptr,
nullptr,
@@ -186,7 +187,7 @@ static RegisterInfo g_reg_info_fp = {
OFFSET(r) + 11 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
+ {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
nullptr,
nullptr,
nullptr,
@@ -213,7 +214,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 13 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
nullptr,
nullptr,
nullptr,
@@ -224,7 +225,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 14 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
nullptr,
nullptr,
nullptr,
@@ -235,7 +236,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(r) + 15 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
nullptr,
nullptr,
nullptr,
@@ -246,7 +247,7 @@ static RegisterInfo g_reg_infos[] = {
OFFSET(cpsr),
eEncodingUint,
eFormatHex,
- {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
nullptr,
nullptr,
nullptr,
@@ -476,12 +477,22 @@ RegisterContextMinidump_ARM::RegisterContextMinidump_ARM(
lldbassert(k_num_regs == k_num_reg_infos);
}
-size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; }
+size_t RegisterContextMinidump_ARM::GetRegisterCountStatic() {
+ return k_num_regs;
+}
+
+// Used for unit testing so we can verify register info is filled in for
+// all register flavors (DWARF, EH Frame, generic, etc).
+size_t RegisterContextMinidump_ARM::GetRegisterCount() {
+ return GetRegisterCountStatic();
+}
+// Used for unit testing so we can verify register info is filled in.
const RegisterInfo *
-RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(size_t reg,
+ bool apple) {
if (reg < k_num_reg_infos) {
- if (m_apple) {
+ if (apple) {
if (reg == reg_r7)
return &g_reg_info_apple_fp;
} else {
@@ -493,6 +504,11 @@ RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
return nullptr;
}
+const RegisterInfo *
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+ return GetRegisterInfoAtIndexStatic(reg, m_apple);
+}
+
size_t RegisterContextMinidump_ARM::GetRegisterSetCount() {
return k_num_reg_sets;
}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
index eff8cdfef00a..7af3b98a6fe7 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
@@ -38,6 +38,12 @@ public:
// Do nothing... registers are always valid...
}
+ // Used for unit testing.
+ static size_t GetRegisterCountStatic();
+ // Used for unit testing.
+ static const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndexStatic(size_t reg, bool apple);
+
size_t GetRegisterCount() override;
const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 7b9598379553..3517f831970d 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -28,13 +28,13 @@ ScriptInterpreterNone::~ScriptInterpreterNone() {}
bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
CommandReturnObject *,
const ExecuteScriptOptions &) {
- m_debugger.GetErrorFile()->PutCString(
+ m_debugger.GetErrorStream().PutCString(
"error: there is no embedded script interpreter in this mode.\n");
return false;
}
void ScriptInterpreterNone::ExecuteInterpreterLoop() {
- m_debugger.GetErrorFile()->PutCString(
+ m_debugger.GetErrorStream().PutCString(
"error: there is no embedded script interpreter in this mode.\n");
}
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 29dd037efd86..70d93424fdec 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -18,9 +18,11 @@
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
@@ -28,9 +30,41 @@
using namespace lldb_private;
using namespace lldb;
+using namespace lldb_private::python;
+using llvm::cantFail;
+using llvm::Error;
+using llvm::Expected;
+using llvm::Twine;
-void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
- s << "Python Obj: 0x" << GetValue();
+template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ return obj.get().IsTrue();
+}
+
+template <>
+Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ return obj.get().AsLongLong();
+}
+
+template <>
+Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ PyObject *str_obj = PyObject_Str(obj.get().get());
+ if (!obj)
+ return llvm::make_error<PythonException>();
+ auto str = Take<PythonString>(str_obj);
+ auto utf8 = str.AsUTF8();
+ if (!utf8)
+ return utf8.takeError();
+ return utf8.get();
+}
+
+void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
+ s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
}
// PythonObject
@@ -167,12 +201,6 @@ PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
PyObject_GetAttr(m_py_obj, py_attr.get()));
}
-bool PythonObject::IsNone() const { return m_py_obj == Py_None; }
-
-bool PythonObject::IsValid() const { return m_py_obj != nullptr; }
-
-bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }
-
StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
switch (GetObjectType()) {
case PyObjectType::Dictionary:
@@ -201,43 +229,19 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
}
// PythonString
-PythonBytes::PythonBytes() : PythonObject() {}
-PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
- SetBytes(bytes);
-}
+PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
-PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
+PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
}
-PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
-}
-
-PythonBytes::~PythonBytes() {}
-
bool PythonBytes::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyBytes_Check(py_obj);
}
-void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonBytes::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
if (!IsValid())
return llvm::ArrayRef<uint8_t>();
@@ -257,8 +261,7 @@ size_t PythonBytes::GetSize() const {
void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
const char *data = reinterpret_cast<const char *>(bytes.data());
- PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
- PythonObject::Reset(PyRefType::Owned, py_bytes);
+ *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
}
StructuredData::StringSP PythonBytes::CreateStructuredString() const {
@@ -275,39 +278,15 @@ PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
const char *str = reinterpret_cast<const char *>(bytes);
- Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
-}
-
-PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
- Reset(type, o);
+ *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
}
-PythonByteArray::PythonByteArray(const PythonBytes &object)
- : PythonObject(object) {}
-
-PythonByteArray::~PythonByteArray() {}
-
bool PythonByteArray::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyByteArray_Check(py_obj);
}
-void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonByteArray::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
if (!IsValid())
return llvm::ArrayRef<uint8_t>();
@@ -334,21 +313,18 @@ StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
// PythonString
-PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
-}
-
-PythonString::PythonString(llvm::StringRef string) : PythonObject() {
- SetString(string);
-}
-
-PythonString::PythonString(const char *string) : PythonObject() {
- SetString(llvm::StringRef(string));
+Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
+#if PY_MAJOR_VERSION >= 3
+ PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
+#else
+ PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
+#endif
+ if (!str)
+ return llvm::make_error<PythonException>();
+ return Take<PythonString>(str);
}
-PythonString::PythonString() : PythonObject() {}
-
-PythonString::~PythonString() {}
+PythonString::PythonString(llvm::StringRef string) { SetString(string); }
bool PythonString::Check(PyObject *py_obj) {
if (!py_obj)
@@ -363,30 +339,40 @@ bool PythonString::Check(PyObject *py_obj) {
return false;
}
-void PythonString::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonString::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
+void PythonString::Convert(PyRefType &type, PyObject *&py_obj) {
#if PY_MAJOR_VERSION < 3
// In Python 2, Don't store PyUnicode objects directly, because we need
// access to their underlying character buffers which Python 2 doesn't
// provide.
- if (PyUnicode_Check(py_obj))
- result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
+ if (PyUnicode_Check(py_obj)) {
+ PyObject *s = PyUnicode_AsUTF8String(py_obj);
+ if (s == nullptr) {
+ PyErr_Clear();
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ return;
+ }
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ else
+ type = PyRefType::Owned;
+ py_obj = s;
+ }
#endif
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
}
llvm::StringRef PythonString::GetString() const {
+ auto s = AsUTF8();
+ if (!s) {
+ llvm::consumeError(s.takeError());
+ return llvm::StringRef("");
+ }
+ return s.get();
+}
+
+Expected<llvm::StringRef> PythonString::AsUTF8() const {
if (!IsValid())
- return llvm::StringRef();
+ return nullDeref();
Py_ssize_t size;
const char *data;
@@ -394,10 +380,16 @@ llvm::StringRef PythonString::GetString() const {
#if PY_MAJOR_VERSION >= 3
data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
#else
- char *c;
- PyString_AsStringAndSize(m_py_obj, &c, &size);
+ char *c = NULL;
+ int r = PyString_AsStringAndSize(m_py_obj, &c, &size);
+ if (r < 0)
+ c = NULL;
data = c;
#endif
+
+ if (!data)
+ return exception();
+
return llvm::StringRef(data, size);
}
@@ -413,13 +405,13 @@ size_t PythonString::GetSize() const {
}
void PythonString::SetString(llvm::StringRef string) {
-#if PY_MAJOR_VERSION >= 3
- PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, unicode);
-#else
- PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
- PythonObject::Reset(PyRefType::Owned, str);
-#endif
+ auto s = FromUTF8(string);
+ if (!s) {
+ llvm::consumeError(s.takeError());
+ Reset();
+ } else {
+ *this = std::move(s.get());
+ }
}
StructuredData::StringSP PythonString::CreateStructuredString() const {
@@ -430,18 +422,7 @@ StructuredData::StringSP PythonString::CreateStructuredString() const {
// PythonInteger
-PythonInteger::PythonInteger() : PythonObject() {}
-
-PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
-}
-
-PythonInteger::PythonInteger(int64_t value) : PythonObject() {
- SetInteger(value);
-}
-
-PythonInteger::~PythonInteger() {}
+PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
bool PythonInteger::Check(PyObject *py_obj) {
if (!py_obj)
@@ -456,16 +437,7 @@ bool PythonInteger::Check(PyObject *py_obj) {
#endif
}
-void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonInteger::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
+void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
#if PY_MAJOR_VERSION < 3
// Always store this as a PyLong, which makes interoperability between Python
// 2.x and Python 3.x easier. This is only necessary in 2.x, since 3.x
@@ -474,16 +446,23 @@ void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
// Since we converted the original object to a different type, the new
// object is an owned object regardless of the ownership semantics
// requested by the user.
- result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
+ long long value = PyInt_AsLong(py_obj);
+ PyObject *l = nullptr;
+ if (!PyErr_Occurred())
+ l = PyLong_FromLongLong(value);
+ if (l == nullptr) {
+ PyErr_Clear();
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ return;
+ }
+ if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ else
+ type = PyRefType::Owned;
+ py_obj = l;
}
#endif
-
- assert(PyLong_Check(result.get()) &&
- "Couldn't get a PyLong from this PyObject");
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
}
int64_t PythonInteger::GetInteger() const {
@@ -506,7 +485,7 @@ int64_t PythonInteger::GetInteger() const {
}
void PythonInteger::SetInteger(int64_t value) {
- PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
+ *this = Take<PythonInteger>(PyLong_FromLongLong(value));
}
StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
@@ -517,11 +496,6 @@ StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
// PythonBoolean
-PythonBoolean::PythonBoolean(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a boolean type
-}
-
PythonBoolean::PythonBoolean(bool value) {
SetValue(value);
}
@@ -530,27 +504,12 @@ bool PythonBoolean::Check(PyObject *py_obj) {
return py_obj ? PyBool_Check(py_obj) : false;
}
-void PythonBoolean::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonBoolean::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
bool PythonBoolean::GetValue() const {
return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
}
void PythonBoolean::SetValue(bool value) {
- PythonObject::Reset(PyRefType::Owned, PyBool_FromLong(value));
+ *this = Take<PythonBoolean>(PyBool_FromLong(value));
}
StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
@@ -561,42 +520,21 @@ StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
// PythonList
-PythonList::PythonList(PyInitialValue value) : PythonObject() {
+PythonList::PythonList(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyList_New(0));
-}
-
-PythonList::PythonList(int list_size) : PythonObject() {
- Reset(PyRefType::Owned, PyList_New(list_size));
+ *this = Take<PythonList>(PyList_New(0));
}
-PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
+PythonList::PythonList(int list_size) {
+ *this = Take<PythonList>(PyList_New(list_size));
}
-PythonList::~PythonList() {}
-
bool PythonList::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyList_Check(py_obj);
}
-void PythonList::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonList::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonList::GetSize() const {
if (IsValid())
return PyList_GET_SIZE(m_py_obj);
@@ -638,17 +576,13 @@ StructuredData::ArraySP PythonList::CreateStructuredArray() const {
// PythonTuple
-PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
+PythonTuple::PythonTuple(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyTuple_New(0));
-}
-
-PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
- Reset(PyRefType::Owned, PyTuple_New(tuple_size));
+ *this = Take<PythonTuple>(PyTuple_New(0));
}
-PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
+PythonTuple::PythonTuple(int tuple_size) {
+ *this = Take<PythonTuple>(PyTuple_New(tuple_size));
}
PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
@@ -674,29 +608,12 @@ PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
}
}
-PythonTuple::~PythonTuple() {}
-
bool PythonTuple::Check(PyObject *py_obj) {
if (!py_obj)
return false;
return PyTuple_Check(py_obj);
}
-void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonTuple::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonTuple::GetSize() const {
if (IsValid())
return PyTuple_GET_SIZE(m_py_obj);
@@ -730,18 +647,11 @@ StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
// PythonDictionary
-PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
+PythonDictionary::PythonDictionary(PyInitialValue value) {
if (value == PyInitialValue::Empty)
- Reset(PyRefType::Owned, PyDict_New());
+ *this = Take<PythonDictionary>(PyDict_New());
}
-PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
- : PythonObject() {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
-}
-
-PythonDictionary::~PythonDictionary() {}
-
bool PythonDictionary::Check(PyObject *py_obj) {
if (!py_obj)
return false;
@@ -749,21 +659,6 @@ bool PythonDictionary::Check(PyObject *py_obj) {
return PyDict_Check(py_obj);
}
-void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonDictionary::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
uint32_t PythonDictionary::GetSize() const {
if (IsValid())
return PyDict_Size(m_py_obj);
@@ -777,16 +672,66 @@ PythonList PythonDictionary::GetKeys() const {
}
PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
- if (IsAllocated() && key.IsValid())
- return PythonObject(PyRefType::Borrowed,
- PyDict_GetItem(m_py_obj, key.get()));
- return PythonObject();
+ auto item = GetItem(key);
+ if (!item) {
+ llvm::consumeError(item.takeError());
+ return PythonObject();
+ }
+ return std::move(item.get());
+}
+
+Expected<PythonObject>
+PythonDictionary::GetItem(const PythonObject &key) const {
+ if (!IsValid())
+ return nullDeref();
+#if PY_MAJOR_VERSION >= 3
+ PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
+ if (PyErr_Occurred())
+ return exception();
+#else
+ PyObject *o = PyDict_GetItem(m_py_obj, key.get());
+#endif
+ if (!o)
+ return keyError();
+ return Retain<PythonObject>(o);
+}
+
+Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
+ if (!IsValid())
+ return nullDeref();
+ PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
+ if (PyErr_Occurred())
+ return exception();
+ if (!o)
+ return keyError();
+ return Retain<PythonObject>(o);
+}
+
+Error PythonDictionary::SetItem(const PythonObject &key,
+ const PythonObject &value) const {
+ if (!IsValid() || !value.IsValid())
+ return nullDeref();
+ int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
+ if (r < 0)
+ return exception();
+ return Error::success();
+}
+
+Error PythonDictionary::SetItem(const Twine &key,
+ const PythonObject &value) const {
+ if (!IsValid() || !value.IsValid())
+ return nullDeref();
+ int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
+ if (r < 0)
+ return exception();
+ return Error::success();
}
void PythonDictionary::SetItemForKey(const PythonObject &key,
const PythonObject &value) {
- if (IsAllocated() && key.IsValid() && value.IsValid())
- PyDict_SetItem(m_py_obj, key.get(), value.get());
+ Error error = SetItem(key, value);
+ if (error)
+ llvm::consumeError(std::move(error));
}
StructuredData::DictionarySP
@@ -803,14 +748,6 @@ PythonDictionary::CreateStructuredDictionary() const {
return result;
}
-PythonModule::PythonModule() : PythonObject() {}
-
-PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
-}
-
-PythonModule::~PythonModule() {}
-
PythonModule PythonModule::BuiltinsModule() {
#if PY_MAJOR_VERSION >= 3
return AddModule("builtins");
@@ -826,9 +763,23 @@ PythonModule PythonModule::AddModule(llvm::StringRef module) {
return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
}
-PythonModule PythonModule::ImportModule(llvm::StringRef module) {
- std::string str = module.str();
- return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
+Expected<PythonModule> PythonModule::Import(const Twine &name) {
+ PyObject *mod = PyImport_ImportModule(NullTerminated(name));
+ if (!mod)
+ return exception();
+ return Take<PythonModule>(mod);
+}
+
+Expected<PythonObject> PythonModule::Get(const Twine &name) {
+ if (!IsValid())
+ return nullDeref();
+ PyObject *dict = PyModule_GetDict(m_py_obj);
+ if (!dict)
+ return exception();
+ PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
+ if (!item)
+ return exception();
+ return Retain<PythonObject>(item);
}
bool PythonModule::Check(PyObject *py_obj) {
@@ -838,33 +789,12 @@ bool PythonModule::Check(PyObject *py_obj) {
return PyModule_Check(py_obj);
}
-void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonModule::Check(py_obj)) {
- PythonObject::Reset();
- return;
- }
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
-}
-
PythonDictionary PythonModule::GetDictionary() const {
- return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
-}
-
-PythonCallable::PythonCallable() : PythonObject() {}
-
-PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
- Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
+ if (!IsValid())
+ return PythonDictionary();
+ return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
}
-PythonCallable::~PythonCallable() {}
-
bool PythonCallable::Check(PyObject *py_obj) {
if (!py_obj)
return false;
@@ -872,32 +802,80 @@ bool PythonCallable::Check(PyObject *py_obj) {
return PyCallable_Check(py_obj);
}
-void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonCallable::Check(py_obj)) {
- PythonObject::Reset();
- return;
+PythonCallable::ArgInfo PythonCallable::GetNumInitArguments() const {
+ auto arginfo = GetInitArgInfo();
+ if (!arginfo) {
+ llvm::consumeError(arginfo.takeError());
+ return ArgInfo{};
}
-
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+ return arginfo.get();
}
-PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
- ArgInfo result = {0, false, false, false};
+Expected<PythonCallable::ArgInfo> PythonCallable::GetInitArgInfo() const {
if (!IsValid())
- return result;
+ return nullDeref();
+ auto init = As<PythonCallable>(GetAttribute("__init__"));
+ if (!init)
+ return init.takeError();
+ return init.get().GetArgInfo();
+}
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+static const char get_arg_info_script[] = R"(
+from inspect import signature, Parameter, ismethod
+from collections import namedtuple
+ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs', 'is_bound_method'])
+def main(f):
+ count = 0
+ varargs = False
+ for parameter in signature(f).parameters.values():
+ kind = parameter.kind
+ if kind in (Parameter.POSITIONAL_ONLY,
+ Parameter.POSITIONAL_OR_KEYWORD):
+ count += 1
+ elif kind == Parameter.VAR_POSITIONAL:
+ varargs = True
+ elif kind in (Parameter.KEYWORD_ONLY,
+ Parameter.VAR_KEYWORD):
+ pass
+ else:
+ raise Exception(f'unknown parameter kind: {kind}')
+ return ArgInfo(count, varargs, ismethod(f))
+)";
+#endif
+
+Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
+ ArgInfo result = {};
+ if (!IsValid())
+ return nullDeref();
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+
+ // no need to synchronize access to this global, we already have the GIL
+ static PythonScript get_arg_info(get_arg_info_script);
+ Expected<PythonObject> pyarginfo = get_arg_info(*this);
+ if (!pyarginfo)
+ return pyarginfo.takeError();
+ result.count = cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
+ result.has_varargs =
+ cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
+ bool is_method =
+ cantFail(As<bool>(pyarginfo.get().GetAttribute("is_bound_method")));
+ result.max_positional_args =
+ result.has_varargs ? ArgInfo::UNBOUNDED : result.count;
+
+ // FIXME emulate old broken behavior
+ if (is_method)
+ result.count++;
+#else
+ bool is_bound_method = false;
PyObject *py_func_obj = m_py_obj;
if (PyMethod_Check(py_func_obj)) {
py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
PythonObject im_self = GetAttributeValue("im_self");
if (im_self.IsValid() && !im_self.IsNone())
- result.is_bound_method = true;
+ is_bound_method = true;
} else {
// see if this is a callable object with an __call__ method
if (!PyFunction_Check(py_func_obj)) {
@@ -906,9 +884,9 @@ PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
auto __callable__ = __call__.AsType<PythonCallable>();
if (__callable__.IsValid()) {
py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
- PythonObject im_self = GetAttributeValue("im_self");
+ PythonObject im_self = __callable__.GetAttributeValue("im_self");
if (im_self.IsValid() && !im_self.IsNone())
- result.is_bound_method = true;
+ is_bound_method = true;
}
}
}
@@ -923,10 +901,27 @@ PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
result.count = code->co_argcount;
result.has_varargs = !!(code->co_flags & CO_VARARGS);
- result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
+ result.max_positional_args = result.has_varargs
+ ? ArgInfo::UNBOUNDED
+ : (result.count - (int)is_bound_method);
+
+#endif
+
return result;
}
+constexpr unsigned
+ PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
+
+PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
+ auto arginfo = GetArgInfo();
+ if (!arginfo) {
+ llvm::consumeError(arginfo.takeError());
+ return ArgInfo{};
+ }
+ return arginfo.get();
+}
+
PythonObject PythonCallable::operator()() {
return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
}
@@ -945,21 +940,9 @@ operator()(std::initializer_list<PythonObject> args) {
PyObject_CallObject(m_py_obj, arg_tuple.get()));
}
-PythonFile::PythonFile() : PythonObject() {}
-
-PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
-
-PythonFile::PythonFile(const char *path, const char *mode) {
- lldb_private::File file;
- FileSystem::Instance().Open(file, FileSpec(path), GetOptionsFromMode(mode));
- Reset(file, mode);
-}
-
-PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
-
-PythonFile::~PythonFile() {}
-
bool PythonFile::Check(PyObject *py_obj) {
+ if (!py_obj)
+ return false;
#if PY_MAJOR_VERSION < 3
return PyFile_Check(py_obj);
#else
@@ -967,86 +950,633 @@ bool PythonFile::Check(PyObject *py_obj) {
// first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
// over `io.open()`, which returns some object derived from `io.IOBase`. As a
// result, the only way to detect a file in Python 3 is to check whether it
- // inherits from `io.IOBase`. Since it is possible for non-files to also
- // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
- // attribute, which should guarantee that it is backed by the file system.
- PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
- PythonDictionary io_dict(PyRefType::Borrowed,
- PyModule_GetDict(io_module.get()));
- PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));
-
- PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));
-
- if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
+ // inherits from `io.IOBase`.
+ auto io_module = PythonModule::Import("io");
+ if (!io_module) {
+ llvm::consumeError(io_module.takeError());
return false;
- if (!object_type.HasAttribute("fileno"))
+ }
+ auto iobase = io_module.get().Get("IOBase");
+ if (!iobase) {
+ llvm::consumeError(iobase.takeError());
return false;
-
- return true;
+ }
+ int r = PyObject_IsInstance(py_obj, iobase.get().get());
+ if (r < 0) {
+ llvm::consumeError(exception()); // clear the exception and log it.
+ return false;
+ }
+ return !!r;
#endif
}
-void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
- // Grab the desired reference type so that if we end up rejecting `py_obj` it
- // still gets decremented if necessary.
- PythonObject result(type, py_obj);
-
- if (!PythonFile::Check(py_obj)) {
- PythonObject::Reset();
- return;
+namespace {
+class GIL {
+public:
+ GIL() {
+ m_state = PyGILState_Ensure();
+ assert(!PyErr_Occurred());
}
+ ~GIL() { PyGILState_Release(m_state); }
+
+protected:
+ PyGILState_STATE m_state;
+};
+} // namespace
+
+const char *PythonException::toCString() const {
+ if (!m_repr_bytes)
+ return "unknown exception";
+ return PyBytes_AS_STRING(m_repr_bytes);
+}
+
+PythonException::PythonException(const char *caller) {
+ assert(PyErr_Occurred());
+ m_exception_type = m_exception = m_traceback = m_repr_bytes = NULL;
+ PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
+ PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
+ PyErr_Clear();
+ if (m_exception) {
+ PyObject *repr = PyObject_Repr(m_exception);
+ if (repr) {
+ m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
+ if (!m_repr_bytes) {
+ PyErr_Clear();
+ }
+ Py_XDECREF(repr);
+ } else {
+ PyErr_Clear();
+ }
+ }
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT);
+ if (caller)
+ LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
+ else
+ LLDB_LOGF(log, "python exception: %s", toCString());
+}
+void PythonException::Restore() {
+ if (m_exception_type && m_exception) {
+ PyErr_Restore(m_exception_type, m_exception, m_traceback);
+ } else {
+ PyErr_SetString(PyExc_Exception, toCString());
+ }
+ m_exception_type = m_exception = m_traceback = NULL;
+}
- // Calling PythonObject::Reset(const PythonObject&) will lead to stack
- // overflow since it calls back into the virtual implementation.
- PythonObject::Reset(PyRefType::Borrowed, result.get());
+PythonException::~PythonException() {
+ Py_XDECREF(m_exception_type);
+ Py_XDECREF(m_exception);
+ Py_XDECREF(m_traceback);
+ Py_XDECREF(m_repr_bytes);
}
-void PythonFile::Reset(File &file, const char *mode) {
- if (!file.IsValid()) {
- Reset();
- return;
+void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
+
+std::error_code PythonException::convertToErrorCode() const {
+ return llvm::inconvertibleErrorCode();
+}
+
+bool PythonException::Matches(PyObject *exc) const {
+ return PyErr_GivenExceptionMatches(m_exception_type, exc);
+}
+
+const char read_exception_script[] = R"(
+import sys
+from traceback import print_exception
+if sys.version_info.major < 3:
+ from StringIO import StringIO
+else:
+ from io import StringIO
+def main(exc_type, exc_value, tb):
+ f = StringIO()
+ print_exception(exc_type, exc_value, tb, file=f)
+ return f.getvalue()
+)";
+
+std::string PythonException::ReadBacktrace() const {
+
+ if (!m_traceback)
+ return toCString();
+
+ // no need to synchronize access to this global, we already have the GIL
+ static PythonScript read_exception(read_exception_script);
+
+ Expected<std::string> backtrace = As<std::string>(
+ read_exception(m_exception_type, m_exception, m_traceback));
+
+ if (!backtrace) {
+ std::string message =
+ std::string(toCString()) + "\n" +
+ "Traceback unavailble, an error occurred while reading it:\n";
+ return (message + llvm::toString(backtrace.takeError()));
}
- char *cmode = const_cast<char *>(mode);
+ return std::move(backtrace.get());
+}
+
+char PythonException::ID = 0;
+
+llvm::Expected<File::OpenOptions>
+GetOptionsForPyObject(const PythonObject &obj) {
#if PY_MAJOR_VERSION >= 3
- Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
- -1, nullptr, "ignore", nullptr, 0));
+ auto options = File::OpenOptions(0);
+ auto readable = As<bool>(obj.CallMethod("readable"));
+ if (!readable)
+ return readable.takeError();
+ auto writable = As<bool>(obj.CallMethod("writable"));
+ if (!writable)
+ return writable.takeError();
+ if (readable.get())
+ options |= File::eOpenOptionRead;
+ if (writable.get())
+ options |= File::eOpenOptionWrite;
+ return options;
#else
- // Read through the Python source, doesn't seem to modify these strings
- Reset(PyRefType::Owned,
- PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
- nullptr));
+ PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
+ return File::GetOptionsFromMode(py_mode.GetString());
#endif
}
-uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
- if (mode.empty())
- return 0;
+// Base class template for python files. All it knows how to do
+// is hold a reference to the python object and close or flush it
+// when the File is closed.
+namespace {
+template <typename Base> class OwnedPythonFile : public Base {
+public:
+ template <typename... Args>
+ OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
+ : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
+ assert(m_py_obj);
+ }
+
+ ~OwnedPythonFile() override {
+ assert(m_py_obj);
+ GIL takeGIL;
+ Close();
+ // we need to ensure the python object is released while we still
+ // hold the GIL
+ m_py_obj.Reset();
+ }
+
+ bool IsPythonSideValid() const {
+ GIL takeGIL;
+ auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
+ if (!closed) {
+ llvm::consumeError(closed.takeError());
+ return false;
+ }
+ return !closed.get();
+ }
+
+ bool IsValid() const override {
+ return IsPythonSideValid() && Base::IsValid();
+ }
+
+ Status Close() override {
+ assert(m_py_obj);
+ Status py_error, base_error;
+ GIL takeGIL;
+ if (!m_borrowed) {
+ auto r = m_py_obj.CallMethod("close");
+ if (!r)
+ py_error = Status(r.takeError());
+ }
+ base_error = Base::Close();
+ if (py_error.Fail())
+ return py_error;
+ return base_error;
+ };
+
+ PyObject *GetPythonObject() const {
+ assert(m_py_obj.IsValid());
+ return m_py_obj.get();
+ }
+
+ static bool classof(const File *file) = delete;
+
+protected:
+ PythonFile m_py_obj;
+ bool m_borrowed;
+};
+} // namespace
+
+// A SimplePythonFile is a OwnedPythonFile that just does all I/O as
+// a NativeFile
+namespace {
+class SimplePythonFile : public OwnedPythonFile<NativeFile> {
+public:
+ SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
+ File::OpenOptions options)
+ : OwnedPythonFile(file, borrowed, fd, options, false) {}
+
+ static char ID;
+ bool isA(const void *classID) const override {
+ return classID == &ID || NativeFile::isA(classID);
+ }
+ static bool classof(const File *file) { return file->isA(&ID); }
+};
+char SimplePythonFile::ID = 0;
+} // namespace
+
+#if PY_MAJOR_VERSION >= 3
+
+namespace {
+class PythonBuffer {
+public:
+ PythonBuffer &operator=(const PythonBuffer &) = delete;
+ PythonBuffer(const PythonBuffer &) = delete;
+
+ static Expected<PythonBuffer> Create(PythonObject &obj,
+ int flags = PyBUF_SIMPLE) {
+ Py_buffer py_buffer = {};
+ PyObject_GetBuffer(obj.get(), &py_buffer, flags);
+ if (!py_buffer.obj)
+ return llvm::make_error<PythonException>();
+ return PythonBuffer(py_buffer);
+ }
+
+ PythonBuffer(PythonBuffer &&other) {
+ m_buffer = other.m_buffer;
+ other.m_buffer.obj = nullptr;
+ }
- return llvm::StringSwitch<uint32_t>(mode.str())
- .Case("r", File::eOpenOptionRead)
- .Case("w", File::eOpenOptionWrite)
- .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
- File::eOpenOptionCanCreate)
- .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
- .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
- File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
- .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
- File::eOpenOptionAppend | File::eOpenOptionCanCreate)
- .Default(0);
+ ~PythonBuffer() {
+ if (m_buffer.obj)
+ PyBuffer_Release(&m_buffer);
+ }
+
+ Py_buffer &get() { return m_buffer; }
+
+private:
+ // takes ownership of the buffer.
+ PythonBuffer(const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
+ Py_buffer m_buffer;
+};
+} // namespace
+
+// Shared methods between TextPythonFile and BinaryPythonFile
+namespace {
+class PythonIOFile : public OwnedPythonFile<File> {
+public:
+ PythonIOFile(const PythonFile &file, bool borrowed)
+ : OwnedPythonFile(file, borrowed) {}
+
+ ~PythonIOFile() override { Close(); }
+
+ bool IsValid() const override { return IsPythonSideValid(); }
+
+ Status Close() override {
+ assert(m_py_obj);
+ GIL takeGIL;
+ if (m_borrowed)
+ return Flush();
+ auto r = m_py_obj.CallMethod("close");
+ if (!r)
+ return Status(r.takeError());
+ return Status();
+ }
+
+ Status Flush() override {
+ GIL takeGIL;
+ auto r = m_py_obj.CallMethod("flush");
+ if (!r)
+ return Status(r.takeError());
+ return Status();
+ }
+
+ Expected<File::OpenOptions> GetOptions() const override {
+ GIL takeGIL;
+ return GetOptionsForPyObject(m_py_obj);
+ }
+
+ static char ID;
+ bool isA(const void *classID) const override {
+ return classID == &ID || File::isA(classID);
+ }
+ static bool classof(const File *file) { return file->isA(&ID); }
+};
+char PythonIOFile::ID = 0;
+} // namespace
+
+namespace {
+class BinaryPythonFile : public PythonIOFile {
+protected:
+ int m_descriptor;
+
+public:
+ BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
+ : PythonIOFile(file, borrowed),
+ m_descriptor(File::DescriptorIsValid(fd) ? fd
+ : File::kInvalidDescriptor) {}
+
+ int GetDescriptor() const override { return m_descriptor; }
+
+ Status Write(const void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ PyObject *pybuffer_p = PyMemoryView_FromMemory(
+ const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
+ if (!pybuffer_p)
+ return Status(llvm::make_error<PythonException>());
+ auto pybuffer = Take<PythonObject>(pybuffer_p);
+ num_bytes = 0;
+ auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
+ if (!bytes_written)
+ return Status(bytes_written.takeError());
+ if (bytes_written.get() < 0)
+ return Status(".write() method returned a negative number!");
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ num_bytes = bytes_written.get();
+ return Status();
+ }
+
+ Status Read(void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ auto pybuffer_obj =
+ m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
+ if (!pybuffer_obj)
+ return Status(pybuffer_obj.takeError());
+ num_bytes = 0;
+ if (pybuffer_obj.get().IsNone()) {
+ // EOF
+ num_bytes = 0;
+ return Status();
+ }
+ auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
+ if (!pybuffer)
+ return Status(pybuffer.takeError());
+ memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
+ num_bytes = pybuffer.get().get().len;
+ return Status();
+ }
+};
+} // namespace
+
+namespace {
+class TextPythonFile : public PythonIOFile {
+protected:
+ int m_descriptor;
+
+public:
+ TextPythonFile(int fd, const PythonFile &file, bool borrowed)
+ : PythonIOFile(file, borrowed),
+ m_descriptor(File::DescriptorIsValid(fd) ? fd
+ : File::kInvalidDescriptor) {}
+
+ int GetDescriptor() const override { return m_descriptor; }
+
+ Status Write(const void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ auto pystring =
+ PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
+ if (!pystring)
+ return Status(pystring.takeError());
+ num_bytes = 0;
+ auto bytes_written =
+ As<long long>(m_py_obj.CallMethod("write", pystring.get()));
+ if (!bytes_written)
+ return Status(bytes_written.takeError());
+ if (bytes_written.get() < 0)
+ return Status(".write() method returned a negative number!");
+ static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
+ num_bytes = bytes_written.get();
+ return Status();
+ }
+
+ Status Read(void *buf, size_t &num_bytes) override {
+ GIL takeGIL;
+ size_t num_chars = num_bytes / 6;
+ size_t orig_num_bytes = num_bytes;
+ num_bytes = 0;
+ if (orig_num_bytes < 6) {
+ return Status("can't read less than 6 bytes from a utf8 text stream");
+ }
+ auto pystring = As<PythonString>(
+ m_py_obj.CallMethod("read", (unsigned long long)num_chars));
+ if (!pystring)
+ return Status(pystring.takeError());
+ if (pystring.get().IsNone()) {
+ // EOF
+ return Status();
+ }
+ auto stringref = pystring.get().AsUTF8();
+ if (!stringref)
+ return Status(stringref.takeError());
+ num_bytes = stringref.get().size();
+ memcpy(buf, stringref.get().begin(), num_bytes);
+ return Status();
+ }
+};
+} // namespace
+
+#endif
+
+llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
+ if (!IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid PythonFile");
+
+ int fd = PyObject_AsFileDescriptor(m_py_obj);
+ if (fd < 0) {
+ PyErr_Clear();
+ return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
+ }
+ auto options = GetOptionsForPyObject(*this);
+ if (!options)
+ return options.takeError();
+
+ // LLDB and python will not share I/O buffers. We should probably
+ // flush the python buffers now.
+ auto r = CallMethod("flush");
+ if (!r)
+ return r.takeError();
+
+ FileSP file_sp;
+ if (borrowed) {
+ // In this case we we don't need to retain the python
+ // object at all.
+ file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
+ } else {
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
+ }
+ if (!file_sp->IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid File");
+
+ return file_sp;
}
-bool PythonFile::GetUnderlyingFile(File &file) const {
+llvm::Expected<FileSP>
+PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
+
+ assert(!PyErr_Occurred());
+
if (!IsValid())
- return false;
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid PythonFile");
+
+#if PY_MAJOR_VERSION < 3
+
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "not supported on python 2");
+
+#else
+
+ int fd = PyObject_AsFileDescriptor(m_py_obj);
+ if (fd < 0) {
+ PyErr_Clear();
+ fd = File::kInvalidDescriptor;
+ }
+
+ auto io_module = PythonModule::Import("io");
+ if (!io_module)
+ return io_module.takeError();
+ auto textIOBase = io_module.get().Get("TextIOBase");
+ if (!textIOBase)
+ return textIOBase.takeError();
+ auto rawIOBase = io_module.get().Get("RawIOBase");
+ if (!rawIOBase)
+ return rawIOBase.takeError();
+ auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
+ if (!bufferedIOBase)
+ return bufferedIOBase.takeError();
+
+ FileSP file_sp;
+
+ auto isTextIO = IsInstance(textIOBase.get());
+ if (!isTextIO)
+ return isTextIO.takeError();
+ if (isTextIO.get())
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<TextPythonFile>(fd, *this, borrowed));
+
+ auto isRawIO = IsInstance(rawIOBase.get());
+ if (!isRawIO)
+ return isRawIO.takeError();
+ auto isBufferedIO = IsInstance(bufferedIOBase.get());
+ if (!isBufferedIO)
+ return isBufferedIO.takeError();
+
+ if (isRawIO.get() || isBufferedIO.get()) {
+ file_sp = std::static_pointer_cast<File>(
+ std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
+ }
+
+ if (!file_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "python file is neither text nor binary");
+
+ if (!file_sp->IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid File");
+
+ return file_sp;
+
+#endif
+}
+
+Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
+ if (!file.IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid file");
+
+ if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
+ return Retain<PythonFile>(simple->GetPythonObject());
+#if PY_MAJOR_VERSION >= 3
+ if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
+ return Retain<PythonFile>(pythonio->GetPythonObject());
+#endif
+
+ if (!mode) {
+ auto m = file.GetOpenMode();
+ if (!m)
+ return m.takeError();
+ mode = m.get();
+ }
+
+ PyObject *file_obj;
+#if PY_MAJOR_VERSION >= 3
+ file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
+ "ignore", nullptr, 0);
+#else
+ // Read through the Python source, doesn't seem to modify these strings
+ char *cmode = const_cast<char *>(mode);
+ // We pass ::flush instead of ::fclose here so we borrow the FILE* --
+ // the lldb_private::File still owns it.
+ file_obj =
+ PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, ::fflush);
+#endif
+
+ if (!file_obj)
+ return exception();
+
+ return Take<PythonFile>(file_obj);
+}
+
+Error PythonScript::Init() {
+ if (function.IsValid())
+ return Error::success();
+
+ PythonDictionary globals(PyInitialValue::Empty);
+ auto builtins = PythonModule::BuiltinsModule();
+ if (Error error = globals.SetItem("__builtins__", builtins))
+ return error;
+ PyObject *o =
+ PyRun_String(script, Py_file_input, globals.get(), globals.get());
+ if (!o)
+ return exception();
+ Take<PythonObject>(o);
+ auto f = As<PythonCallable>(globals.GetItem("main"));
+ if (!f)
+ return f.takeError();
+ function = std::move(f.get());
+
+ return Error::success();
+}
+
+llvm::Expected<PythonObject>
+python::runStringOneLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals) {
+ if (!globals.IsValid() || !locals.IsValid())
+ return nullDeref();
+
+ PyObject *code =
+ Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
+ if (!code) {
+ PyErr_Clear();
+ code =
+ Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
+ }
+ if (!code)
+ return exception();
+ auto code_ref = Take<PythonObject>(code);
+
+#if PY_MAJOR_VERSION < 3
+ PyObject *result =
+ PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get());
+#else
+ PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
+#endif
+
+ if (!result)
+ return exception();
+
+ return Take<PythonObject>(result);
+}
- file.Close();
- // We don't own the file descriptor returned by this function, make sure the
- // File object knows about that.
- file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
- PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
- file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
- return file.IsValid();
+llvm::Expected<PythonObject>
+python::runStringMultiLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals) {
+ if (!globals.IsValid() || !locals.IsValid())
+ return nullDeref();
+ PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
+ globals.get(), locals.get());
+ if (!result)
+ return exception();
+ return Take<PythonObject>(result);
}
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 049ce90bb1b1..373d3212697d 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -6,6 +6,45 @@
//
//===----------------------------------------------------------------------===//
+//
+// !! FIXME FIXME FIXME !!
+//
+// Python APIs nearly all can return an exception. They do this
+// by returning NULL, or -1, or some such value and setting
+// the exception state with PyErr_Set*(). Exceptions must be
+// handled before further python API functions are called. Failure
+// to do so will result in asserts on debug builds of python.
+// It will also sometimes, but not usually result in crashes of
+// release builds.
+//
+// Nearly all the code in this header does not handle python exceptions
+// correctly. It should all be converted to return Expected<> or
+// Error types to capture the exception.
+//
+// Everything in this file except functions that return Error or
+// Expected<> is considered deprecated and should not be
+// used in new code. If you need to use it, fix it first.
+//
+//
+// TODOs for this file
+//
+// * Make all methods safe for exceptions.
+//
+// * Eliminate method signatures that must translate exceptions into
+// empty objects or NULLs. Almost everything here should return
+// Expected<>. It should be acceptable for certain operations that
+// 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.
+// Python objects should be created with Retain<> or Take<>, and they
+// should be assigned with operator=
+//
+// * Eliminate default constructors, make python objects always
+// nonnull, and use optionals where necessary.
+//
+
+
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
@@ -20,12 +59,15 @@
#include "llvm/ADT/ArrayRef.h"
namespace lldb_private {
+namespace python {
+class PythonObject;
class PythonBytes;
class PythonString;
class PythonList;
class PythonDictionary;
class PythonInteger;
+class PythonException;
class StructuredPythonObject : public StructuredData::Generic {
public:
@@ -43,7 +85,7 @@ public:
bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
private:
DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
@@ -72,61 +114,137 @@ enum class PyRefType {
// not call Py_INCREF.
};
-enum class PyInitialValue { Invalid, Empty };
-class PythonObject {
-public:
- PythonObject() : m_py_obj(nullptr) {}
+// Take a reference that you already own, and turn it into
+// a PythonObject.
+//
+// Most python API methods will return a +1 reference
+// if they succeed or NULL if and only if
+// they set an exception. Use this to collect such return
+// values, after checking for NULL.
+//
+// If T is not just PythonObject, then obj must be already be
+// checked to be of the correct type.
+template <typename T> T Take(PyObject *obj) {
+ assert(obj);
+ assert(!PyErr_Occurred());
+ T thing(PyRefType::Owned, obj);
+ assert(thing.IsValid());
+ return std::move(thing);
+}
+
+// Retain a reference you have borrowed, and turn it into
+// a PythonObject.
+//
+// A minority of python APIs return a borrowed reference
+// instead of a +1. They will also return NULL if and only
+// if they set an exception. Use this to collect such return
+// values, after checking for NULL.
+//
+// If T is not just PythonObject, then obj must be already be
+// checked to be of the correct type.
+template <typename T> T Retain(PyObject *obj) {
+ assert(obj);
+ assert(!PyErr_Occurred());
+ T thing(PyRefType::Borrowed, obj);
+ assert(thing.IsValid());
+ return std::move(thing);
+}
+
+// This class can be used like a utility function to convert from
+// a llvm-friendly Twine into a null-terminated const char *,
+// which is the form python C APIs want their strings in.
+//
+// Example:
+// const llvm::Twine &some_twine;
+// PyFoo_Bar(x, y, z, NullTerminated(some_twine));
+//
+// Why a class instead of a function? If the twine isn't already null
+// terminated, it will need a temporary buffer to copy the string
+// into. We need that buffer to stick around for the lifetime of the
+// statement.
+class NullTerminated {
+ const char *str;
+ llvm::SmallString<32> storage;
- PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
- Reset(type, py_obj);
+public:
+ NullTerminated(const llvm::Twine &twine) {
+ llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
+ str = ref.begin();
}
+ operator const char *() { return str; }
+};
- PythonObject(const PythonObject &rhs) : m_py_obj(nullptr) { Reset(rhs); }
+inline llvm::Error nullDeref() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "A NULL PyObject* was dereferenced");
+}
- virtual ~PythonObject() { Reset(); }
+inline llvm::Error exception(const char *s = nullptr) {
+ return llvm::make_error<PythonException>(s);
+}
- void Reset() {
- // Avoid calling the virtual method since it's not necessary
- // to actually validate the type of the PyObject if we're
- // just setting to null.
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
- m_py_obj = nullptr;
- }
+inline llvm::Error keyError() {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "key not in dict");
+}
- void Reset(const PythonObject &rhs) {
- // Avoid calling the virtual method if it's not necessary
- // to actually validate the type of the PyObject.
- if (!rhs.IsValid())
- Reset();
- else
- Reset(PyRefType::Borrowed, rhs.m_py_obj);
- }
+enum class PyInitialValue { Invalid, Empty };
- // PythonObject is implicitly convertible to PyObject *, which will call the
- // wrong overload. We want to explicitly disallow this, since a PyObject
- // *always* owns its reference. Therefore the overload which takes a
- // PyRefType doesn't make sense, and the copy constructor should be used.
- void Reset(PyRefType type, const PythonObject &ref) = delete;
+template <typename T, typename Enable = void> struct PythonFormat;
- virtual void Reset(PyRefType type, PyObject *py_obj) {
- if (py_obj == m_py_obj)
- return;
+template <> struct PythonFormat<unsigned long long> {
+ static constexpr char format = 'K';
+ static auto get(unsigned long long value) { return value; }
+};
- if (Py_IsInitialized())
- Py_XDECREF(m_py_obj);
+template <> struct PythonFormat<long long> {
+ static constexpr char format = 'L';
+ static auto get(long long value) { return value; }
+};
- m_py_obj = py_obj;
+template <> struct PythonFormat<PyObject *> {
+ static constexpr char format = 'O';
+ static auto get(PyObject *value) { return value; }
+};
+
+template <typename T>
+struct PythonFormat<
+ T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
+ static constexpr char format = 'O';
+ static auto get(const T &value) { return value.get(); }
+};
+
+class PythonObject {
+public:
+ PythonObject() : m_py_obj(nullptr) {}
+ PythonObject(PyRefType type, PyObject *py_obj) {
+ m_py_obj = py_obj;
// If this is a borrowed reference, we need to convert it to
// an owned reference by incrementing it. If it is an owned
// reference (for example the caller allocated it with PyDict_New()
// then we must *not* increment it.
- if (Py_IsInitialized() && type == PyRefType::Borrowed)
+ if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
Py_XINCREF(m_py_obj);
}
+ PythonObject(const PythonObject &rhs)
+ : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
+
+ PythonObject(PythonObject &&rhs) {
+ m_py_obj = rhs.m_py_obj;
+ rhs.m_py_obj = nullptr;
+ }
+
+ ~PythonObject() { Reset(); }
+
+ void Reset() {
+ if (m_py_obj && Py_IsInitialized())
+ Py_DECREF(m_py_obj);
+ m_py_obj = nullptr;
+ }
+
void Dump() const {
if (m_py_obj)
_PyObject_Dump(m_py_obj);
@@ -144,8 +262,9 @@ public:
return result;
}
- PythonObject &operator=(const PythonObject &other) {
- Reset(PyRefType::Borrowed, other.get());
+ PythonObject &operator=(PythonObject other) {
+ Reset();
+ m_py_obj = std::exchange(other.m_py_obj, nullptr);
return *this;
}
@@ -174,11 +293,13 @@ public:
PythonObject GetAttributeValue(llvm::StringRef attribute) const;
- bool IsValid() const;
+ bool IsNone() const { return m_py_obj == Py_None; }
+
+ bool IsValid() const { return m_py_obj != nullptr; }
- bool IsAllocated() const;
+ bool IsAllocated() const { return IsValid() && !IsNone(); }
- bool IsNone() const;
+ explicit operator bool() const { return IsValid() && !IsNone(); }
template <typename T> T AsType() const {
if (!T::Check(m_py_obj))
@@ -189,24 +310,125 @@ public:
StructuredData::ObjectSP CreateStructuredObject() const;
protected:
+
+#if PY_MAJOR_VERSION < 3
+ // The python 2 API declares some arguments as char* that should
+ // be const char *, but it doesn't actually modify them.
+ static char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
+#else
+ static const char *py2_const_cast(const char *s) { return s; }
+#endif
+
+public:
+ template <typename... T>
+ llvm::Expected<PythonObject> CallMethod(const char *name,
+ const T &... t) const {
+ const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
+ PyObject *obj =
+ PyObject_CallMethod(m_py_obj, py2_const_cast(name),
+ py2_const_cast(format), PythonFormat<T>::get(t)...);
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ template <typename... T>
+ llvm::Expected<PythonObject> Call(const T &... t) const {
+ const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
+ PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
+ PythonFormat<T>::get(t)...);
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
+ if (!m_py_obj)
+ return nullDeref();
+ PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
+ if (!obj)
+ return exception();
+ return python::Take<PythonObject>(obj);
+ }
+
+ llvm::Expected<bool> IsTrue() {
+ if (!m_py_obj)
+ return nullDeref();
+ int r = PyObject_IsTrue(m_py_obj);
+ if (r < 0)
+ return exception();
+ 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<bool> IsInstance(const PythonObject &cls) {
+ if (!m_py_obj || !cls.IsValid())
+ return nullDeref();
+ int r = PyObject_IsInstance(m_py_obj, cls.get());
+ if (r < 0)
+ return exception();
+ return !!r;
+ }
+
+protected:
PyObject *m_py_obj;
};
-class PythonBytes : public PythonObject {
+
+// This is why C++ needs monads.
+template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
+ if (!obj)
+ return obj.takeError();
+ if (!T::Check(obj.get().get()))
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "type error");
+ return T(PyRefType::Borrowed, std::move(obj.get().get()));
+}
+
+template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
+
+template <>
+llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
+
+template <>
+llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
+
+
+template <class T> class TypedPythonObject : public PythonObject {
public:
- PythonBytes();
- explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
- PythonBytes(const uint8_t *bytes, size_t length);
- PythonBytes(PyRefType type, PyObject *o);
+ // override to perform implicit type conversions on Reset
+ // This can be eliminated once we drop python 2 support.
+ static void Convert(PyRefType &type, PyObject *&py_obj) {}
- ~PythonBytes() override;
+ TypedPythonObject(PyRefType type, PyObject *py_obj) {
+ if (!py_obj)
+ return;
+ T::Convert(type, py_obj);
+ if (T::Check(py_obj))
+ PythonObject::operator=(PythonObject(type, py_obj));
+ else if (type == PyRefType::Owned)
+ Py_DECREF(py_obj);
+ }
- static bool Check(PyObject *py_obj);
+ TypedPythonObject() {}
+};
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+class PythonBytes : public TypedPythonObject<PythonBytes> {
+public:
+ using TypedPythonObject::TypedPythonObject;
+ explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
+ PythonBytes(const uint8_t *bytes, size_t length);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
llvm::ArrayRef<uint8_t> GetBytes() const;
@@ -217,23 +439,15 @@ public:
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonByteArray : public PythonObject {
+class PythonByteArray : public TypedPythonObject<PythonByteArray> {
public:
- PythonByteArray();
+ using TypedPythonObject::TypedPythonObject;
explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
PythonByteArray(const uint8_t *bytes, size_t length);
- PythonByteArray(PyRefType type, PyObject *o);
PythonByteArray(const PythonBytes &object);
- ~PythonByteArray() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
llvm::ArrayRef<uint8_t> GetBytes() const;
size_t GetSize() const;
@@ -243,45 +457,39 @@ public:
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonString : public PythonObject {
+class PythonString : public TypedPythonObject<PythonString> {
public:
- PythonString();
- explicit PythonString(llvm::StringRef string);
- explicit PythonString(const char *string);
- PythonString(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
+ static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
- ~PythonString() override;
+ PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
- static bool Check(PyObject *py_obj);
+ explicit PythonString(llvm::StringRef string); // safe, null on error
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ static bool Check(PyObject *py_obj);
+ static void Convert(PyRefType &type, PyObject *&py_obj);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::StringRef GetString() const; // safe, empty string on error
- llvm::StringRef GetString() const;
+ llvm::Expected<llvm::StringRef> AsUTF8() const;
size_t GetSize() const;
- void SetString(llvm::StringRef string);
+ void SetString(llvm::StringRef string); // safe, null on error
StructuredData::StringSP CreateStructuredString() const;
};
-class PythonInteger : public PythonObject {
+class PythonInteger : public TypedPythonObject<PythonInteger> {
public:
- PythonInteger();
- explicit PythonInteger(int64_t value);
- PythonInteger(PyRefType type, PyObject *o);
-
- ~PythonInteger() override;
+ using TypedPythonObject::TypedPythonObject;
- static bool Check(PyObject *py_obj);
+ PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ explicit PythonInteger(int64_t value);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
+ static void Convert(PyRefType &type, PyObject *&py_obj);
int64_t GetInteger() const;
@@ -290,21 +498,14 @@ public:
StructuredData::IntegerSP CreateStructuredInteger() const;
};
-class PythonBoolean : public PythonObject {
+class PythonBoolean : public TypedPythonObject<PythonBoolean> {
public:
- PythonBoolean() = default;
- explicit PythonBoolean(bool value);
- PythonBoolean(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonBoolean() override = default;
+ explicit PythonBoolean(bool value);
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
bool GetValue() const;
void SetValue(bool value);
@@ -312,22 +513,17 @@ public:
StructuredData::BooleanSP CreateStructuredBoolean() const;
};
-class PythonList : public PythonObject {
+class PythonList : public TypedPythonObject<PythonList> {
public:
- PythonList() {}
+ using TypedPythonObject::TypedPythonObject;
+
+ PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
+
explicit PythonList(PyInitialValue value);
explicit PythonList(int list_size);
- PythonList(PyRefType type, PyObject *o);
-
- ~PythonList() override;
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
uint32_t GetSize() const;
PythonObject GetItemAtIndex(uint32_t index) const;
@@ -339,24 +535,17 @@ public:
StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonTuple : public PythonObject {
+class PythonTuple : public TypedPythonObject<PythonTuple> {
public:
- PythonTuple() {}
+ using TypedPythonObject::TypedPythonObject;
+
explicit PythonTuple(PyInitialValue value);
explicit PythonTuple(int tuple_size);
- PythonTuple(PyRefType type, PyObject *o);
PythonTuple(std::initializer_list<PythonObject> objects);
PythonTuple(std::initializer_list<PyObject *> objects);
- ~PythonTuple() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
-
- void Reset(PyRefType type, PyObject *py_obj) override;
-
uint32_t GetSize() const;
PythonObject GetItemAtIndex(uint32_t index) const;
@@ -366,37 +555,35 @@ public:
StructuredData::ArraySP CreateStructuredArray() const;
};
-class PythonDictionary : public PythonObject {
+class PythonDictionary : public TypedPythonObject<PythonDictionary> {
public:
- PythonDictionary() {}
- explicit PythonDictionary(PyInitialValue value);
- PythonDictionary(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonDictionary() override;
-
- static bool Check(PyObject *py_obj);
+ PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ explicit PythonDictionary(PyInitialValue value);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ static bool Check(PyObject *py_obj);
uint32_t GetSize() const;
PythonList GetKeys() const;
- PythonObject GetItemForKey(const PythonObject &key) const;
- void SetItemForKey(const PythonObject &key, const PythonObject &value);
+ PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
+ void SetItemForKey(const PythonObject &key,
+ const PythonObject &value); // DEPRECATED
+
+ llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
+ llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
+ llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
+ llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
StructuredData::DictionarySP CreateStructuredDictionary() const;
};
-class PythonModule : public PythonObject {
+class PythonModule : public TypedPythonObject<PythonModule> {
public:
- PythonModule();
- PythonModule(PyRefType type, PyObject *o);
-
- ~PythonModule() override;
+ using TypedPythonObject::TypedPythonObject;
static bool Check(PyObject *py_obj);
@@ -406,38 +593,57 @@ public:
static PythonModule AddModule(llvm::StringRef module);
- static PythonModule ImportModule(llvm::StringRef module);
+ // safe, returns invalid on error;
+ static PythonModule ImportModule(llvm::StringRef name) {
+ std::string s = name;
+ auto mod = Import(s.c_str());
+ if (!mod) {
+ llvm::consumeError(mod.takeError());
+ return PythonModule();
+ }
+ return std::move(mod.get());
+ }
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::Expected<PythonObject> Get(const llvm::Twine &name);
PythonDictionary GetDictionary() const;
};
-class PythonCallable : public PythonObject {
+class PythonCallable : public TypedPythonObject<PythonCallable> {
public:
+ using TypedPythonObject::TypedPythonObject;
+
struct ArgInfo {
- size_t count;
- bool is_bound_method : 1;
- bool has_varargs : 1;
- bool has_kwargs : 1;
+ /* the largest number of positional arguments this callable
+ * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
+ * function and can accept an arbitrary number */
+ unsigned max_positional_args;
+ static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
+ /* the number of positional arguments, including optional ones,
+ * and excluding varargs. If this is a bound method, then the
+ * count will still include a +1 for self.
+ *
+ * FIXME. That's crazy. This should be replaced with
+ * an accurate min and max for positional args.
+ */
+ int count;
+ /* does the callable have positional varargs? */
+ bool has_varargs : 1; // FIXME delete this
};
- PythonCallable();
- PythonCallable(PyRefType type, PyObject *o);
-
- ~PythonCallable() override;
-
static bool Check(PyObject *py_obj);
- // Bring in the no-argument base class version
- using PythonObject::Reset;
+ llvm::Expected<ArgInfo> GetArgInfo() const;
- void Reset(PyRefType type, PyObject *py_obj) override;
+ llvm::Expected<ArgInfo> GetInitArgInfo() const;
- ArgInfo GetNumArguments() const;
+ ArgInfo GetNumArguments() const; // DEPRECATED
+
+ // If the callable is a Py_Class, then find the number of arguments
+ // of the __init__ method.
+ ArgInfo GetNumInitArguments() const; // DEPRECATED
PythonObject operator()();
@@ -451,27 +657,123 @@ public:
}
};
-class PythonFile : public PythonObject {
+class PythonFile : public TypedPythonObject<PythonFile> {
public:
- PythonFile();
- PythonFile(File &file, const char *mode);
- PythonFile(const char *path, const char *mode);
- PythonFile(PyRefType type, PyObject *o);
+ using TypedPythonObject::TypedPythonObject;
- ~PythonFile() override;
+ PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
static bool Check(PyObject *py_obj);
- using PythonObject::Reset;
+ static llvm::Expected<PythonFile> FromFile(File &file,
+ const char *mode = nullptr);
- void Reset(PyRefType type, PyObject *py_obj) override;
- void Reset(File &file, const char *mode);
+ llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
+ llvm::Expected<lldb::FileSP>
+ ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
+};
- static uint32_t GetOptionsFromMode(llvm::StringRef mode);
+class PythonException : public llvm::ErrorInfo<PythonException> {
+private:
+ PyObject *m_exception_type, *m_exception, *m_traceback;
+ PyObject *m_repr_bytes;
- bool GetUnderlyingFile(File &file) const;
+public:
+ static char ID;
+ const char *toCString() const;
+ PythonException(const char *caller = nullptr);
+ void Restore();
+ ~PythonException();
+ void log(llvm::raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+ bool Matches(PyObject *exc) const;
+ std::string ReadBacktrace() const;
+};
+
+// This extracts the underlying T out of an Expected<T> and returns it.
+// If the Expected is an Error instead of a T, that error will be converted
+// into a python exception, and this will return a default-constructed T.
+//
+// This is appropriate for use right at the boundary of python calling into
+// C++, such as in a SWIG typemap. In such a context you should simply
+// check if the returned T is valid, and if it is, return a NULL back
+// to python. This will result in the Error being raised as an exception
+// from python code's point of view.
+//
+// For example:
+// ```
+// Expected<Foo *> efoop = some_cpp_function();
+// Foo *foop = unwrapOrSetPythonException(efoop);
+// if (!foop)
+// return NULL;
+// do_something(*foop);
+//
+// If the Error returned was itself created because a python exception was
+// raised when C++ code called into python, then the original exception
+// will be restored. Otherwise a simple string exception will be raised.
+template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
+ if (expected)
+ return expected.get();
+ llvm::handleAllErrors(
+ expected.takeError(), [](PythonException &E) { E.Restore(); },
+ [](const llvm::ErrorInfoBase &E) {
+ PyErr_SetString(PyExc_Exception, E.message().c_str());
+ });
+ return T();
+}
+
+// This is only here to help incrementally migrate old, exception-unsafe
+// code.
+template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
+ if (expected)
+ return std::move(expected.get());
+ llvm::consumeError(expected.takeError());
+ return T();
+}
+
+llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals);
+
+llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
+ const PythonDictionary &globals,
+ const PythonDictionary &locals);
+
+// Sometimes the best way to interact with a python interpreter is
+// to run some python code. You construct a PythonScript with
+// script string. The script assigns some function to `_function_`
+// and you get a C++ callable object that calls the python function.
+//
+// Example:
+//
+// const char script[] = R"(
+// def main(x, y):
+// ....
+// )";
+//
+// Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
+// // no need to synchronize access to this global, we already have the GIL
+// static PythonScript foo(script)
+// return foo(x, y);
+// }
+class PythonScript {
+ const char *script;
+ PythonCallable function;
+
+ llvm::Error Init();
+
+public:
+ PythonScript(const char *script) : script(script), function() {}
+
+ template <typename... Args>
+ llvm::Expected<PythonObject> operator()(Args &&... args) {
+ if (llvm::Error error = Init())
+ return std::move(error);
+ return function.Call(std::forward<Args>(args)...);
+ }
};
+} // namespace python
} // namespace lldb_private
#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
deleted file mode 100644
index c9d834ce6868..000000000000
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- PythonExceptionState.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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_DISABLE_PYTHON
-
-// LLDB Python header must be included first
-#include "lldb-python.h"
-
-#include "PythonExceptionState.h"
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb_private;
-
-PythonExceptionState::PythonExceptionState(bool restore_on_exit)
- : m_restore_on_exit(restore_on_exit) {
- Acquire(restore_on_exit);
-}
-
-PythonExceptionState::~PythonExceptionState() {
- if (m_restore_on_exit)
- Restore();
-}
-
-void PythonExceptionState::Acquire(bool restore_on_exit) {
- // If a state is already acquired, the user needs to decide whether they want
- // to discard or restore it. Don't allow the potential silent loss of a
- // valid state.
- assert(!IsError());
-
- if (!HasErrorOccurred())
- return;
-
- PyObject *py_type = nullptr;
- PyObject *py_value = nullptr;
- PyObject *py_traceback = nullptr;
- PyErr_Fetch(&py_type, &py_value, &py_traceback);
- // PyErr_Fetch clears the error flag.
- assert(!HasErrorOccurred());
-
- // Ownership of the objects returned by `PyErr_Fetch` is transferred to us.
- m_type.Reset(PyRefType::Owned, py_type);
- m_value.Reset(PyRefType::Owned, py_value);
- m_traceback.Reset(PyRefType::Owned, py_traceback);
- m_restore_on_exit = restore_on_exit;
-}
-
-void PythonExceptionState::Restore() {
- if (m_type.IsValid()) {
- // The documentation for PyErr_Restore says "Do not pass a null type and
- // non-null value or traceback. So only restore if type was non-null to
- // begin with. In this case we're passing ownership back to Python so
- // release them all.
- PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
- }
-
- // After we restore, we should not hold onto the exception state. Demand
- // that it be re-acquired.
- Discard();
-}
-
-void PythonExceptionState::Discard() {
- m_type.Reset();
- m_value.Reset();
- m_traceback.Reset();
-}
-
-void PythonExceptionState::Reset() {
- if (m_restore_on_exit)
- Restore();
- else
- Discard();
-}
-
-bool PythonExceptionState::HasErrorOccurred() { return PyErr_Occurred(); }
-
-bool PythonExceptionState::IsError() const {
- return m_type.IsValid() || m_value.IsValid() || m_traceback.IsValid();
-}
-
-PythonObject PythonExceptionState::GetType() const { return m_type; }
-
-PythonObject PythonExceptionState::GetValue() const { return m_value; }
-
-PythonObject PythonExceptionState::GetTraceback() const { return m_traceback; }
-
-std::string PythonExceptionState::Format() const {
- // Don't allow this function to modify the error state.
- PythonExceptionState state(true);
-
- std::string backtrace = ReadBacktrace();
- if (!IsError())
- return std::string();
-
- // It's possible that ReadPythonBacktrace generated another exception. If
- // this happens we have to clear the exception, because otherwise
- // PyObject_Str() will assert below. That's why we needed to do the save /
- // restore at the beginning of this function.
- PythonExceptionState bt_error_state(false);
-
- std::string error_string;
- llvm::raw_string_ostream error_stream(error_string);
- error_stream << m_value.Str().GetString() << "\n";
-
- if (!bt_error_state.IsError()) {
- // If we were able to read the backtrace, just append it.
- error_stream << backtrace << "\n";
- } else {
- // Otherwise, append some information about why we were unable to obtain
- // the backtrace.
- PythonString bt_error = bt_error_state.GetValue().Str();
- error_stream << "An error occurred while retrieving the backtrace: "
- << bt_error.GetString() << "\n";
- }
- return error_stream.str();
-}
-
-std::string PythonExceptionState::ReadBacktrace() const {
- std::string retval("backtrace unavailable");
-
- auto traceback_module = PythonModule::ImportModule("traceback");
-#if PY_MAJOR_VERSION >= 3
- auto stringIO_module = PythonModule::ImportModule("io");
-#else
- auto stringIO_module = PythonModule::ImportModule("StringIO");
-#endif
- if (!m_traceback.IsAllocated())
- return retval;
-
- if (!traceback_module.IsAllocated() || !stringIO_module.IsAllocated())
- return retval;
-
- auto stringIO_builder =
- stringIO_module.ResolveName<PythonCallable>("StringIO");
- if (!stringIO_builder.IsAllocated())
- return retval;
-
- auto stringIO_buffer = stringIO_builder();
- if (!stringIO_buffer.IsAllocated())
- return retval;
-
- auto printTB = traceback_module.ResolveName<PythonCallable>("print_tb");
- if (!printTB.IsAllocated())
- return retval;
-
- auto printTB_result =
- printTB(m_traceback.get(), Py_None, stringIO_buffer.get());
- auto stringIO_getvalue =
- stringIO_buffer.ResolveName<PythonCallable>("getvalue");
- if (!stringIO_getvalue.IsAllocated())
- return retval;
-
- auto printTB_string = stringIO_getvalue().AsType<PythonString>();
- if (!printTB_string.IsAllocated())
- return retval;
-
- llvm::StringRef string_data(printTB_string.GetString());
- retval.assign(string_data.data(), string_data.size());
-
- return retval;
-}
-
-#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h b/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
deleted file mode 100644
index 3a88aa037776..000000000000
--- a/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- PythonExceptionState.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_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONEXCEPTIONSTATE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONEXCEPTIONSTATE_H
-
-#ifndef LLDB_DISABLE_PYTHON
-
-#include "PythonDataObjects.h"
-
-namespace lldb_private {
-
-class PythonExceptionState {
-public:
- explicit PythonExceptionState(bool restore_on_exit);
- ~PythonExceptionState();
-
- void Acquire(bool restore_on_exit);
-
- void Restore();
-
- void Discard();
-
- void Reset();
-
- static bool HasErrorOccurred();
-
- bool IsError() const;
-
- PythonObject GetType() const;
-
- PythonObject GetValue() const;
-
- PythonObject GetTraceback() const;
-
- std::string Format() const;
-
-private:
- std::string ReadBacktrace() const;
-
- bool m_restore_on_exit;
-
- PythonObject m_type;
- PythonObject m_value;
- PythonObject m_traceback;
-};
-}
-
-#endif
-
-#endif
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 2d2b68ceaaa6..3eee52184142 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -16,7 +16,6 @@
#include "lldb-python.h"
#include "PythonDataObjects.h"
-#include "PythonExceptionState.h"
#include "ScriptInterpreterPythonImpl.h"
#include "lldb/API/SBFrame.h"
@@ -45,6 +44,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatAdapters.h"
#include <memory>
#include <mutex>
@@ -54,6 +54,8 @@
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::python;
+using llvm::Expected;
// Defined in the SWIG source file
#if PY_MAJOR_VERSION >= 3
@@ -96,6 +98,8 @@ LLDBSwigPythonCreateCommandObject(const char *python_class_name,
extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
+ StructuredDataImpl *args_data,
+ std::string &error_string,
const lldb::ThreadPlanSP &thread_plan_sp);
extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
@@ -302,39 +306,26 @@ void ScriptInterpreterPython::ComputePythonDirForApple(
auto rend = llvm::sys::path::rend(path_ref);
auto framework = std::find(rbegin, rend, "LLDB.framework");
if (framework == rend) {
- ComputePythonDirForPosix(path);
+ ComputePythonDir(path);
return;
}
path.resize(framework - rend);
llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python");
}
-void ScriptInterpreterPython::ComputePythonDirForPosix(
+void ScriptInterpreterPython::ComputePythonDir(
llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::posix;
-#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
// Build the path by backing out of the lib dir, then building with whatever
// the real python interpreter uses. (e.g. lib for most, lib64 on RHEL
- // x86_64).
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR);
-#else
- llvm::sys::path::append(path, style,
- "python" + llvm::Twine(PY_MAJOR_VERSION) + "." +
- llvm::Twine(PY_MINOR_VERSION),
- "site-packages");
-#endif
-}
-
-void ScriptInterpreterPython::ComputePythonDirForWindows(
- llvm::SmallVectorImpl<char> &path) {
- auto style = llvm::sys::path::Style::windows;
- llvm::sys::path::remove_filename(path, style);
- llvm::sys::path::append(path, style, "lib", "site-packages");
+ // x86_64, or bin on Windows).
+ llvm::sys::path::remove_filename(path);
+ llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR);
+#if defined(_WIN32)
// This will be injected directly through FileSpec.GetDirectory().SetString(),
// so we need to normalize manually.
std::replace(path.begin(), path.end(), '\\', '/');
+#endif
}
FileSpec ScriptInterpreterPython::GetPythonDir() {
@@ -347,10 +338,8 @@ FileSpec ScriptInterpreterPython::GetPythonDir() {
#if defined(__APPLE__)
ComputePythonDirForApple(path);
-#elif defined(_WIN32)
- ComputePythonDirForWindows(path);
#else
- ComputePythonDirForPosix(path);
+ ComputePythonDir(path);
#endif
spec.GetDirectory().SetString(path);
return spec;
@@ -382,7 +371,7 @@ void ScriptInterpreterPython::Terminate() {}
ScriptInterpreterPythonImpl::Locker::Locker(
ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry,
- uint16_t on_leave, FILE *in, FILE *out, FILE *err)
+ uint16_t on_leave, FileSP in, FileSP out, FileSP err)
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
@@ -412,8 +401,8 @@ bool ScriptInterpreterPythonImpl::Locker::DoAcquireLock() {
}
bool ScriptInterpreterPythonImpl::Locker::DoInitSession(uint16_t on_entry_flags,
- FILE *in, FILE *out,
- FILE *err) {
+ FileSP in, FileSP out,
+ FileSP err) {
if (!m_python_interpreter)
return false;
return m_python_interpreter->EnterSession(on_entry_flags, in, out, err);
@@ -448,9 +437,9 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger)
m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(),
m_run_one_line_str_global(),
m_dictionary_name(m_debugger.GetInstanceName().AsCString()),
- m_terminal_state(), 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_command_thread_state(nullptr) {
+ 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_command_thread_state(nullptr) {
InitializePrivate();
m_dictionary_name.append("_dict");
@@ -535,7 +524,7 @@ def function (frame, bp_loc, internal_dict):
}
if (instructions) {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp && interactive) {
output_sp->PutCString(instructions);
output_sp->Flush();
@@ -558,7 +547,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
if (!bp_options)
continue;
- auto data_up = llvm::make_unique<CommandDataPython>();
+ auto data_up = std::make_unique<CommandDataPython>();
if (!data_up)
break;
data_up->user_source.SplitIntoLines(data);
@@ -571,7 +560,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
bp_options->SetCallback(
ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
if (error_sp) {
error_sp->Printf("Warning: No command attached to breakpoint.\n");
error_sp->Flush();
@@ -583,7 +572,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
case eIOHandlerWatchpoint: {
WatchpointOptions *wp_options =
(WatchpointOptions *)io_handler.GetUserData();
- auto data_up = llvm::make_unique<WatchpointOptions::CommandData>();
+ auto data_up = std::make_unique<WatchpointOptions::CommandData>();
data_up->user_source.SplitIntoLines(data);
if (GenerateWatchpointCommandCallbackData(data_up->user_source,
@@ -593,7 +582,7 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler,
wp_options->SetCallback(
ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp);
} else if (!batch_mode) {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
if (error_sp) {
error_sp->Printf("Warning: No command attached to breakpoint.\n");
error_sp->Flush();
@@ -609,29 +598,15 @@ ScriptInterpreterPythonImpl::CreateInstance(Debugger &debugger) {
return std::make_shared<ScriptInterpreterPythonImpl>(debugger);
}
-void ScriptInterpreterPythonImpl::ResetOutputFileHandle(FILE *fh) {}
-
-void ScriptInterpreterPythonImpl::SaveTerminalState(int fd) {
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state on
- // the input file handle.
- m_terminal_state.Save(fd, false);
-}
-
-void ScriptInterpreterPythonImpl::RestoreTerminalState() {
- // Python mucks with the terminal state of STDIN. If we can possibly avoid
- // this by setting the file handles up correctly prior to entering the
- // interpreter we should. For now we save and restore the terminal state on
- // the input file handle.
- m_terminal_state.Restore();
-}
-
void ScriptInterpreterPythonImpl::LeaveSession() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (log)
log->PutCString("ScriptInterpreterPythonImpl::LeaveSession()");
+ // Unset the LLDB global variables.
+ PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
+ "= None; lldb.thread = None; lldb.frame = None");
+
// checking that we have a valid thread state - since we use our own
// threading and locking in some (rare) cases during cleanup Python may end
// up believing we have no thread state and PyImport_AddModule will crash if
@@ -662,45 +637,52 @@ void ScriptInterpreterPythonImpl::LeaveSession() {
m_session_is_active = false;
}
-bool ScriptInterpreterPythonImpl::SetStdHandle(File &file, const char *py_name,
- PythonFile &save_file,
+bool ScriptInterpreterPythonImpl::SetStdHandle(FileSP file_sp,
+ const char *py_name,
+ PythonObject &save_file,
const char *mode) {
- if (file.IsValid()) {
- // Flush the file before giving it to python to avoid interleaved output.
- file.Flush();
+ if (!file_sp || !*file_sp) {
+ save_file.Reset();
+ return false;
+ }
+ File &file = *file_sp;
- PythonDictionary &sys_module_dict = GetSysModuleDictionary();
+ // Flush the file before giving it to python to avoid interleaved output.
+ file.Flush();
- save_file = sys_module_dict.GetItemForKey(PythonString(py_name))
- .AsType<PythonFile>();
+ PythonDictionary &sys_module_dict = GetSysModuleDictionary();
- PythonFile new_file(file, mode);
- sys_module_dict.SetItemForKey(PythonString(py_name), new_file);
- return true;
- } else
- save_file.Reset();
- return false;
+ auto new_file = PythonFile::FromFile(file, mode);
+ if (!new_file) {
+ llvm::consumeError(new_file.takeError());
+ return false;
+ }
+
+ save_file = sys_module_dict.GetItemForKey(PythonString(py_name));
+
+ sys_module_dict.SetItemForKey(PythonString(py_name), new_file.get());
+ return true;
}
bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
- FILE *in, FILE *out, FILE *err) {
+ FileSP in_sp, FileSP out_sp,
+ FileSP err_sp) {
// If we have already entered the session, without having officially 'left'
// it, then there is no need to 'enter' it again.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT));
if (m_session_is_active) {
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
- ") session is already active, returning without doing anything",
- on_entry_flags);
+ LLDB_LOGF(
+ log,
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
+ ") session is already active, returning without doing anything",
+ on_entry_flags);
return false;
}
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16
- ")",
- on_entry_flags);
+ LLDB_LOGF(
+ log,
+ "ScriptInterpreterPythonImpl::EnterSession(on_entry_flags=0x%" PRIx16 ")",
+ on_entry_flags);
m_session_is_active = true;
@@ -733,33 +715,29 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
PythonDictionary &sys_module_dict = GetSysModuleDictionary();
if (sys_module_dict.IsValid()) {
- File in_file(in, false);
- File out_file(out, false);
- File err_file(err, false);
-
- lldb::StreamFileSP in_sp;
- lldb::StreamFileSP out_sp;
- lldb::StreamFileSP err_sp;
- if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid())
- m_debugger.AdoptTopIOHandlerFilesIfInvalid(in_sp, out_sp, err_sp);
+ lldb::FileSP top_in_sp;
+ lldb::StreamFileSP top_out_sp, top_err_sp;
+ if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp)
+ m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp,
+ top_err_sp);
if (on_entry_flags & Locker::NoSTDIN) {
m_saved_stdin.Reset();
} else {
- if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) {
- if (in_sp)
- SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r");
+ if (!SetStdHandle(in_sp, "stdin", m_saved_stdin, "r")) {
+ if (top_in_sp)
+ SetStdHandle(top_in_sp, "stdin", m_saved_stdin, "r");
}
}
- if (!SetStdHandle(out_file, "stdout", m_saved_stdout, "w")) {
- if (out_sp)
- SetStdHandle(out_sp->GetFile(), "stdout", m_saved_stdout, "w");
+ if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) {
+ if (top_out_sp)
+ SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w");
}
- if (!SetStdHandle(err_file, "stderr", m_saved_stderr, "w")) {
- if (err_sp)
- SetStdHandle(err_sp->GetFile(), "stderr", m_saved_stderr, "w");
+ if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) {
+ if (top_err_sp)
+ SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w");
}
}
@@ -769,9 +747,9 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
return true;
}
-PythonObject &ScriptInterpreterPythonImpl::GetMainModule() {
+PythonModule &ScriptInterpreterPythonImpl::GetMainModule() {
if (!m_main_module.IsValid())
- m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
+ m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__"));
return m_main_module;
}
@@ -788,19 +766,16 @@ PythonDictionary &ScriptInterpreterPythonImpl::GetSessionDictionary() {
if (!main_dict.IsValid())
return m_session_dict;
- PythonObject item = main_dict.GetItemForKey(PythonString(m_dictionary_name));
- m_session_dict.Reset(PyRefType::Borrowed, item.get());
+ m_session_dict = unwrapIgnoringErrors(
+ As<PythonDictionary>(main_dict.GetItem(m_dictionary_name)));
return m_session_dict;
}
PythonDictionary &ScriptInterpreterPythonImpl::GetSysModuleDictionary() {
if (m_sys_module_dict.IsValid())
return m_sys_module_dict;
-
- PythonObject sys_module(PyRefType::Borrowed, PyImport_AddModule("sys"));
- if (sys_module.IsValid())
- m_sys_module_dict.Reset(PyRefType::Borrowed,
- PyModule_GetDict(sys_module.get()));
+ PythonModule sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
+ m_sys_module_dict = sys_module.GetDictionary();
return m_sys_module_dict;
}
@@ -867,7 +842,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
// directly down to Python.
Debugger &debugger = m_debugger;
- StreamFileSP input_file_sp;
+ FileSP input_file_sp;
StreamFileSP output_file_sp;
StreamFileSP error_file_sp;
Communication output_comm(
@@ -875,7 +850,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
bool join_read_thread = false;
if (options.GetEnableIO()) {
if (result) {
- input_file_sp = debugger.GetInputFile();
+ input_file_sp = debugger.GetInputFileSP();
// Set output to a temporary file so we can forward the results on to
// the result object
@@ -906,9 +881,9 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
::setbuf(outfile_handle, nullptr);
result->SetImmediateOutputFile(
- debugger.GetOutputFile()->GetFile().GetStream());
+ debugger.GetOutputStream().GetFileSP());
result->SetImmediateErrorFile(
- debugger.GetErrorFile()->GetFile().GetStream());
+ debugger.GetErrorStream().GetFileSP());
}
}
}
@@ -916,22 +891,26 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp,
error_file_sp);
} else {
- input_file_sp = std::make_shared<StreamFile>();
- FileSystem::Instance().Open(input_file_sp->GetFile(),
+ auto nullin = FileSystem::Instance().Open(
FileSpec(FileSystem::DEV_NULL),
File::eOpenOptionRead);
-
- output_file_sp = std::make_shared<StreamFile>();
- FileSystem::Instance().Open(output_file_sp->GetFile(),
+ auto nullout = FileSystem::Instance().Open(
FileSpec(FileSystem::DEV_NULL),
File::eOpenOptionWrite);
-
- error_file_sp = output_file_sp;
+ 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()));
}
- FILE *in_file = input_file_sp->GetFile().GetStream();
- FILE *out_file = output_file_sp->GetFile().GetStream();
- FILE *err_file = error_file_sp->GetFile().GetStream();
bool success = false;
{
// WARNING! It's imperative that this RAII scope be as tight as
@@ -947,8 +926,8 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
Locker::AcquireLock | Locker::InitSession |
(options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
((result && result->GetInteractive()) ? 0 : Locker::NoSTDIN),
- Locker::FreeAcquiredLock | Locker::TearDownSession, in_file, out_file,
- err_file);
+ Locker::FreeAcquiredLock | Locker::TearDownSession, input_file_sp,
+ output_file_sp->GetFileSP(), error_file_sp->GetFileSP());
// Find the correct script interpreter dictionary in the main module.
PythonDictionary &session_dict = GetSessionDictionary();
@@ -975,9 +954,8 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
}
// Flush our output and error file handles
- ::fflush(out_file);
- if (out_file != err_file)
- ::fflush(err_file);
+ output_file_sp->Flush();
+ error_file_sp->Flush();
}
if (join_read_thread) {
@@ -1020,7 +998,7 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
// a running interpreter loop inside the already running Python interpreter
// loop, so we won't do it.
- if (!debugger.GetInputFile()->GetFile().IsValid())
+ if (!debugger.GetInputFile().IsValid())
return;
IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this));
@@ -1040,19 +1018,19 @@ bool ScriptInterpreterPythonImpl::Interrupt() {
long tid = state->thread_id;
PyThreadState_Swap(state);
int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
- if (log)
- log->Printf("ScriptInterpreterPythonImpl::Interrupt() sending "
- "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
- tid, num_threads);
+ LLDB_LOGF(log,
+ "ScriptInterpreterPythonImpl::Interrupt() sending "
+ "PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...",
+ tid, num_threads);
return true;
}
}
- if (log)
- log->Printf(
- "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
- "can't interrupt");
+ LLDB_LOGF(log,
+ "ScriptInterpreterPythonImpl::Interrupt() python code not running, "
+ "can't interrupt");
return false;
}
+
bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
void *ret_value, const ExecuteScriptOptions &options) {
@@ -1063,152 +1041,111 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession);
- PythonObject py_return;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed,
- PyModule_GetDict(main_module.get()));
- PythonObject py_error;
- bool ret_success = false;
- int success;
+ PythonModule &main_module = GetMainModule();
+ PythonDictionary globals = main_module.GetDictionary();
PythonDictionary locals = GetSessionDictionary();
-
- if (!locals.IsValid()) {
- locals.Reset(
- PyRefType::Owned,
- PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
- }
-
+ if (!locals.IsValid())
+ locals = unwrapIgnoringErrors(
+ As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
if (!locals.IsValid())
locals = globals;
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- std::string as_string = in_string.str();
- { // scope for PythonInputReaderManager
- // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
- py_return.Reset(PyRefType::Owned,
- PyRun_String(as_string.c_str(), Py_eval_input,
- globals.get(), locals.get()));
- if (!py_return.IsValid()) {
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
-
- py_return.Reset(PyRefType::Owned,
- PyRun_String(as_string.c_str(), Py_single_input,
- globals.get(), locals.get()));
- }
+ Expected<PythonObject> maybe_py_return =
+ runStringOneLine(in_string, globals, locals);
+
+ if (!maybe_py_return) {
+ llvm::handleAllErrors(
+ maybe_py_return.takeError(),
+ [&](PythonException &E) {
+ E.Restore();
+ if (options.GetMaskoutErrors()) {
+ if (E.Matches(PyExc_SyntaxError)) {
+ PyErr_Print();
+ }
+ PyErr_Clear();
+ }
+ },
+ [](const llvm::ErrorInfoBase &E) {});
+ return false;
}
- if (py_return.IsValid()) {
- switch (return_type) {
- case eScriptReturnTypeCharPtr: // "char *"
- {
- const char format[3] = "s#";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
- // Py_None
- {
- const char format[3] = "z";
- success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
- break;
- }
- case eScriptReturnTypeBool: {
- const char format[2] = "b";
- success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
- break;
- }
- case eScriptReturnTypeShortInt: {
- const char format[2] = "h";
- success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
- break;
- }
- case eScriptReturnTypeShortIntUnsigned: {
- const char format[2] = "H";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
- break;
- }
- case eScriptReturnTypeInt: {
- const char format[2] = "i";
- success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
- break;
- }
- case eScriptReturnTypeIntUnsigned: {
- const char format[2] = "I";
- success = PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
- break;
- }
- case eScriptReturnTypeLongInt: {
- const char format[2] = "l";
- success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongIntUnsigned: {
- const char format[2] = "k";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLong: {
- const char format[2] = "L";
- success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
- break;
- }
- case eScriptReturnTypeLongLongUnsigned: {
- const char format[2] = "K";
- success =
- PyArg_Parse(py_return.get(), format, (unsigned long long *)ret_value);
- break;
- }
- case eScriptReturnTypeFloat: {
- const char format[2] = "f";
- success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
- break;
- }
- case eScriptReturnTypeDouble: {
- const char format[2] = "d";
- success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
- break;
- }
- case eScriptReturnTypeChar: {
- const char format[2] = "c";
- success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
- break;
- }
- case eScriptReturnTypeOpaqueObject: {
- success = true;
- PyObject *saved_value = py_return.get();
- Py_XINCREF(saved_value);
- *((PyObject **)ret_value) = saved_value;
- break;
- }
- }
+ PythonObject py_return = std::move(maybe_py_return.get());
+ assert(py_return.IsValid());
- ret_success = success;
+ switch (return_type) {
+ case eScriptReturnTypeCharPtr: // "char *"
+ {
+ const char format[3] = "s#";
+ return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ }
+ case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
+ // Py_None
+ {
+ const char format[3] = "z";
+ return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+ }
+ case eScriptReturnTypeBool: {
+ const char format[2] = "b";
+ return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
+ }
+ case eScriptReturnTypeShortInt: {
+ const char format[2] = "h";
+ return PyArg_Parse(py_return.get(), format, (short *)ret_value);
+ }
+ case eScriptReturnTypeShortIntUnsigned: {
+ const char format[2] = "H";
+ return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
+ }
+ case eScriptReturnTypeInt: {
+ const char format[2] = "i";
+ return PyArg_Parse(py_return.get(), format, (int *)ret_value);
+ }
+ case eScriptReturnTypeIntUnsigned: {
+ const char format[2] = "I";
+ return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
+ }
+ case eScriptReturnTypeLongInt: {
+ const char format[2] = "l";
+ return PyArg_Parse(py_return.get(), format, (long *)ret_value);
+ }
+ case eScriptReturnTypeLongIntUnsigned: {
+ const char format[2] = "k";
+ return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
+ }
+ case eScriptReturnTypeLongLong: {
+ const char format[2] = "L";
+ return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
+ }
+ case eScriptReturnTypeLongLongUnsigned: {
+ const char format[2] = "K";
+ return PyArg_Parse(py_return.get(), format,
+ (unsigned long long *)ret_value);
+ }
+ case eScriptReturnTypeFloat: {
+ const char format[2] = "f";
+ return PyArg_Parse(py_return.get(), format, (float *)ret_value);
+ }
+ case eScriptReturnTypeDouble: {
+ const char format[2] = "d";
+ return PyArg_Parse(py_return.get(), format, (double *)ret_value);
+ }
+ case eScriptReturnTypeChar: {
+ const char format[2] = "c";
+ return PyArg_Parse(py_return.get(), format, (char *)ret_value);
+ }
+ case eScriptReturnTypeOpaqueObject: {
+ *((PyObject **)ret_value) = py_return.release();
+ return true;
}
-
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid()) {
- ret_success = false;
- if (options.GetMaskoutErrors()) {
- if (PyErr_GivenExceptionMatches(py_error.get(), PyExc_SyntaxError))
- PyErr_Print();
- PyErr_Clear();
- }
}
-
- return ret_success;
}
Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
const char *in_string, const ExecuteScriptOptions &options) {
- Status error;
+
+ if (in_string == nullptr)
+ return Status();
Locker locker(this,
Locker::AcquireLock | Locker::InitSession |
@@ -1216,52 +1153,32 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
Locker::NoSTDIN,
Locker::FreeAcquiredLock | Locker::TearDownSession);
- PythonObject return_value;
- PythonObject &main_module = GetMainModule();
- PythonDictionary globals(PyRefType::Borrowed,
- PyModule_GetDict(main_module.get()));
- PythonObject py_error;
+ PythonModule &main_module = GetMainModule();
+ PythonDictionary globals = main_module.GetDictionary();
PythonDictionary locals = GetSessionDictionary();
-
if (!locals.IsValid())
- locals.Reset(
- PyRefType::Owned,
- PyObject_GetAttrString(globals.get(), m_dictionary_name.c_str()));
-
+ locals = unwrapIgnoringErrors(
+ As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
if (!locals.IsValid())
locals = globals;
- py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
- if (py_error.IsValid())
- PyErr_Clear();
+ Expected<PythonObject> return_value =
+ runStringMultiLine(in_string, globals, locals);
- if (in_string != nullptr) {
- PythonObject code_object;
- code_object.Reset(PyRefType::Owned,
- Py_CompileString(in_string, "temp.py", Py_file_input));
-
- if (code_object.IsValid()) {
-// In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
-// takes a PyObject. They are convertible (hence the function
-// PyCode_Check(PyObject*), so we have to do the cast for Python 2.x
-#if PY_MAJOR_VERSION >= 3
- PyObject *py_code_obj = code_object.get();
-#else
- PyCodeObject *py_code_obj =
- reinterpret_cast<PyCodeObject *>(code_object.get());
-#endif
- return_value.Reset(
- PyRefType::Owned,
- PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
- }
+ if (!return_value) {
+ llvm::Error error =
+ llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
+ llvm::Error error = llvm::createStringError(
+ llvm::inconvertibleErrorCode(), E.ReadBacktrace());
+ if (!options.GetMaskoutErrors())
+ E.Restore();
+ return error;
+ });
+ return Status(std::move(error));
}
- PythonExceptionState exception_state(!options.GetMaskoutErrors());
- if (exception_state.IsError())
- error.SetErrorString(exception_state.Format().c_str());
-
- return error;
+ return Status();
}
void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
@@ -1308,7 +1225,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
// Set a Python one-liner as the callback for the breakpoint.
Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
BreakpointOptions *bp_options, const char *command_body_text) {
- auto data_up = llvm::make_unique<CommandDataPython>();
+ auto data_up = std::make_unique<CommandDataPython>();
// Split the command_body_text into lines, and pass that to
// GenerateBreakpointCommandCallbackData. That will wrap the body in an
@@ -1331,7 +1248,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
// Set a Python one-liner as the callback for the watchpoint.
void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback(
WatchpointOptions *wp_options, const char *oneliner) {
- auto data_up = llvm::make_unique<WatchpointOptions::CommandData>();
+ auto data_up = std::make_unique<WatchpointOptions::CommandData>();
// It's necessary to set both user_source and script_source to the oneliner.
// The former is used to generate callback description (as in watchpoint
@@ -1853,12 +1770,14 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
}
StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
- const char *class_name, lldb::ThreadPlanSP thread_plan_sp) {
+ const char *class_name, StructuredDataImpl *args_data,
+ std::string &error_str,
+ lldb::ThreadPlanSP thread_plan_sp) {
if (class_name == nullptr || class_name[0] == '\0')
return StructuredData::ObjectSP();
if (!thread_plan_sp.get())
- return StructuredData::ObjectSP();
+ return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
@@ -1866,17 +1785,18 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
if (!script_interpreter)
- return StructuredData::ObjectSP();
+ return {};
void *ret_val;
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
-
ret_val = LLDBSwigPythonCreateScriptedThreadPlan(
class_name, python_interpreter->m_dictionary_name.c_str(),
- thread_plan_sp);
+ args_data, error_str, thread_plan_sp);
+ if (!ret_val)
+ return {};
}
return StructuredData::ObjectSP(new StructuredPythonObject(ret_val));
@@ -2052,15 +1972,22 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
if (!generic)
return StructuredData::DictionarySP();
- PythonObject reply_pyobj;
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
TargetSP target_sp(target->shared_from_this());
- reply_pyobj.Reset(PyRefType::Owned,
- (PyObject *)LLDBSWIGPython_GetDynamicSetting(
- generic->GetValue(), setting_name, target_sp));
- PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
+ auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting(
+ generic->GetValue(), setting_name, target_sp);
+
+ if (!setting)
+ return StructuredData::DictionarySP();
+
+ PythonDictionary py_dict =
+ unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
+
+ if (!py_dict)
+ return StructuredData::DictionarySP();
+
return py_dict.CreateStructuredDictionary();
}
@@ -2230,18 +2157,6 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
return ret_val;
}
-void ScriptInterpreterPythonImpl::Clear() {
- // Release any global variables that might have strong references to
- // LLDB objects when clearing the python script interpreter.
- Locker locker(this, Locker::AcquireLock, Locker::FreeAcquiredLock);
-
- // This may be called as part of Py_Finalize. In that case the modules are
- // destroyed in random order and we can't guarantee that we can access these.
- if (Py_IsInitialized())
- PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process "
- "= None; lldb.thread = None; lldb.frame = None");
-}
-
bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index 24941ec77452..33ae308041b2 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -48,8 +48,7 @@ public:
protected:
static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
- static void ComputePythonDirForPosix(llvm::SmallVectorImpl<char> &path);
- static void ComputePythonDirForWindows(llvm::SmallVectorImpl<char> &path);
+ static void ComputePythonDir(llvm::SmallVectorImpl<char> &path);
};
} // namespace lldb_private
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index a9993c4068a2..929567e579d8 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -78,6 +78,8 @@ public:
StructuredData::ObjectSP
CreateScriptedThreadPlan(const char *class_name,
+ StructuredDataImpl *args_data,
+ std::string &error_str,
lldb::ThreadPlanSP thread_plan) override;
bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
@@ -188,8 +190,6 @@ public:
const TypeSummaryOptions &options,
std::string &retval) override;
- void Clear() override;
-
bool GetDocumentationForItem(const char *item, std::string &dest) override;
bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
@@ -256,8 +256,6 @@ public:
void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
const char *oneliner) override;
- void ResetOutputFileHandle(FILE *new_fh) override;
-
const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
PyThreadState *GetThreadState() { return m_command_thread_state; }
@@ -296,17 +294,19 @@ public:
TearDownSession = 0x0004
};
- Locker(ScriptInterpreterPythonImpl *py_interpreter = nullptr,
+ Locker(ScriptInterpreterPythonImpl *py_interpreter,
uint16_t on_entry = AcquireLock | InitSession,
- uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
- FILE *out = nullptr, FILE *err = nullptr);
+ uint16_t on_leave = FreeLock | TearDownSession,
+ lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
+ lldb::FileSP err = nullptr);
~Locker() override;
private:
bool DoAcquireLock();
- bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+ bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
+ lldb::FileSP out, lldb::FileSP err);
bool DoFreeLock();
@@ -314,7 +314,6 @@ public:
bool m_teardown_session;
ScriptInterpreterPythonImpl *m_python_interpreter;
- // FILE* m_tmp_fh;
PyGILState_STATE m_GILState;
};
@@ -343,14 +342,11 @@ public:
static void AddToSysPath(AddLocation location, std::string path);
- bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);
+ bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
+ lldb::FileSP err);
void LeaveSession();
- void SaveTerminalState(int fd);
-
- void RestoreTerminalState();
-
uint32_t IsExecutingPython() const { return m_lock_count > 0; }
uint32_t IncrementLockCount() { return ++m_lock_count; }
@@ -367,27 +363,26 @@ public:
eIOHandlerWatchpoint
};
- PythonObject &GetMainModule();
+ python::PythonModule &GetMainModule();
- PythonDictionary &GetSessionDictionary();
+ python::PythonDictionary &GetSessionDictionary();
- PythonDictionary &GetSysModuleDictionary();
+ python::PythonDictionary &GetSysModuleDictionary();
bool GetEmbeddedInterpreterModuleObjects();
- bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
- const char *mode);
-
- PythonFile m_saved_stdin;
- PythonFile m_saved_stdout;
- PythonFile m_saved_stderr;
- PythonObject m_main_module;
- PythonDictionary m_session_dict;
- PythonDictionary m_sys_module_dict;
- PythonObject m_run_one_line_function;
- PythonObject m_run_one_line_str_global;
+ bool SetStdHandle(lldb::FileSP file, const char *py_name,
+ python::PythonObject &save_file, const char *mode);
+
+ python::PythonObject m_saved_stdin;
+ python::PythonObject m_saved_stdout;
+ python::PythonObject m_saved_stderr;
+ python::PythonModule m_main_module;
+ python::PythonDictionary m_session_dict;
+ python::PythonDictionary m_sys_module_dict;
+ python::PythonObject m_run_one_line_function;
+ python::PythonObject m_run_one_line_str_global;
std::string m_dictionary_name;
- TerminalState m_terminal_state;
ActiveIOHandler m_active_io_handler;
bool m_session_is_active;
bool m_pty_slave_is_open;
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index 81a27125c036..c6b234baa8c8 100644
--- a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -104,30 +104,13 @@ void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
/// Code to handle the StructuredDataDarwinLog settings
-static constexpr PropertyDefinition g_properties[] = {
- {
- "enable-on-startup", // name
- OptionValue::eTypeBoolean, // type
- true, // global
- false, // default uint value
- nullptr, // default cstring value
- {}, // enum values
- "Enable Darwin os_log collection when debugged process is launched "
- "or attached." // description
- },
- {
- "auto-enable-options", // name
- OptionValue::eTypeString, // type
- true, // global
- 0, // default uint value
- "", // default cstring value
- {}, // enum values
- "Specify the options to 'plugin structured-data darwin-log enable' "
- "that should be applied when automatically enabling logging on "
- "startup/attach." // description
- }};
-
-enum { ePropertyEnableOnStartup = 0, ePropertyAutoEnableOptions = 1 };
+#define LLDB_PROPERTIES_darwinlog
+#include "StructuredDataDarwinLogProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_darwinlog
+#include "StructuredDataDarwinLogPropertiesEnum.inc"
+};
class StructuredDataDarwinLogProperties : public Properties {
public:
@@ -138,7 +121,7 @@ public:
StructuredDataDarwinLogProperties() : Properties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_darwinlog_properties);
}
~StructuredDataDarwinLogProperties() override {}
@@ -146,13 +129,13 @@ public:
bool GetEnableOnStartup() const {
const uint32_t idx = ePropertyEnableOnStartup;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_darwinlog_properties[idx].default_uint_value != 0);
}
llvm::StringRef GetAutoEnableOptions() const {
const uint32_t idx = ePropertyAutoEnableOptions;
return m_collection_sp->GetPropertyAtIndexAsString(
- nullptr, idx, g_properties[idx].default_cstr_value);
+ nullptr, idx, g_darwinlog_properties[idx].default_cstr_value);
}
const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; }
@@ -305,11 +288,8 @@ private:
// Instantiate the regex so we can report any errors.
auto regex = RegularExpression(op_arg);
- if (!regex.IsValid()) {
- char error_text[256];
- error_text[0] = '\0';
- regex.GetErrorAsCString(error_text, sizeof(error_text));
- error.SetErrorString(error_text);
+ if (llvm::Error err = regex.GetError()) {
+ error.SetErrorString(llvm::toString(std::move(err)));
return FilterRuleSP();
}
@@ -807,15 +787,10 @@ protected:
// Now check if we have a running process. If so, we should instruct the
// process monitor to enable/disable DarwinLog support now.
- Target *target = GetSelectedOrDummyTarget();
- if (!target) {
- // No target, so there is nothing more to do right now.
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ Target &target = GetSelectedOrDummyTarget();
// Grab the active process.
- auto process_sp = target->GetProcessSP();
+ auto process_sp = target.GetProcessSP();
if (!process_sp) {
// No active process, so there is nothing more to do right now.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -897,9 +872,9 @@ protected:
// Figure out if we've got a process. If so, we can tell if DarwinLog is
// available for that process.
- Target *target = GetSelectedOrDummyTarget();
- auto process_sp = target ? target->GetProcessSP() : ProcessSP();
- if (!target || !process_sp) {
+ Target &target = GetSelectedOrDummyTarget();
+ auto process_sp = target.GetProcessSP();
+ if (!process_sp) {
stream.PutCString("Availability: unknown (requires process)\n");
stream.PutCString("Enabled: not applicable "
"(requires process)\n");
@@ -1119,26 +1094,26 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
object_sp->Dump(json_stream);
else
json_stream.PutCString("<null>");
- log->Printf("StructuredDataDarwinLog::%s() called with json: %s",
- __FUNCTION__, json_stream.GetData());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called with json: %s",
+ __FUNCTION__, json_stream.GetData());
}
// Ignore empty structured data.
if (!object_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() StructuredData object "
- "is null",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() StructuredData object "
+ "is null",
+ __FUNCTION__);
return;
}
// Ignore any data that isn't for us.
if (type_name != GetDarwinLogTypeName()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() StructuredData type "
- "expected to be %s but was %s, ignoring",
- __FUNCTION__, GetDarwinLogTypeName().AsCString(),
- type_name.AsCString());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() StructuredData type "
+ "expected to be %s but was %s, ignoring",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ type_name.AsCString());
return;
}
@@ -1148,9 +1123,8 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
auto options_sp = GetGlobalEnableOptions(debugger_sp);
if (options_sp && options_sp->GetBroadcastEvents()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() broadcasting event",
- __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() broadcasting event",
+ __FUNCTION__);
process.BroadcastStructuredData(object_sp, shared_from_this());
}
@@ -1263,19 +1237,18 @@ void StructuredDataDarwinLog::SetEnabled(bool enabled) {
void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
ModuleList &module_list) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s called (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
// Check if we should enable the darwin log support on startup/attach.
if (!GetGlobalProperties()->GetEnableOnStartup() &&
!s_is_explicitly_enabled) {
// We're neither auto-enabled or explicitly enabled, so we shouldn't try to
// enable here.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s not applicable, we're not "
- "enabled (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s not applicable, we're not "
+ "enabled (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1283,10 +1256,10 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
{
std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
if (m_added_breakpoint) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s process uid %u's "
- "post-libtrace-init breakpoint is already set",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s process uid %u's "
+ "post-libtrace-init breakpoint is already set",
+ __FUNCTION__, process.GetUniqueID());
return;
}
}
@@ -1298,11 +1271,11 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
GetGlobalProperties()->GetLoggingModuleName();
if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
// We need this. Bail.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s no logging module name "
- "specified, we don't know where to set a breakpoint "
- "(process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s no logging module name "
+ "specified, we don't know where to set a breakpoint "
+ "(process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1324,23 +1297,23 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
}
if (!found_logging_support_module) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s logging module %s "
- "has not yet been loaded, can't set a breakpoint "
- "yet (process uid %u)",
- __FUNCTION__, logging_module_name.AsCString(),
- process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s logging module %s "
+ "has not yet been loaded, can't set a breakpoint "
+ "yet (process uid %u)",
+ __FUNCTION__, logging_module_name.AsCString(),
+ process.GetUniqueID());
return;
}
// Time to enqueue the breakpoint so we can wait for logging support to be
// initialized before we try to tap the libtrace stream.
AddInitCompletionHook(process);
- if (log)
- log->Printf("StructuredDataDarwinLog::%s post-init hook breakpoint "
- "set for logging module %s (process uid %u)",
- __FUNCTION__, logging_module_name.AsCString(),
- process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s post-init hook breakpoint "
+ "set for logging module %s (process uid %u)",
+ __FUNCTION__, logging_module_name.AsCString(),
+ process.GetUniqueID());
// We need to try the enable here as well, which will succeed in the event
// that we're attaching to (rather than launching) the process and the
@@ -1519,38 +1492,36 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
// we can execute our logic to enable the logging support.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
// Get the current thread.
if (!context) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: no context, "
- "ignoring",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: no context, "
+ "ignoring",
+ __FUNCTION__);
return false;
}
// Get the plugin from the process.
auto process_sp = context->exe_ctx_ref.GetProcessSP();
if (!process_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: invalid "
- "process in context, ignoring",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: invalid "
+ "process in context, ignoring",
+ __FUNCTION__);
return false;
}
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() call is for process uid %d",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %d",
+ __FUNCTION__, process_sp->GetUniqueID());
auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
if (!plugin_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: no plugin for "
- "feature %s in process uid %u",
- __FUNCTION__, GetDarwinLogTypeName().AsCString(),
- process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: no plugin for "
+ "feature %s in process uid %u",
+ __FUNCTION__, GetDarwinLogTypeName().AsCString(),
+ process_sp->GetUniqueID());
return false;
}
@@ -1561,51 +1532,51 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
std::weak_ptr<StructuredDataPlugin> plugin_wp(plugin_sp);
ThreadPlanCallOnFunctionExit::Callback callback =
[plugin_wp, &called_enable_method, log, process_uid]() {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "called (process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "called (process uid %u)",
+ process_uid);
auto strong_plugin_sp = plugin_wp.lock();
if (!strong_plugin_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "plugin no longer exists, ignoring (process "
- "uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "plugin no longer exists, ignoring (process "
+ "uid %u)",
+ process_uid);
return;
}
// Make sure we only call it once, just in case the thread plan hits
// the breakpoint twice.
if (!called_enable_method) {
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "calling EnableNow() (process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "calling EnableNow() (process uid %u)",
+ process_uid);
static_cast<StructuredDataDarwinLog *>(strong_plugin_sp.get())
->EnableNow();
called_enable_method = true;
} else {
// Our breakpoint was hit more than once. Unexpected but no harm
// done. Log it.
- if (log)
- log->Printf("StructuredDataDarwinLog::post-init callback: "
- "skipping EnableNow(), already called by "
- "callback [we hit this more than once] "
- "(process uid %u)",
- process_uid);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::post-init callback: "
+ "skipping EnableNow(), already called by "
+ "callback [we hit this more than once] "
+ "(process uid %u)",
+ process_uid);
}
};
// Grab the current thread.
auto thread_sp = context->exe_ctx_ref.GetThreadSP();
if (!thread_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
- "retrieve the current thread from the execution "
- "context, nowhere to run the thread plan (process uid "
- "%u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to "
+ "retrieve the current thread from the execution "
+ "context, nowhere to run the thread plan (process uid "
+ "%u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return false;
}
@@ -1614,10 +1585,10 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
ThreadPlanSP(new ThreadPlanCallOnFunctionExit(*thread_sp, callback));
const bool abort_other_plans = false;
thread_sp->QueueThreadPlan(thread_plan_sp, abort_other_plans);
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() queuing thread plan on "
- "trace library init method entry (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() queuing thread plan on "
+ "trace library init method entry (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
// We return false here to indicate that it isn't a public stop.
return false;
@@ -1625,18 +1596,17 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback(
void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
// Make sure we haven't already done this.
{
std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
if (m_added_breakpoint) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() ignoring request, "
- "breakpoint already set (process uid %u)",
- __FUNCTION__, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() ignoring request, "
+ "breakpoint already set (process uid %u)",
+ __FUNCTION__, process.GetUniqueID());
return;
}
@@ -1669,22 +1639,22 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
eLanguageTypeC, offset, skip_prologue, internal, hardware);
if (!breakpoint_sp) {
// Huh? Bail here.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() failed to set "
- "breakpoint in module %s, function %s (process uid %u)",
- __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
- func_name, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() failed to set "
+ "breakpoint in module %s, function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
return;
}
// Set our callback.
breakpoint_sp->SetCallback(InitCompletionHookCallback, nullptr);
m_breakpoint_id = breakpoint_sp->GetID();
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() breakpoint set in module %s,"
- "function %s (process uid %u)",
- __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
- func_name, process.GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() breakpoint set in module %s,"
+ "function %s (process uid %u)",
+ __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(),
+ func_name, process.GetUniqueID());
}
void StructuredDataDarwinLog::DumpTimestamp(Stream &stream,
@@ -1825,22 +1795,20 @@ size_t StructuredDataDarwinLog::HandleDisplayOfEvent(
void StructuredDataDarwinLog::EnableNow() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() called", __FUNCTION__);
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
// Run the enable command.
auto process_sp = GetProcess();
if (!process_sp) {
// Nothing to do.
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
- "valid process, skipping",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to get "
+ "valid process, skipping",
+ __FUNCTION__);
return;
}
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() call is for process uid %u",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %u",
+ __FUNCTION__, process_sp->GetUniqueID());
// If we have configuration data, we can directly enable it now. Otherwise,
// we need to run through the command interpreter to parse the auto-run
@@ -1849,10 +1817,10 @@ void StructuredDataDarwinLog::EnableNow() {
DebuggerSP debugger_sp =
process_sp->GetTarget().GetDebugger().shared_from_this();
if (!debugger_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to get "
- "debugger shared pointer, skipping (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to get "
+ "debugger shared pointer, skipping (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return;
}
@@ -1864,13 +1832,15 @@ void StructuredDataDarwinLog::EnableNow() {
const bool success = RunEnableCommand(interpreter);
if (log) {
if (success)
- log->Printf("StructuredDataDarwinLog::%s() ran enable command "
- "successfully for (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() ran enable command "
+ "successfully for (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
else
- log->Printf("StructuredDataDarwinLog::%s() error: running "
- "enable command failed (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() error: running "
+ "enable command failed (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
}
// Report failures to the debugger error stream.
auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
@@ -1886,11 +1856,11 @@ void StructuredDataDarwinLog::EnableNow() {
// specified options.
auto config_sp = options_sp->BuildConfigurationData(true);
if (!config_sp) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() warning: failed to "
- "build configuration data for enable options, skipping "
- "(process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() warning: failed to "
+ "build configuration data for enable options, skipping "
+ "(process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
return;
}
@@ -1901,11 +1871,11 @@ void StructuredDataDarwinLog::EnableNow() {
// Report results.
if (!error.Success()) {
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() "
- "ConfigureStructuredData() call failed "
- "(process uid %u): %s",
- __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() "
+ "ConfigureStructuredData() call failed "
+ "(process uid %u): %s",
+ __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
auto error_stream_sp = debugger_sp->GetAsyncErrorStream();
if (error_stream_sp) {
error_stream_sp->Printf("failed to configure DarwinLog "
@@ -1916,9 +1886,9 @@ void StructuredDataDarwinLog::EnableNow() {
m_is_enabled = false;
} else {
m_is_enabled = true;
- if (log)
- log->Printf("StructuredDataDarwinLog::%s() success via direct "
- "configuration (process uid %u)",
- __FUNCTION__, process_sp->GetUniqueID());
+ LLDB_LOGF(log,
+ "StructuredDataDarwinLog::%s() success via direct "
+ "configuration (process uid %u)",
+ __FUNCTION__, process_sp->GetUniqueID());
}
}
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td
new file mode 100644
index 000000000000..5c22158542f9
--- /dev/null
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "darwinlog" in {
+ def EnableOnStartup: Property<"enable-on-startup", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Enable Darwin os_log collection when debugged process is launched or attached.">;
+ def AutoEnableOptions: Property<"auto-enable-options", "String">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Specify the options to 'plugin structured-data darwin-log enable' that should be applied when automatically enabling logging on startup/attach.">;
+}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index d4258274a38c..f84cf0c5368d 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -15,7 +15,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Utility/Log.h"
@@ -126,8 +125,8 @@ SymbolFileBreakpad::LineIterator::operator++() {
llvm::iterator_range<SymbolFileBreakpad::LineIterator>
SymbolFileBreakpad::lines(Record::Kind section_type) {
- return llvm::make_range(LineIterator(*m_obj_file, section_type),
- LineIterator(*m_obj_file));
+ return llvm::make_range(LineIterator(*m_objfile_sp, section_type),
+ LineIterator(*m_objfile_sp));
}
namespace {
@@ -179,15 +178,13 @@ ConstString SymbolFileBreakpad::GetPluginNameStatic() {
}
uint32_t SymbolFileBreakpad::CalculateAbilities() {
- if (!m_obj_file)
- return 0;
- if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
+ if (!m_objfile_sp || !llvm::isa<ObjectFileBreakpad>(*m_objfile_sp))
return 0;
return CompileUnits | Functions | LineTables;
}
-uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
+uint32_t SymbolFileBreakpad::CalculateNumCompileUnits() {
ParseCUData();
return m_cu_data->GetSize();
}
@@ -204,7 +201,8 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
// The FileSpec of the compile unit will be the file corresponding to the
// first LINE record.
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
++It; // Skip FUNC record.
if (It != End) {
@@ -213,12 +211,12 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
spec = (*m_files)[record->FileNum];
}
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(),
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(),
/*user_data*/ nullptr, spec, index,
eLanguageTypeUnknown,
/*is_optimized*/ eLazyBoolNo);
- GetSymbolVendor().SetCompileUnitAtIndex(index, cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -228,6 +226,7 @@ size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.line_table_up)
@@ -239,6 +238,7 @@ bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.support_files)
ParseLineTableAndSupportFiles(comp_unit, data);
@@ -251,6 +251,7 @@ uint32_t
SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry)))
return 0;
@@ -260,7 +261,7 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
if (idx == UINT32_MAX)
return 0;
- sc.comp_unit = GetSymbolVendor().GetCompileUnitAtIndex(idx).get();
+ sc.comp_unit = GetCompileUnitAtIndex(idx).get();
SymbolContextItem result = eSymbolContextCompUnit;
if (resolve_scope & eSymbolContextLineEntry) {
if (sc.comp_unit->GetLineTable()->FindLineEntryByAddress(so_addr,
@@ -275,57 +276,43 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
uint32_t SymbolFileBreakpad::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & eSymbolContextCompUnit))
return 0;
uint32_t old_size = sc_list.GetSize();
for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
- CompileUnit &cu = *GetSymbolVendor().GetCompileUnitAtIndex(i);
+ CompileUnit &cu = *GetCompileUnitAtIndex(i);
cu.ResolveSymbolContext(file_spec, line, check_inlines,
/*exact*/ false, resolve_scope, sc_list);
}
return sc_list.GetSize() - old_size;
}
-uint32_t SymbolFileBreakpad::FindFunctions(
+void SymbolFileBreakpad::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindTypes(
+void SymbolFileBreakpad::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {}
-size_t
-SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+void SymbolFileBreakpad::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
- Module &module = *m_obj_file->GetModule();
+ Module &module = *m_objfile_sp->GetModule();
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
@@ -347,8 +334,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
return;
}
symbols.try_emplace(
- address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
- eSymbolTypeCode, /*is_global*/ true, /*is_debug*/ false,
+ address, /*symID*/ 0, Mangled(name), eSymbolTypeCode,
+ /*is_global*/ true, /*is_debug*/ false,
/*is_trampoline*/ false, /*is_artificial*/ false,
AddressRange(section_sp, address - section_sp->GetFileAddress(),
size.getValueOr(0)),
@@ -372,6 +359,20 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
symtab.CalculateSymbolSizes();
}
+llvm::Expected<lldb::addr_t>
+SymbolFileBreakpad::GetParameterStackSize(Symbol &symbol) {
+ ParseUnwindData();
+ if (auto *entry = m_unwind_data->win.FindEntryThatContains(
+ symbol.GetAddress().GetFileAddress())) {
+ auto record = StackWinRecord::parse(
+ *LineIterator(*m_objfile_sp, Record::StackWin, entry->data));
+ assert(record.hasValue());
+ return record->ParameterSize;
+ }
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Parameter size unknown.");
+}
+
static llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
GetRule(llvm::StringRef &unwind_rules) {
// Unwind rules are of the form
@@ -418,7 +419,17 @@ ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
return ResolveRegister(resolver, name);
}
-bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
+llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
+ ArchSpec arch = m_objfile_sp->GetArchitecture();
+ StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
+ arch.GetByteOrder());
+ ToDWARF(node, dwarf);
+ uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
+ std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
+ return {saved, dwarf.GetSize()};
+}
+
+bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
const RegisterInfoResolver &resolver,
UnwindPlan::Row &row) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
@@ -427,7 +438,7 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
while (auto rule = GetRule(unwind_rules)) {
node_alloc.Reset();
llvm::StringRef lhs = rule->first;
- postfix::Node *rhs = postfix::Parse(rule->second, node_alloc);
+ postfix::Node *rhs = postfix::ParseOneExpression(rule->second, node_alloc);
if (!rhs) {
LLDB_LOG(log, "Could not parse `{0}` as unwind rhs.", rule->second);
return false;
@@ -451,18 +462,12 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
return false;
}
- ArchSpec arch = m_obj_file->GetArchitecture();
- StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
- arch.GetByteOrder());
- ToDWARF(*rhs, dwarf);
- uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
- std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
-
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
if (lhs == ".cfa") {
- row.GetCFAValue().SetIsDWARFExpression(saved, dwarf.GetSize());
+ row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
} else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
UnwindPlan::Row::RegisterLocation loc;
- loc.SetIsDWARFExpression(saved, dwarf.GetSize());
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
} else
LLDB_LOG(log, "Invalid register `{0}` in unwind rule.", lhs);
@@ -478,31 +483,40 @@ UnwindPlanSP
SymbolFileBreakpad::GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) {
ParseUnwindData();
- const UnwindMap::Entry *entry =
- m_unwind_data->FindEntryThatContains(address.GetFileAddress());
- if (!entry)
- return nullptr;
+ if (auto *entry =
+ m_unwind_data->cfi.FindEntryThatContains(address.GetFileAddress()))
+ return ParseCFIUnwindPlan(entry->data, resolver);
+ if (auto *entry =
+ m_unwind_data->win.FindEntryThatContains(address.GetFileAddress()))
+ return ParseWinUnwindPlan(entry->data, resolver);
+ return nullptr;
+}
+UnwindPlanSP
+SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS)
return nullptr;
- LineIterator It(*m_obj_file, Record::StackCFI, entry->data), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark),
+ End(*m_objfile_sp);
llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It);
- assert(init_record.hasValue());
- assert(init_record->Size.hasValue());
+ assert(init_record.hasValue() && init_record->Size.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
plan_sp->SetSourceName("breakpad STACK CFI");
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
plan_sp->SetPlanValidAddressRange(
AddressRange(base + init_record->Address, *init_record->Size,
- m_obj_file->GetModule()->GetSectionList()));
+ m_objfile_sp->GetModule()->GetSectionList()));
auto row_sp = std::make_shared<UnwindPlan::Row>();
row_sp->SetOffset(0);
- if (!ParseUnwindRow(init_record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(init_record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
for (++It; It != End; ++It) {
@@ -514,19 +528,107 @@ SymbolFileBreakpad::GetUnwindPlan(const Address &address,
row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
row_sp->SetOffset(record->Address - init_record->Address);
- if (!ParseUnwindRow(record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
}
return plan_sp;
}
-SymbolVendor &SymbolFileBreakpad::GetSymbolVendor() {
- return *m_obj_file->GetModule()->GetSymbolVendor();
+UnwindPlanSP
+SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ LineIterator It(*m_objfile_sp, Record::StackWin, bookmark);
+ llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It);
+ assert(record.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
+
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
+ plan_sp->SetSourceName("breakpad STACK WIN");
+ plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+ plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+ plan_sp->SetPlanValidAddressRange(
+ AddressRange(base + record->RVA, record->CodeSize,
+ m_objfile_sp->GetModule()->GetSectionList()));
+
+ auto row_sp = std::make_shared<UnwindPlan::Row>();
+ row_sp->SetOffset(0);
+
+ llvm::BumpPtrAllocator node_alloc;
+ std::vector<std::pair<llvm::StringRef, postfix::Node *>> program =
+ postfix::ParseFPOProgram(record->ProgramString, node_alloc);
+
+ if (program.empty()) {
+ LLDB_LOG(log, "Invalid unwind rule: {0}.", record->ProgramString);
+ return nullptr;
+ }
+ auto it = program.begin();
+ const auto &symbol_resolver =
+ [&](postfix::SymbolNode &symbol) -> postfix::Node * {
+ llvm::StringRef name = symbol.GetName();
+ for (const auto &rule : llvm::make_range(program.begin(), it)) {
+ if (rule.first == name)
+ return rule.second;
+ }
+ if (const RegisterInfo *info = ResolveRegister(resolver, name))
+ return postfix::MakeNode<postfix::RegisterNode>(
+ node_alloc, info->kinds[eRegisterKindLLDB]);
+ return nullptr;
+ };
+
+ // We assume the first value will be the CFA. It is usually called T0, but
+ // clang will use T1, if it needs to realign the stack.
+ auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second);
+ if (symbol && symbol->GetName() == ".raSearch") {
+ row_sp->GetCFAValue().SetRaSearch(record->LocalSize +
+ record->SavedRegisterSize);
+ } else {
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ row_sp->GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
+ }
+
+ // Replace the node value with InitialValueNode, so that subsequent
+ // expressions refer to the CFA value instead of recomputing the whole
+ // expression.
+ it->second = postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
+
+
+ // Now process the rest of the assignments.
+ for (++it; it != program.end(); ++it) {
+ const RegisterInfo *info = ResolveRegister(resolver, it->first);
+ // It is not an error if the resolution fails because the program may
+ // contain temporary variables.
+ if (!info)
+ continue;
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ UnwindPlan::Row::RegisterLocation loc;
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
+ row_sp->SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
+ }
+
+ plan_sp->AppendRow(row_sp);
+ return plan_sp;
}
addr_t SymbolFileBreakpad::GetBaseFileAddress() {
- return m_obj_file->GetModule()
+ return m_objfile_sp->GetModule()
->GetObjectFile()
->GetBaseAddress()
.GetFileAddress();
@@ -569,8 +671,8 @@ void SymbolFileBreakpad::ParseCUData() {
// We shall create one compile unit for each FUNC record. So, count the number
// of FUNC records, and store them in m_cu_data, together with their ranges.
- for (LineIterator It(*m_obj_file, Record::Func), End(*m_obj_file); It != End;
- ++It) {
+ for (LineIterator It(*m_objfile_sp, Record::Func), End(*m_objfile_sp);
+ It != End; ++It) {
if (auto record = FuncRecord::parse(*It)) {
m_cu_data->Append(CompUnitMap::Entry(base + record->Address, record->Size,
CompUnitData(It.GetBookmark())));
@@ -589,7 +691,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
"How did we create compile units without a base address?");
SupportFileMap map;
- data.line_table_up = llvm::make_unique<LineTable>(&cu);
+ data.line_table_up = std::make_unique<LineTable>(&cu);
std::unique_ptr<LineSequence> line_seq_up(
data.line_table_up->CreateLineSequenceContainer());
llvm::Optional<addr_t> next_addr;
@@ -603,7 +705,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
line_seq_up->Clear();
};
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
for (++It; It != End; ++It) {
auto record = LineRecord::parse(*It);
@@ -631,8 +734,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
void SymbolFileBreakpad::ParseUnwindData() {
if (m_unwind_data)
return;
-
m_unwind_data.emplace();
+
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
@@ -640,14 +743,24 @@ void SymbolFileBreakpad::ParseUnwindData() {
"of object file.");
}
- for (LineIterator It(*m_obj_file, Record::StackCFI), End(*m_obj_file);
+ for (LineIterator It(*m_objfile_sp, Record::StackCFI), End(*m_objfile_sp);
It != End; ++It) {
if (auto record = StackCFIRecord::parse(*It)) {
if (record->Size)
- m_unwind_data->Append(UnwindMap::Entry(
+ m_unwind_data->cfi.Append(UnwindMap::Entry(
base + record->Address, *record->Size, It.GetBookmark()));
} else
LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
}
- m_unwind_data->Sort();
+ m_unwind_data->cfi.Sort();
+
+ for (LineIterator It(*m_objfile_sp, Record::StackWin), End(*m_objfile_sp);
+ It != End; ++It) {
+ if (auto record = StackWinRecord::parse(*It)) {
+ m_unwind_data->win.Append(UnwindMap::Entry(
+ base + record->RVA, record->CodeSize, It.GetBookmark()));
+ } else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+ }
+ m_unwind_data->win.Sort();
}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 8a0b7645fd0a..a10138cdf92f 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -12,6 +12,7 @@
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -31,12 +32,13 @@ public:
return "Breakpad debug symbol file reader.";
}
- static SymbolFile *CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileBreakpad(obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) {
+ return new SymbolFileBreakpad(std::move(objfile_sp));
}
// Constructors and Destructors
- SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
+ SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
~SymbolFileBreakpad() override {}
@@ -46,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
return lldb::eLanguageTypeUnknown;
}
@@ -72,12 +70,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override { return 0; }
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override {
- return 0;
- }
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override {}
size_t ParseVariablesForContext(const SymbolContext &sc) override {
return 0;
@@ -99,31 +95,30 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override {
- return 0;
- }
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override {}
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override {
- return nullptr;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override {
+ return llvm::make_error<llvm::StringError>(
+ "SymbolFileBreakpad does not support GetTypeSystemForLanguage",
+ llvm::inconvertibleErrorCode());
}
CompilerDeclContext
@@ -134,6 +129,8 @@ public:
void AddSymbols(Symtab &symtab) override;
+ llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
+
lldb::UnwindPlanSP
GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) override;
@@ -196,15 +193,22 @@ private:
};
- SymbolVendor &GetSymbolVendor();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::addr_t GetBaseFileAddress();
void ParseFileRecords();
void ParseCUData();
void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
void ParseUnwindData();
- bool ParseUnwindRow(llvm::StringRef unwind_rules,
- const RegisterInfoResolver &resolver,
- UnwindPlan::Row &row);
+ llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
+ lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
+ bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
+ const RegisterInfoResolver &resolver,
+ UnwindPlan::Row &row);
+ lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
@@ -212,7 +216,11 @@ private:
llvm::Optional<CompUnitMap> m_cu_data;
using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
- llvm::Optional<UnwindMap> m_unwind_data;
+ struct UnwindData {
+ UnwindMap cfi;
+ UnwindMap win;
+ };
+ llvm::Optional<UnwindData> m_unwind_data;
llvm::BumpPtrAllocator m_allocator;
};
diff --git a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 9ae047da1325..0a5073b8cd9e 100644
--- a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -21,30 +21,30 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
Module &module, DWARFDataExtractor apple_names,
DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
- auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_names, debug_str, ".apple_names");
if (!apple_names_table_up->IsValid())
apple_names_table_up.reset();
auto apple_namespaces_table_up =
- llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ std::make_unique<DWARFMappedHash::MemoryTable>(
apple_namespaces, debug_str, ".apple_namespaces");
if (!apple_namespaces_table_up->IsValid())
apple_namespaces_table_up.reset();
- auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_types, debug_str, ".apple_types");
if (!apple_types_table_up->IsValid())
apple_types_table_up.reset();
- auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_objc, debug_str, ".apple_objc");
if (!apple_objc_table_up->IsValid())
apple_objc_table_up.reset();
if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
apple_objc_table_up)
- return llvm::make_unique<AppleDWARFIndex>(
+ return std::make_unique<AppleDWARFIndex>(
module, std::move(apple_names_table_up),
std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
std::move(apple_objc_table_up));
@@ -110,6 +110,7 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
const bool has_qualified_name_hash =
m_apple_types_up->GetHeader().header_data.ContainsAtom(
DWARFMappedHash::eAtomTypeQualNameHash);
+
const ConstString type_name(context[0].name);
const dw_tag_t tag = context[0].tag;
if (has_tag && has_qualified_name_hash) {
@@ -119,12 +120,32 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
type_name.GetStringRef(), tag, qualified_name_hash, offsets);
- } else if (has_tag) {
+ return;
+ }
+
+ if (has_tag) {
+ // When searching for a scoped type (for example,
+ // "std::vector<int>::const_iterator") searching for the innermost
+ // name alone ("const_iterator") could yield many false
+ // positives. By searching for the parent type ("vector<int>")
+ // first we can avoid extracting type DIEs from object files that
+ // would fail the filter anyway.
+ 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())
+ return;
+ }
+
if (log)
m_module.LogMessage(log, "FindByNameAndTag()");
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
- } else
- m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+ return;
+ }
+
+ m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
}
void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index e7927b31b9c3..7ee4727cde91 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -28,7 +28,6 @@ public:
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
- lldb_private::Log *log,
bool *type_is_new_ptr) = 0;
virtual lldb_private::Function *
@@ -48,8 +47,8 @@ public:
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
+ virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) = 0;
static llvm::Optional<lldb_private::SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b85ab54a10d3..636e6032b877 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -9,7 +9,6 @@
#include <stdlib.h>
#include "DWARFASTParserClang.h"
-#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
@@ -28,7 +27,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
@@ -144,23 +143,27 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
// If this type comes from a Clang module, look in the DWARF section
// of the pcm file in the module cache. Clang generates DWO skeleton
// units as breadcrumbs to find them.
- std::vector<CompilerContext> decl_context;
+ llvm::SmallVector<CompilerContext, 4> decl_context;
die.GetDeclContext(decl_context);
TypeMap dwo_types;
- if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true,
- dwo_types)) {
+ // The type in the Clang module must have the same language as the current CU.
+ LanguageSet languages;
+ languages.Insert(die.GetCU()->GetLanguageType());
+ dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, dwo_types);
+ if (dwo_types.Empty()) {
if (!IsClangModuleFwdDecl(die))
return TypeSP();
- // Since this this type is defined in one of the Clang modules imported by
- // this symbol file, search all of them.
+ // Since this type is defined in one of the Clang modules imported
+ // by this symbol file, search all of them.
auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
for (const auto &name_module : sym_file.getExternalTypeModules()) {
if (!name_module.second)
continue;
- SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
- if (sym_vendor->FindTypes(decl_context, true, dwo_types))
+ name_module.second->GetSymbolFile()->FindTypes(decl_context,
+ languages, dwo_types);
+ if (dwo_types.GetSize())
break;
}
}
@@ -188,7 +191,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
&dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
- dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
if (tag_decl)
@@ -228,42 +231,7 @@ static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
}
}
-namespace {
-/// Parsed form of all attributes that are relevant for type reconstruction.
-/// Some attributes are relevant for all kinds of types (declaration), while
-/// others are only meaningful to a specific type (is_virtual)
-struct ParsedTypeAttributes {
- explicit ParsedTypeAttributes(const DWARFDIE &die);
-
- AccessType accessibility = eAccessNone;
- bool is_artificial = false;
- bool is_complete_objc_class = false;
- bool is_explicit = false;
- bool is_forward_declaration = false;
- bool is_inline = false;
- bool is_scoped_enum = false;
- bool is_vector = false;
- bool is_virtual = false;
- clang::StorageClass storage = clang::SC_None;
- const char *mangled_name = nullptr;
- ConstString name;
- Declaration decl;
- DWARFDIE object_pointer;
- DWARFFormValue abstract_origin;
- DWARFFormValue containing_type;
- DWARFFormValue signature;
- DWARFFormValue specification;
- DWARFFormValue type;
- LanguageType class_language = eLanguageTypeUnknown;
- llvm::Optional<uint64_t> byte_size;
- size_t calling_convention = llvm::dwarf::DW_CC_normal;
- uint32_t bit_stride = 0;
- uint32_t byte_stride = 0;
- uint32_t encoding = 0;
-};
-} // namespace
-
-ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die) {
+ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
DWARFAttributes attributes;
size_t num_attributes = die.GetAttributes(attributes);
for (size_t i = 0; i < num_attributes; ++i) {
@@ -390,13 +358,17 @@ static std::string GetUnitName(const DWARFDIE &die) {
}
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die, Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) {
if (type_is_new_ptr)
*type_is_new_ptr = false;
if (!die)
return nullptr;
+
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS));
+
SymbolFileDWARF *dwarf = die.GetDWARF();
if (log) {
DWARFDIE context_die;
@@ -420,11 +392,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Set a bit that lets us know that we are currently parsing this
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- ParsedTypeAttributes attrs(die);
+ ParsedDWARFTypeAttributes attrs(die);
if (DWARFDIE signature_die = attrs.signature.Reference()) {
if (TypeSP type_sp =
- ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
+ ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
if (clang::DeclContext *decl_ctx =
GetCachedClangDeclContextForDIE(signature_die))
@@ -434,7 +406,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
return nullptr;
}
- TypeList *type_list = dwarf->GetTypeList();
if (type_is_new_ptr)
*type_is_new_ptr = true;
@@ -562,7 +533,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool function_type_is_new_pointer;
TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
- sc, function_type, log, &function_type_is_new_pointer);
+ sc, function_type, &function_type_is_new_pointer);
if (lldb_function_type_sp) {
clang_type = m_ast.CreateBlockPointerType(
@@ -660,370 +631,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type: {
- // UniqueDWARFASTType is large, so don't create a local variables on
- // the stack, put it on the heap. This function is often called
- // recursively and clang isn't good and sharing the stack space for
- // variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
- new UniqueDWARFASTType());
-
- ConstString unique_typename(attrs.name);
- Declaration unique_decl(attrs.decl);
-
- if (attrs.name) {
- if (Language::LanguageIsCPlusPlus(cu_language)) {
- // For C++, we rely solely upon the one definition rule that says
- // only one thing can exist at a given decl context. We ignore the
- // file and line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
-
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
- *unique_ast_entry_up)) {
- type_sp = unique_ast_entry_up->m_type_sp;
- if (type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- 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;
- }
-
- if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
- !die.HasChildren() && cu_language == eLanguageTypeObjC) {
- // Work around an issue with clang at the moment where forward
- // declarations for objective C classes are emitted as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are no children,
- // and the byte size is zero.
- attrs.is_forward_declaration = true;
- }
-
- if (attrs.class_language == eLanguageTypeObjC ||
- attrs.class_language == eLanguageTypeObjC_plus_plus) {
- if (!attrs.is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // We have a valid eSymbolTypeObjCClass class symbol whose name
- // matches the current objective C class that we are trying to find
- // and this DIE isn't the complete definition (we checked
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp =
- dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, attrs.name, true);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
- "incomplete objc type, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- if (attrs.is_forward_declaration) {
- // We have a forward declaration to a type and we need to try and
- // find a full declaration. We look in the current type index just in
- // case we have a forward declaration followed by an actual
- // declarations in the DWARF. If this fails, we need to look
- // elsewhere...
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, trying to find complete type",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString());
- }
-
- // See if the type comes from a DWO module and if so, track down that
- // type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert(tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, nullptr);
-
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
- attrs.name.GetCString());
-
- if (attrs.accessibility == eAccessNone && decl_ctx) {
- // Check the decl context that contains this class/struct/union. If
- // it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass(containing_decl_kind))
- attrs.accessibility = default_accessibility;
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
-
- if (attrs.name.GetStringRef().contains('<')) {
- ClangASTContext::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);
- if (!class_template_decl) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
- "clang::ClassTemplateDecl failed to return a decl.",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString());
- }
- return TypeSP();
- }
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType(
- class_specialization_decl);
- clang_type_was_created = true;
-
- m_ast.SetMetadata(class_template_decl, metadata);
- m_ast.SetMetadata(class_specialization_decl, metadata);
- }
- }
-
- 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);
- }
- }
-
- // Store a forward declaration to this class type in case any
- // 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::eResolveStateForward);
-
- type_sp->SetIsCompleteObjCClass(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
- // module
- unique_ast_entry_up->m_type_sp = type_sp;
- unique_ast_entry_up->m_die = die;
- unique_ast_entry_up->m_declaration = unique_decl;
- unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
- dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
- *unique_ast_entry_up);
-
- if (attrs.is_forward_declaration && die.HasChildren()) {
- // Check to see if the DIE actually has a definition, some version of
- // GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram, members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die) {
- switch (child_die.Tag()) {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- attrs.is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
- }
-
- if (!attrs.is_forward_declaration) {
- // Always start the definition for a class type so that if the class
- // has child classes or types that require the class to be created
- // for use as their decl contexts the class will be ready to accept
- // 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);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), attrs.name.GetCString());
- }
-
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
-
- if (record_decl) {
- GetClangASTImporter().InsertRecordDecl(
- record_decl, ClangASTImporter::LayoutInfo());
- }
- }
- } else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
-
- if (attrs.class_language != eLanguageTypeObjC &&
- attrs.class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::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
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
- ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a
- // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
- // binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
- clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
- die.GetID();
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- }
- }
-
- // If we made a clang type, set the trivial abi if applicable: We only
- // do this for pass by value - which implies the Trivial ABI. There
- // isn't a way to assert that something that would normally be pass by
- // value is pass by reference, so we ignore that attribute if set.
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl) {
- record_decl->setHasTrivialSpecialMemberForCall();
- }
- }
-
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl)
- record_decl->setArgPassingRestrictions(
- clang::RecordDecl::APK_CannotPassInRegs);
- }
-
- } break;
+ assert((!type_sp && !clang_type) &&
+ "Did not expect partially computed structure-like type");
+ TypeSP struct_like_type_sp = ParseStructureLikeDIE(die, attrs);
+ return UpdateSymbolContextScopeForType(sc, die, struct_like_type_sp);
+ }
case DW_TAG_enumeration_type: {
if (attrs.is_forward_declaration) {
@@ -1395,8 +1007,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
is_attr_used, attrs.is_artificial);
type_handled = cxx_method_decl != NULL;
+ // Artificial methods are always handled even when we
+ // don't create a new declaration for them.
+ type_handled |= attrs.is_artificial;
- if (type_handled) {
+ if (cxx_method_decl) {
LinkDeclContextToDIE(
ClangASTContext::GetAsDeclContext(cxx_method_decl),
die);
@@ -1407,12 +1022,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!object_pointer_name.empty()) {
metadata.SetObjectPtrName(
object_pointer_name.c_str());
- if (log)
- log->Printf(
- "Setting object pointer name: %s on method "
- "object %p.\n",
- object_pointer_name.c_str(),
- static_cast<void *>(cxx_method_decl));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
m_ast.SetMetadata(cxx_method_decl, metadata);
} else {
@@ -1520,11 +1134,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!object_pointer_name.empty()) {
metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf("Setting object pointer name: %s on function "
- "object %p.",
- object_pointer_name.c_str(),
- static_cast<void *>(function_decl));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
}
m_ast.SetMetadata(function_decl, metadata);
}
@@ -1651,31 +1265,418 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
break;
}
- if (type_sp.get()) {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ // TODO: We should consider making the switch above exhaustive to simplify
+ // control flow in ParseTypeFromDWARF. Then, we could simply replace this
+ // return statement with a call to llvm_unreachable.
+ return UpdateSymbolContextScopeForType(sc, die, type_sp);
+}
+
+TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
+ const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
+ if (!type_sp)
+ return type_sp;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeList &type_list = dwarf->GetTypeList();
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = NULL;
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
+ symbol_context_scope = sc.comp_unit;
+ } else if (sc.function != NULL && sc_parent_die) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ } else {
+ symbol_context_scope = sc.module_sp.get();
+ }
+
+ if (symbol_context_scope != NULL)
+ type_sp->SetSymbolContextScope(symbol_context_scope);
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- } else
- symbol_context_scope = sc.module_sp.get();
+ // We are ready to put this type into the uniqued list up at the module
+ // level.
+ type_list.Insert(type_sp);
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+}
+
+TypeSP
+DWARFASTParserClang::ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs) {
+ TypeSP type_sp;
+ CompilerType clang_type;
+ const dw_tag_t tag = die.Tag();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ LanguageType cu_language = die.GetLanguage();
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS);
+
+ // UniqueDWARFASTType is large, so don't create a local variables on the
+ // stack, put it on the heap. This function is often called recursively and
+ // clang isn't good at sharing the stack space for variables in different
+ // blocks.
+ auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
+
+ ConstString unique_typename(attrs.name);
+ Declaration unique_decl(attrs.decl);
+
+ if (attrs.name) {
+ if (Language::LanguageIsCPlusPlus(cu_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
+
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
+ *unique_ast_entry_up)) {
+ type_sp = unique_ast_entry_up->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ LinkDeclContextToDIE(
+ GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
+ return type_sp;
+ }
}
+ }
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ 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;
+ }
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
+ attrs.is_forward_declaration = true;
+ }
+
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // We have a valid eSymbolTypeObjCClass class symbol whose name
+ // matches the current objective C class that we are trying to find
+ // and this DIE isn't the complete definition (we checked
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp =
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
+ "incomplete objc type, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
+
+ if (attrs.is_forward_declaration) {
+ // We have a forward declaration to a type and we need to try and
+ // find a full declaration. We look in the current type index just in
+ // case we have a forward declaration followed by an actual
+ // declarations in the DWARF. If this fails, we need to look
+ // elsewhere...
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ attrs.name.GetCString());
+
+ if (attrs.accessibility == eAccessNone && decl_ctx) {
+ // Check the decl context that contains this class/struct/union. If
+ // it is a class we must give it an accessibility.
+ const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+ if (DeclKindIsCXXClass(containing_decl_kind))
+ attrs.accessibility = default_accessibility;
+ }
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (attrs.name.GetStringRef().contains('<')) {
+ ClangASTContext::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);
+ if (!class_template_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString());
+ }
+ return TypeSP();
+ }
+
+ clang::ClassTemplateSpecializationDecl *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ // Store a forward declaration to this class type in case any
+ // 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::eResolveStateForward);
+
+ type_sp->SetIsCompleteObjCClass(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
+ // module
+ unique_ast_entry_up->m_type_sp = type_sp;
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_up);
+
+ if (attrs.is_forward_declaration && die.HasChildren()) {
+ // Check to see if the DIE actually has a definition, some version of
+ // GCC will
+ // emit DIEs with DW_AT_declaration set to true, but yet still have
+ // subprogram, members, or inheritance, so we can't trust it
+ DWARFDIE child_die = die.GetFirstChild();
+ while (child_die) {
+ switch (child_die.Tag()) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ case DW_TAG_APPLE_property:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ child_die.Clear();
+ attrs.is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
+ }
+ }
+ }
+
+ if (!attrs.is_forward_declaration) {
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // 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);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), attrs.name.GetCString());
+ }
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
+
+ if (record_decl) {
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::LayoutInfo());
+ }
+ }
+ } else if (clang_type_was_created) {
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
+
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::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
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ // Can't assume m_ast.GetSymbolFile() is actually a
+ // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
+ // binaries.
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
+ die.GetID();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
+
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl && record_decl->getDefinition()) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
+
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl)
+ record_decl->setArgPassingRestrictions(
+ clang::RecordDecl::APK_CannotPassInRegs);
}
return type_sp;
}
@@ -2181,14 +2182,16 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
return false;
}
-std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
+void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) {
- std::vector<DWARFDIE> result;
- for (auto it = m_decl_ctx_to_die.find(
- (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
- it != m_decl_ctx_to_die.end(); it++)
- result.push_back(it->second);
- return result;
+ auto opaque_decl_ctx =
+ (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
+ for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
+ it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
+ it = m_decl_ctx_to_die.erase(it))
+ for (DWARFDIE decl = it->second.GetFirstChild(); decl;
+ decl = decl.GetSibling())
+ GetClangDeclForDIE(decl);
}
CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
@@ -2530,9 +2533,11 @@ bool DWARFASTParserClang::ParseChildMembers(
if (DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
nullptr, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ module_sp,
+ DataExtractor(debug_info_data, block_offset,
+ block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
member_byte_offset =
memberOffset.ResolveValue(nullptr).UInt();
}
@@ -2965,11 +2970,12 @@ bool DWARFASTParserClang::ParseChildMembers(
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(nullptr, nullptr, module_sp,
- debug_info_data, die.GetCU(),
- block_offset, block_length,
- eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ if (DWARFExpression::Evaluate(
+ nullptr, nullptr, module_sp,
+ DataExtractor(debug_info_data, block_offset,
+ block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
member_byte_offset =
memberOffset.ResolveValue(nullptr).UInt();
}
@@ -3270,6 +3276,8 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
array_info.element_orders.push_back(num_elements);
}
} break;
+ default:
+ break;
}
}
return array_info;
@@ -3672,11 +3680,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (src_size != dst_size) {
if (src_size != 0 && dst_size != 0) {
- if (log)
- log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but they didn't have the same size (src=%d, dst=%d)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_size, dst_size);
+ LLDB_LOGF(log,
+ "warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but they didn't have the same size (src=%d, dst=%d)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(), src_size,
+ dst_size);
}
fast_path = false;
@@ -3690,12 +3698,12 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
if (src_die.Tag() != dst_die.Tag()) {
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_die.GetOffset(), src_die.GetTagAsCString(),
- dst_die.GetOffset(), dst_die.GetTagAsCString());
+ LLDB_LOGF(log,
+ "warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_die.GetTagAsCString(),
+ dst_die.GetOffset(), dst_die.GetTagAsCString());
fast_path = false;
}
@@ -3706,12 +3714,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))
continue;
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
- "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
- src_class_die.GetOffset(), dst_class_die.GetOffset(),
- src_die.GetOffset(), src_name, dst_die.GetOffset(),
- dst_name);
+ LLDB_LOGF(log,
+ "warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
+ "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
+ src_class_die.GetOffset(), dst_class_die.GetOffset(),
+ src_die.GetOffset(), src_name, dst_die.GetOffset(), dst_name);
fast_path = false;
}
@@ -3733,32 +3740,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x for "
- "0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x for "
+ "0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf(
- "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type), src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "uniquing type %p (uid=0x%" PRIx64
+ ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
}
} else {
@@ -3778,39 +3784,36 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x "
- "for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf("uniquing type %p (uid=0x%" PRIx64
- ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type),
- src_child_type->GetID(), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(
+ log,
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
} else {
- if (log)
- log->Printf("warning: couldn't find a match for 0x%8.8x",
- dst_die.GetOffset());
+ LLDB_LOGF(log, "warning: couldn't find a match for 0x%8.8x",
+ dst_die.GetOffset());
failures.push_back(dst_die);
}
@@ -3836,32 +3839,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
if (src_decl_ctx) {
- if (log)
- log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
- dst_die.GetOffset());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
} else {
- if (log)
- log->Printf("warning: tried to unique decl context from 0x%8.8x "
- "for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique decl context from 0x%8.8x "
+ "for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
Type *src_child_type =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
if (src_child_type) {
- if (log)
- log->Printf(
- "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void *>(src_child_type), src_child_type->GetID(),
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(
+ log,
+ "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_child_type), src_child_type->GetID(),
+ src_die.GetOffset(), dst_die.GetOffset());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
} else {
- if (log)
- log->Printf("warning: tried to unique lldb_private::Type from "
- "0x%8.8x for 0x%8.8x, but none was found",
- src_die.GetOffset(), dst_die.GetOffset());
+ LLDB_LOGF(log,
+ "warning: tried to unique lldb_private::Type from "
+ "0x%8.8x for 0x%8.8x, but none was found",
+ src_die.GetOffset(), dst_die.GetOffset());
}
}
}
@@ -3872,10 +3874,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
ConstString dst_name_artificial =
dst_name_to_die_artificial.GetCStringAtIndex(idx);
dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
- if (log)
- log->Printf("warning: need to create artificial method for 0x%8.8x for "
- "method '%s'",
- dst_die.GetOffset(), dst_name_artificial.GetCString());
+ LLDB_LOGF(log,
+ "warning: need to create artificial method for 0x%8.8x for "
+ "method '%s'",
+ dst_die.GetOffset(), dst_name_artificial.GetCString());
failures.push_back(dst_die);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 5b5d83d65932..106f9254a449 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -15,7 +15,10 @@
#include "llvm/ADT/SmallVector.h"
#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
#include "DWARFDefines.h"
+#include "DWARFFormValue.h"
+#include "LogChannelDWARF.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -29,6 +32,8 @@ class CompileUnit;
class DWARFDebugInfoEntry;
class SymbolFileDWARF;
+struct ParsedDWARFTypeAttributes;
+
class DWARFASTParserClang : public DWARFASTParser {
public:
DWARFASTParserClang(lldb_private::ClangASTContext &ast);
@@ -37,7 +42,7 @@ public:
// DWARFASTParser interface.
lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) override;
lldb_private::Function *
@@ -51,8 +56,8 @@ public:
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
- std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override;
+ void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) override;
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
@@ -63,9 +68,28 @@ public:
lldb_private::ClangASTImporter &GetClangASTImporter();
protected:
+ /// Protected typedefs and members.
+ /// @{
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ DIEToDeclContextMap;
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+ DIEToDeclMap;
+ typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
+
+ lldb_private::ClangASTContext &m_ast;
+ DIEToDeclMap m_die_to_decl;
+ DeclToDIEMap m_decl_to_die;
+ DIEToDeclContextMap m_die_to_decl_ctx;
+ DeclContextToDIEMap m_decl_ctx_to_die;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+ /// @}
+
clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
@@ -103,6 +127,10 @@ protected:
bool is_signed, uint32_t enumerator_byte_size,
const DWARFDIE &parent_die);
+ /// Parse a structure, class, or union type DIE.
+ lldb::TypeSP ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
+
lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
@@ -123,29 +151,52 @@ protected:
void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
+ /// If \p type_sp is valid, calculate and set its symbol context scope, and
+ /// update the type list for its backing symbol file.
+ ///
+ /// Returns \p type_sp.
+ lldb::TypeSP
+ UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die, lldb::TypeSP type_sp);
+
lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
// Return true if this type is a declaration to a type in an external
// module.
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
+};
- typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
- DIEToDeclContextMap;
- // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
- // DeclContextToDIEMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
- DeclContextToDIEMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
- DIEToDeclMap;
- typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
-
- lldb_private::ClangASTContext &m_ast;
- DIEToDeclMap m_die_to_decl;
- DeclToDIEMap m_decl_to_die;
- DIEToDeclContextMap m_die_to_decl_ctx;
- DeclContextToDIEMap m_decl_ctx_to_die;
- std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+/// Parsed form of all attributes that are relevant for type reconstruction.
+/// Some attributes are relevant for all kinds of types (declaration), while
+/// others are only meaningful to a specific type (is_virtual)
+struct ParsedDWARFTypeAttributes {
+ explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
+
+ lldb::AccessType accessibility = lldb::eAccessNone;
+ bool is_artificial = false;
+ bool is_complete_objc_class = false;
+ bool is_explicit = false;
+ bool is_forward_declaration = false;
+ bool is_inline = false;
+ bool is_scoped_enum = false;
+ bool is_vector = false;
+ bool is_virtual = false;
+ clang::StorageClass storage = clang::SC_None;
+ const char *mangled_name = nullptr;
+ lldb_private::ConstString name;
+ lldb_private::Declaration decl;
+ DWARFDIE object_pointer;
+ DWARFFormValue abstract_origin;
+ DWARFFormValue containing_type;
+ DWARFFormValue signature;
+ DWARFFormValue specification;
+ DWARFFormValue type;
+ lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
+ llvm::Optional<uint64_t> byte_size;
+ size_t calling_convention = llvm::dwarf::DW_CC_normal;
+ uint32_t bit_stride = 0;
+ uint32_t byte_stride = 0;
+ uint32_t encoding = 0;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 6128163a2926..741669b05754 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -18,7 +18,8 @@
using namespace lldb_private;
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
- : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
+ : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
+ m_attributes() {}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
uint8_t has_children)
@@ -33,7 +34,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
return DWARFEnumState::Complete;
m_attributes.clear();
- m_tag = data.GetULEB128(offset_ptr);
+ m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr));
if (m_tag == DW_TAG_null)
return llvm::make_error<llvm::object::GenericBinaryError>(
"abbrev decl requires non-null tag.");
@@ -68,7 +69,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
}
bool DWARFAbbreviationDeclaration::IsValid() {
- return m_code != 0 && m_tag != 0;
+ return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null;
}
uint32_t
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 96adb72c9532..033105efdc53 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
using namespace lldb_private;
@@ -29,7 +30,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
if (m_die)
return m_die->Tag();
else
- return 0;
+ return llvm::dwarf::DW_TAG_null;
}
const char *DWARFBaseDIE::GetTagAsCString() const {
@@ -102,19 +103,22 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
return nullptr;
}
-lldb_private::TypeSystem *DWARFBaseDIE::GetTypeSystem() const {
- if (m_cu)
- return m_cu->GetTypeSystem();
- else
- 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 {
- lldb_private::TypeSystem *type_system = GetTypeSystem();
- if (type_system)
- return type_system->GetDWARFParser();
- else
+ 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 {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 0058043017cd..9652d7946e87 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -12,6 +12,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
+#include "llvm/Support/Error.h"
+
class DIERef;
class DWARFASTParser;
class DWARFAttributes;
@@ -55,7 +57,7 @@ public:
llvm::Optional<DIERef> GetDIERef() const;
- lldb_private::TypeSystem *GetTypeSystem() const;
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem() const;
DWARFASTParser *GetDWARFParser() const;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 9d97ca15a252..5ee0687995a1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -342,7 +342,8 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
}
}
-void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
+void DWARFDIE::GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const {
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return;
@@ -351,40 +352,33 @@ void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
parent.GetDeclContext(context);
switch (tag) {
case DW_TAG_module:
- context.push_back(
- CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Module, ConstString(GetName())});
break;
case DW_TAG_namespace:
- context.push_back(CompilerContext(CompilerContextKind::Namespace,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Namespace, ConstString(GetName())});
break;
case DW_TAG_structure_type:
- context.push_back(CompilerContext(CompilerContextKind::Structure,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Struct, ConstString(GetName())});
break;
case DW_TAG_union_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Union, ConstString(GetName())});
break;
case DW_TAG_class_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Class, ConstString(GetName())});
break;
case DW_TAG_enumeration_type:
- context.push_back(CompilerContext(CompilerContextKind::Enumeration,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Enum, ConstString(GetName())});
break;
case DW_TAG_subprogram:
- context.push_back(CompilerContext(CompilerContextKind::Function,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Function, ConstString(GetPubname())});
break;
case DW_TAG_variable:
- context.push_back(CompilerContext(CompilerContextKind::Variable,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Variable, ConstString(GetPubname())});
break;
case DW_TAG_typedef:
- context.push_back(
- CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Typedef, ConstString(GetName())});
break;
default:
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 7753ec9008cb..a779c589611a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -78,8 +78,8 @@ public:
/// Return this DIE's decl context as it is needed to look up types
/// in Clang's -gmodules debug info format.
- void
- GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const;
+ void GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const;
// Getting attribute values from the DIE.
//
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index ccf33e6dc341..c8da2381353e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -66,8 +66,8 @@ void DWARFDebugAranges::Dump(Log *log) const {
for (size_t i = 0; i < num_entries; ++i) {
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
if (entry)
- log->Printf("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
- entry->GetRangeBase(), entry->GetRangeEnd());
+ LLDB_LOGF(log, "0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
+ entry->GetRangeBase(), entry->GetRangeEnd());
}
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 100f35f8c6b0..1e04baca2c58 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -38,7 +38,7 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
if (m_cu_aranges_up)
return *m_cu_aranges_up;
- m_cu_aranges_up = llvm::make_unique<DWARFDebugAranges>();
+ m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
const DWARFDataExtractor &debug_aranges_data =
m_context.getOrLoadArangesData();
if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 2f55b7d40ed9..8c0fbeb4b717 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -192,7 +192,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
*offset_ptr = offset;
return true;
} else {
- m_tag = 0;
+ m_tag = llvm::dwarf::DW_TAG_null;
m_has_children = false;
return true; // NULL debug tag entry
}
@@ -340,18 +340,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- *frame_base = DWARFExpression(module, data, cu,
- block_offset, block_length);
+ *frame_base = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length), cu);
} else {
- const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- cu, debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- *frame_base =
- DWARFExpression(module, debug_loc_data, cu,
- debug_loc_offset, loc_list_length);
+ DataExtractor data = dwarf.DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ *frame_base = DWARFExpression(module, data, cu);
if (lo_pc != LLDB_INVALID_ADDRESS) {
assert(lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc -
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 1e7b5f27642d..25c885608d85 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -31,7 +31,7 @@ public:
DWARFDebugInfoEntry()
: m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
- m_has_children(false), m_abbr_idx(0), m_tag(0) {}
+ m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -178,8 +178,9 @@ protected:
// a single NULL terminating child.
m_has_children : 1;
uint16_t m_abbr_idx;
- uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through
- // the compile unit abbrev table
+ /// 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;
};
#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
deleted file mode 100644
index 953089fee22b..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-//===-- DWARFDebugLine.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 "DWARFDebugLine.h"
-
-//#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
-#include <assert.h>
-
-#include <memory>
-
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Timer.h"
-
-#include "DWARFUnit.h"
-#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace std;
-
-// Parse
-//
-// Parse all information in the debug_line_data into an internal
-// representation.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
- m_lineTableMap.clear();
- lldb::offset_t offset = 0;
- LineTable::shared_ptr line_table_sp(new LineTable);
- while (debug_line_data.ValidOffset(offset)) {
- const lldb::offset_t debug_line_offset = offset;
-
- if (line_table_sp.get() == nullptr)
- break;
-
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
- // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
- // debug_line_offset);
- m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp = std::make_shared<LineTable>();
- } else
- ++offset; // Try next byte in line table
- }
-}
-
-void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
- if (m_lineTableMap.empty())
- Parse(debug_line_data);
-}
-
-// DWARFDebugLine::GetLineTable
-DWARFDebugLine::LineTable::shared_ptr
-DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
- DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
- LineTableConstIter pos = m_lineTableMap.find(offset);
- if (pos != m_lineTableMap.end())
- line_table_shared_ptr = pos->second;
- return line_table_shared_ptr;
-}
-
-// Parse
-//
-// Parse the entire line table contents calling callback each time a new
-// prologue is parsed and every time a new row is to be added to the line
-// table.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback,
- void *userData) {
- lldb::offset_t offset = 0;
- if (debug_line_data.ValidOffset(offset)) {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
- ++offset; // Skip to next byte in .debug_line section
- }
-}
-
-namespace {
-struct EntryDescriptor {
- dw_sleb128_t code;
- dw_sleb128_t form;
-};
-
-static std::vector<EntryDescriptor>
-ReadDescriptors(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr) {
- std::vector<EntryDescriptor> ret;
- uint8_t n = debug_line_data.GetU8(offset_ptr);
- for (uint8_t i = 0; i < n; ++i) {
- EntryDescriptor ent;
- ent.code = debug_line_data.GetULEB128(offset_ptr);
- ent.form = debug_line_data.GetULEB128(offset_ptr);
- ret.push_back(ent);
- }
- return ret;
-}
-} // namespace
-
-// DWARFDebugLine::ParsePrologue
-bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr,
- Prologue *prologue, DWARFUnit *dwarf_cu) {
- const lldb::offset_t prologue_offset = *offset_ptr;
-
- // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
-
- prologue->Clear();
- uint32_t i;
- const char *s;
- prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
- prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 5)
- return false;
-
- if (prologue->version >= 5) {
- prologue->address_size = debug_line_data.GetU8(offset_ptr);
- prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
- }
-
- prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
- const lldb::offset_t end_prologue_offset =
- prologue->prologue_length + *offset_ptr;
- prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
- if (prologue->version >= 4)
- prologue->maximum_operations_per_instruction =
- debug_line_data.GetU8(offset_ptr);
- else
- prologue->maximum_operations_per_instruction = 1;
- prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
- prologue->line_base = debug_line_data.GetU8(offset_ptr);
- prologue->line_range = debug_line_data.GetU8(offset_ptr);
- prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
-
- prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
-
- for (i = 1; i < prologue->opcode_base; ++i) {
- uint8_t op_len = debug_line_data.GetU8(offset_ptr);
- prologue->standard_opcode_lengths.push_back(op_len);
- }
-
- if (prologue->version >= 5) {
- std::vector<EntryDescriptor> dirEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < dirCount; ++i) {
- for (EntryDescriptor &ent : dirEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (ent.code != DW_LNCT_path) {
- if (!value.SkipValue(debug_line_data, offset_ptr))
- return false;
- continue;
- }
-
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
- prologue->include_directories.push_back(value.AsCString());
- }
- }
-
- std::vector<EntryDescriptor> filesEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
- uint8_t n = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < n; ++i) {
- FileNameEntry entry;
- for (EntryDescriptor &ent : filesEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
-
- switch (ent.code) {
- case DW_LNCT_path:
- entry.name = value.AsCString();
- break;
- case DW_LNCT_directory_index:
- entry.dir_idx = value.Unsigned();
- break;
- case DW_LNCT_timestamp:
- entry.mod_time = value.Unsigned();
- break;
- case DW_LNCT_size:
- entry.length = value.Unsigned();
- break;
- case DW_LNCT_MD5:
- assert(value.Unsigned() == 16);
- std::uninitialized_copy_n(value.BlockData(), 16,
- entry.checksum.Bytes.begin());
- break;
- default:
- break;
- }
- }
-
- if (seen.insert(entry.checksum.words()).second)
- prologue->file_names.push_back(entry);
- }
- } else {
- while (*offset_ptr < end_prologue_offset) {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
-
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.GetCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- prologue->file_names.push_back(fileEntry);
- } else
- break;
- }
- }
-
- // XXX GNU as is broken for 64-Bit DWARF
- if (*offset_ptr != end_prologue_offset) {
- Host::SystemLog(Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8" PRIx64
- " should have ended at 0x%8.8" PRIx64
- " but it ended at 0x%8.8" PRIx64 "\n",
- prologue_offset, end_prologue_offset, *offset_ptr);
- }
- return end_prologue_offset;
-}
-
-bool DWARFDebugLine::ParseSupportFiles(
- const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) {
- lldb::offset_t offset = stmt_list;
-
- Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
- Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
- "at 0x%8.8x (parsing ended around "
- "0x%8.8" PRIx64 "\n",
- stmt_list, offset);
- return false;
- }
-
- FileSpec file_spec;
- std::string remapped_file;
-
- for (uint32_t file_idx = 1;
- prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(),
- dwarf_cu->GetPathStyle(), file_spec);
- ++file_idx) {
- if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, FileSpec::Style::native);
- support_files.Append(file_spec);
- }
- return true;
-}
-
-// ParseStatementTable
-//
-// Parse a single line table (prologue and all rows) and call the callback
-// function once for the prologue (row in state will be zero) and each time a
-// row is to be added to the line table.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
- Prologue::shared_ptr prologue(new Prologue());
-
- const dw_offset_t debug_line_offset = *offset_ptr;
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
- debug_line_offset);
-
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
- if (log)
- log->Error("failed to parse DWARF line table prologue");
- // Restore our offset and return false to indicate failure!
- *offset_ptr = debug_line_offset;
- return false;
- }
-
- if (log)
- prologue->Dump(log);
-
- const dw_offset_t end_offset =
- debug_line_offset + prologue->total_length +
- (debug_line_data.GetDWARFSizeofInitialLength());
-
- State state(prologue, log, callback, userData);
-
- while (*offset_ptr < end_offset) {
- // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
- uint8_t opcode = debug_line_data.GetU8(offset_ptr);
-
- if (opcode == 0) {
- // Extended Opcodes always start with a zero opcode followed by a uleb128
- // length so you can skip ones you don't know about
- lldb::offset_t ext_offset = *offset_ptr;
- dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
- dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
-
- // DEBUG_PRINTF("Extended: <%2u> ", len);
- uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
- switch (sub_opcode) {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the state-
- // machine registers. Then reset the registers to the initial values
- // specified above. Every statement program sequence must end with a
- // DW_LNE_end_sequence instruction which creates a row whose address is
- // that of the byte after the last target machine instruction of the
- // sequence.
- state.end_sequence = true;
- state.AppendRowToMatrix(*offset_ptr);
- state.Reset();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes that
- // affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- if (arg_size == 4)
- state.address = debug_line_data.GetU32(offset_ptr);
- else // arg_size == 8
- state.address = debug_line_data.GetU64(offset_ptr);
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number
- // representing the directory index of the directory in which the file
- // was found. The third is an unsigned LEB128 number representing the
- // time of last modification of the file. The fourth is an unsigned
- // LEB128 number representing the length in bytes of the file. The time
- // and length fields may contain LEB128(0) if the information is not
- // available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0) if
- // the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by the
- // DW_LNE_define_file instruction. These numbers are used in the file
- // register of the state machine.
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(offset_ptr);
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- state.prologue->file_names.push_back(fileEntry);
- }
- break;
-
- default:
- // Length doesn't include the zero opcode byte or the length itself,
- // but it does include the sub_opcode, so we have to adjust for that
- // below
- (*offset_ptr) += arg_size;
- break;
- }
- } else if (opcode < prologue->opcode_base) {
- switch (opcode) {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the current
- // values of the state-machine registers. Then set the basic_block
- // register to false.
- state.AppendRowToMatrix(*offset_ptr);
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the result to the
- // address register of the state machine.
- state.address +=
- debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to the line
- // register of the state machine.
- state.line += debug_line_data.GetSLEB128(offset_ptr);
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- state.file = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.column = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state machine to
- // the logical negation of its current value.
- state.is_stmt = !state.is_stmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.basic_block = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state machine
- // the address increment value corresponding to special opcode 255. The
- // motivation for DW_LNS_const_add_pc is this: when the statement
- // program needs to advance the address by a small amount, it can use a
- // single special opcode, which occupies a single byte. When it needs
- // to advance the address by up to twice the range of the last special
- // opcode, it can use DW_LNS_const_add_pc followed by a special opcode,
- // for a total of two bytes. Only if it needs to advance the address by
- // more than twice that range will it need to use both
- // DW_LNS_advance_pc and a special opcode, requiring three or more
- // bytes.
- {
- uint8_t adjust_opcode = 255 - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
- prologue->min_inst_length;
- state.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of the
- // state machine the value of the (unencoded) operand. This is the only
- // extended opcode that takes an argument that is not a variable length
- // number. The motivation for DW_LNS_fixed_advance_pc is this: existing
- // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
- // they cannot encode LEB128 numbers or judge when the computation of a
- // special opcode overflows and requires the use of DW_LNS_advance_pc.
- // Such assemblers, however, can use DW_LNS_fixed_advance_pc instead,
- // sacrificing compression.
- state.address += debug_line_data.GetU16(offset_ptr);
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the state
- // machine to true
- state.prologue_end = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.epilogue_begin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.isa = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths of
- // such opcodes because they are specified in the prologue as a
- // multiple of LEB128 operands for each opcode.
- {
- uint8_t i;
- assert(static_cast<size_t>(opcode - 1) <
- prologue->standard_opcode_lengths.size());
- const uint8_t opcode_length =
- prologue->standard_opcode_lengths[opcode - 1];
- for (i = 0; i < opcode_length; ++i)
- debug_line_data.Skip_LEB128(offset_ptr);
- }
- break;
- }
- } else {
- // Special Opcodes
-
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base field in
- // the header, plus the value of the line_range field, minus 1 (line base
- // + line range - 1). If the desired line increment is greater than the
- // maximum line increment, a standard opcode must be used instead of a
- // special opcode. The "address advance" is calculated by dividing the
- // desired address increment by the minimum_instruction_length field from
- // the header. The special opcode is then calculated using the following
- // formula:
- //
- // opcode = (desired line increment - line_base) + (line_range * address
- // advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode must be
- // used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the opcode
- // itself to give the adjusted opcode. The amount to increment the
- // address register is the result of the adjusted opcode divided by the
- // line_range multiplied by the minimum_instruction_length field from the
- // header. That is:
- //
- // address increment = (adjusted opcode / line_range) *
- // minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus the
- // result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t adjust_opcode = opcode - prologue->opcode_base;
- dw_addr_t addr_offset =
- (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- int32_t line_offset =
- prologue->line_base + (adjust_opcode % prologue->line_range);
- state.line += line_offset;
- state.address += addr_offset;
- state.AppendRowToMatrix(*offset_ptr);
- }
- }
-
- state.Finalize(*offset_ptr);
-
- return end_offset;
-}
-
-// ParseStatementTableCallback
-static void ParseStatementTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table, so lets keep a reference to the
- // prologue using the supplied shared pointer
- line_table->prologue = state.prologue;
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- // We have a new row, lets append it
- line_table->AppendRow(state);
- }
-}
-
-// ParseStatementTable
-//
-// Parse a line table at offset and populate the LineTable class with the
-// prologue and all rows.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- LineTable *line_table, DWARFUnit *dwarf_cu) {
- return ParseStatementTable(debug_line_data, offset_ptr,
- ParseStatementTableCallback, line_table, dwarf_cu);
-}
-
-inline bool DWARFDebugLine::Prologue::IsValid() const {
- return SymbolFileDWARF::SupportedVersion(version);
-}
-
-// DWARFDebugLine::Prologue::Dump
-void DWARFDebugLine::Prologue::Dump(Log *log) {
- uint32_t i;
-
- log->Printf("Line table prologue:");
- log->Printf(" total_length: 0x%8.8x", total_length);
- log->Printf(" version: %u", version);
- log->Printf("prologue_length: 0x%8.8x", prologue_length);
- log->Printf("min_inst_length: %u", min_inst_length);
- log->Printf("default_is_stmt: %u", default_is_stmt);
- log->Printf(" line_base: %i", line_base);
- log->Printf(" line_range: %u", line_range);
- log->Printf(" opcode_base: %u", opcode_base);
-
- for (i = 0; i < standard_opcode_lengths.size(); ++i) {
- log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
- standard_opcode_lengths[i]);
- }
-
- if (!include_directories.empty()) {
- for (i = 0; i < include_directories.size(); ++i) {
- log->Printf("include_directories[%3u] = '%s'", i + 1,
- include_directories[i]);
- }
- }
-
- if (!file_names.empty()) {
- log->PutCString(" Dir Mod Time File Len File Name");
- log->PutCString(" ---- ---------- ---------- "
- "---------------------------");
- for (i = 0; i < file_names.size(); ++i) {
- const FileNameEntry &fileEntry = file_names[i];
- log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
- fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
- fileEntry.name);
- }
- }
-}
-
-// DWARFDebugLine::ParsePrologue::Append
-//
-// Append the contents of the prologue to the binary stream buffer
-// void
-// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
-//{
-// uint32_t i;
-//
-// buff.Append32(total_length);
-// buff.Append16(version);
-// buff.Append32(prologue_length);
-// buff.Append8(min_inst_length);
-// buff.Append8(default_is_stmt);
-// buff.Append8(line_base);
-// buff.Append8(line_range);
-// buff.Append8(opcode_base);
-//
-// for (i=0; i<standard_opcode_lengths.size(); ++i)
-// buff.Append8(standard_opcode_lengths[i]);
-//
-// for (i=0; i<include_directories.size(); ++i)
-// buff.AppendCStr(include_directories[i].c_str());
-// buff.Append8(0); // Terminate the include directory section with empty
-// string
-//
-// for (i=0; i<file_names.size(); ++i)
-// {
-// buff.AppendCStr(file_names[i].name.c_str());
-// buff.Append32_as_ULEB128(file_names[i].dir_idx);
-// buff.Append32_as_ULEB128(file_names[i].mod_time);
-// buff.Append32_as_ULEB128(file_names[i].length);
-// }
-// buff.Append8(0); // Terminate the file names section with empty string
-//}
-
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
- const FileSpec &comp_dir,
- FileSpec::Style style,
- FileSpec &file) const {
- uint32_t idx = file_idx - 1; // File indexes are 1 based...
- if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, style);
- if (file.IsRelative()) {
- if (file_names[idx].dir_idx > 0) {
- const uint32_t dir_idx = file_names[idx].dir_idx - 1;
- if (dir_idx < include_directories.size()) {
- file.PrependPathComponent(include_directories[dir_idx]);
- if (!file.IsRelative())
- return true;
- }
- }
-
- if (comp_dir)
- file.PrependPathComponent(comp_dir);
- }
- return true;
- }
- return false;
-}
-
-void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
- rows.push_back(state);
-}
-
-// Compare function for the binary search in
-// DWARFDebugLine::LineTable::LookupAddress()
-static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
- const DWARFDebugLine::Row &row2) {
- return row1.address < row2.address;
-}
-
-// DWARFDebugLine::LineTable::LookupAddress
-uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
- dw_addr_t cu_high_pc) const {
- uint32_t index = UINT32_MAX;
- if (!rows.empty()) {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.address = address;
- Row::const_iterator begin_pos = rows.begin();
- Row::const_iterator end_pos = rows.end();
- Row::const_iterator pos =
- lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
- if (pos == end_pos) {
- if (address < cu_high_pc)
- return rows.size() - 1;
- } else {
- // Rely on fact that we are using a std::vector and we can do pointer
- // arithmetic to find the row index (which will be one less that what we
- // found since it will find the first position after the current address)
- // since std::vector iterators are just pointers to the container type.
- index = pos - begin_pos;
- if (pos->address > address) {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
- }
- return index; // Failed to find address
-}
-
-// DWARFDebugLine::Row::Row
-DWARFDebugLine::Row::Row(bool default_is_stmt)
- : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
- basic_block(false), end_sequence(false), prologue_end(false),
- epilogue_begin(false), isa(0) {}
-
-// Called after a row is appended to the matrix
-void DWARFDebugLine::Row::PostAppend() {
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
-}
-
-// DWARFDebugLine::Row::Reset
-void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
- address = 0;
- line = 1;
- column = 0;
- file = 1;
- is_stmt = default_is_stmt;
- basic_block = false;
- end_sequence = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
-}
-// DWARFDebugLine::Row::Dump
-void DWARFDebugLine::Row::Dump(Log *log) const {
- log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
- column, file, isa, is_stmt ? " is_stmt" : "",
- basic_block ? " basic_block" : "",
- prologue_end ? " prologue_end" : "",
- epilogue_begin ? " epilogue_begin" : "",
- end_sequence ? " end_sequence" : "");
-}
-
-// Compare function LineTable structures
-static bool AddressLessThan(const DWARFDebugLine::Row &a,
- const DWARFDebugLine::Row &b) {
- return a.address < b.address;
-}
-
-// Insert a row at the correct address if the addresses can be out of order
-// which can only happen when we are linking a line table that may have had
-// it's contents rearranged.
-void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
- const Row &state) {
- // If we don't have anything yet, or if the address of the last state in our
- // line table is less than the current one, just append the current state
- if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
- state_coll.push_back(state);
- } else {
- // Do a binary search for the correct entry
- pair<Row::iterator, Row::iterator> range(equal_range(
- state_coll.begin(), state_coll.end(), state, AddressLessThan));
-
- // If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence
- // entry. We currently always place an extra end sequence when ever we exit
- // a valid address range for a function in case the functions get
- // rearranged by optimizations or by order specifications. These extra end
- // sequences will disappear by getting replaced with valid consecutive
- // entries within a compile unit if there are no gaps.
- if (range.first == range.second) {
- state_coll.insert(range.first, state);
- } else {
- if ((distance(range.first, range.second) == 1) &&
- range.first->end_sequence == true) {
- *range.first = state;
- } else {
- state_coll.insert(range.second, state);
- }
- }
- }
-}
-
-// DWARFDebugLine::State::State
-DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
- DWARFDebugLine::State::Callback cb, void *userData)
- : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
- callbackUserData(userData), row(StartParsingLineTable) {
- // Call the callback with the initial row state of zero for the prologue
- if (callback)
- callback(0, *this, callbackUserData);
-}
-
-// DWARFDebugLine::State::Reset
-void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
-
-// DWARFDebugLine::State::AppendRowToMatrix
-void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
- // Each time we are to add an entry into the line table matrix call the
- // callback function so that someone can do something with the current state
- // of the state machine (like build a line table or dump the line table!)
- if (log) {
- if (row == 0) {
- log->PutCString("Address Line Column File ISA Flags");
- log->PutCString(
- "------------------ ------ ------ ------ --- -------------");
- }
- Dump(log);
- }
-
- ++row; // Increase the row number before we call our callback for a real row
- if (callback)
- callback(offset, *this, callbackUserData);
- PostAppend();
-}
-
-// DWARFDebugLine::State::Finalize
-void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
- // Call the callback with a special row state when we are done parsing a line
- // table
- row = DoneParsingLineTable;
- if (callback)
- callback(offset, *this, callbackUserData);
-}
-
-// void
-// DWARFDebugLine::AppendLineTableData
-//(
-// const DWARFDebugLine::Prologue* prologue,
-// const DWARFDebugLine::Row::collection& state_coll,
-// const uint32_t addr_size,
-// BinaryStreamBuf &debug_line_data
-//)
-//{
-// if (state_coll.empty())
-// {
-// // We have no entries, just make an empty line table
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-// }
-// else
-// {
-// DWARFDebugLine::Row::const_iterator pos;
-// Row::const_iterator end = state_coll.end();
-// bool default_is_stmt = prologue->default_is_stmt;
-// const DWARFDebugLine::Row reset_state(default_is_stmt);
-// const DWARFDebugLine::Row* prev_state = &reset_state;
-// const int32_t max_line_increment_for_special_opcode =
-// prologue->MaxLineIncrementForSpecialOpcode();
-// for (pos = state_coll.begin(); pos != end; ++pos)
-// {
-// const DWARFDebugLine::Row& curr_state = *pos;
-// int32_t line_increment = 0;
-// dw_addr_t addr_offset = curr_state.address - prev_state->address;
-// dw_addr_t addr_advance = (addr_offset) / prologue->min_inst_length;
-// line_increment = (int32_t)(curr_state.line - prev_state->line);
-//
-// // If our previous state was the reset state, then let's emit the
-// // address to keep GDB's DWARF parser happy. If we don't start each
-// // sequence with a DW_LNE_set_address opcode, the line table won't
-// // get slid properly in GDB.
-//
-// if (prev_state == &reset_state)
-// {
-// debug_line_data.Append8(0); // Extended opcode
-// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
-// opcode bytes
-// debug_line_data.Append8(DW_LNE_set_address);
-// debug_line_data.AppendMax64(curr_state.address, addr_size);
-// addr_advance = 0;
-// }
-//
-// if (prev_state->file != curr_state.file)
-// {
-// debug_line_data.Append8(DW_LNS_set_file);
-// debug_line_data.Append32_as_ULEB128(curr_state.file);
-// }
-//
-// if (prev_state->column != curr_state.column)
-// {
-// debug_line_data.Append8(DW_LNS_set_column);
-// debug_line_data.Append32_as_ULEB128(curr_state.column);
-// }
-//
-// // Don't do anything fancy if we are at the end of a sequence
-// // as we don't want to push any extra rows since the
-// DW_LNE_end_sequence
-// // will push a row itself!
-// if (curr_state.end_sequence)
-// {
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push the end sequence on!
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-//
-// prev_state = &reset_state;
-// }
-// else
-// {
-// if (line_increment || addr_advance)
-// {
-// if (line_increment > max_line_increment_for_special_opcode)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// line_increment = 0;
-// }
-//
-// uint32_t special_opcode = (line_increment >=
-// prologue->line_base) ? ((line_increment -
-// prologue->line_base) + (prologue->line_range * addr_advance)
-// + prologue->opcode_base) : 256;
-// if (special_opcode > 255)
-// {
-// // Both the address and line won't fit in one special
-// opcode
-// // check to see if just the line advance will?
-// uint32_t special_opcode_line = ((line_increment >=
-// prologue->line_base) && (line_increment != 0)) ?
-// ((line_increment - prologue->line_base) +
-// prologue->opcode_base) : 256;
-//
-//
-// if (special_opcode_line > 255)
-// {
-// // Nope, the line advance won't fit by itself, check
-// the address increment by itself
-// uint32_t special_opcode_addr = addr_advance ?
-// ((0 - prologue->line_base) +
-// (prologue->line_range * addr_advance) +
-// prologue->opcode_base) : 256;
-//
-// if (special_opcode_addr > 255)
-// {
-// // Neither the address nor the line will fit in
-// a
-// // special opcode, we must manually enter both
-// then
-// // do a DW_LNS_copy to push a row (special
-// opcode
-// // automatically imply a new row is pushed)
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push a row onto the line table manually
-// debug_line_data.Append8(DW_LNS_copy);
-//
-// }
-// else
-// {
-// // The address increment alone will fit into a
-// special opcode
-// // so modify our line change, then issue a
-// special opcode
-// // for the address increment and it will push a
-// row into the
-// // line table
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line
-// table
-// debug_line_data.Append8(special_opcode_addr);
-// }
-// }
-// else
-// {
-// // The line change alone will fit into a special
-// opcode
-// // so modify our address increment first, then issue
-// a
-// // special opcode for the line change and it will
-// push
-// // a row into the line table
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode_line);
-// }
-// }
-// else
-// {
-// // Advance of line and address will fit into a single
-// byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode);
-// }
-// }
-// prev_state = &curr_state;
-// }
-// }
-// }
-//}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
deleted file mode 100644
index 0d236ca686b5..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===-- DWARFDebugLine.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 SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-private.h"
-
-#include "DWARFDataExtractor.h"
-#include "DWARFDefines.h"
-
-#include "llvm/Support/MD5.h"
-
-class DWARFUnit;
-class SymbolFileDWARF;
-
-// DWARFDebugLine
-class DWARFDebugLine {
-public:
- // FileNameEntry
- struct FileNameEntry {
- FileNameEntry()
- : name(nullptr), dir_idx(0), mod_time(0), length(0), checksum() {}
-
- const char *name;
- dw_sleb128_t dir_idx;
- dw_sleb128_t mod_time;
- dw_sleb128_t length;
- llvm::MD5::MD5Result checksum;
- };
-
- // Prologue
- struct Prologue {
-
- Prologue()
- : total_length(0), version(0), prologue_length(0), min_inst_length(0),
- default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
- standard_opcode_lengths(), include_directories(), file_names() {}
-
- typedef std::shared_ptr<Prologue> shared_ptr;
-
- uint32_t total_length; // The size in bytes of the statement information for
- // this compilation unit (not including the
- // total_length field itself).
- uint16_t
- version; // Version identifier for the statement information format.
-
- uint8_t address_size;
- uint8_t segment_selector_size;
-
- uint32_t prologue_length; // The number of bytes following the
- // prologue_length field to the beginning of the
- // first byte of the statement program itself.
- uint8_t min_inst_length; // The size in bytes of the smallest target machine
- // instruction. Statement program opcodes that
- // alter the address register first multiply their
- // operands by this value.
- uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum
- // number of individual
- // operations that may be
- // encoded in an instruction.
- uint8_t default_is_stmt; // The initial value of theis_stmtregister.
- int8_t line_base; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t line_range; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t opcode_base; // The number assigned to the first special opcode.
- std::vector<uint8_t> standard_opcode_lengths;
- std::vector<const char *> include_directories;
- std::vector<FileNameEntry> file_names;
-
- int32_t MaxLineIncrementForSpecialOpcode() const {
- return line_base + (int8_t)line_range - 1;
- }
- bool IsValid() const;
- // void Append(BinaryStreamBuf& buff) const;
- void Dump(lldb_private::Log *log);
- void Clear() {
- total_length = version = prologue_length = min_inst_length = line_base =
- line_range = opcode_base = 0;
- line_base = 0;
- standard_opcode_lengths.clear();
- include_directories.clear();
- file_names.clear();
- }
- bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
- lldb_private::FileSpec::Style style,
- lldb_private::FileSpec &file) const;
- };
-
- // Standard .debug_line state machine structure
- struct Row {
- typedef std::vector<Row> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- Row(bool default_is_stmt = false);
- virtual ~Row() {}
- void PostAppend();
- void Reset(bool default_is_stmt);
- void Dump(lldb_private::Log *log) const;
- static void Insert(Row::collection &state_coll, const Row &state);
-
- dw_addr_t address; // The program-counter value corresponding to a machine
- // instruction generated by the compiler.
- uint32_t line; // An unsigned integer indicating a source line number. Lines
- // are numbered beginning at 1. The compiler may emit the
- // value 0 in cases where an instruction cannot be attributed
- // to any source line.
- uint16_t column; // An unsigned integer indicating a column number within a
- // source line. Columns are numbered beginning at 1. The
- // value 0 is reserved to indicate that a statement begins
- // at the 'left edge' of the line.
- uint16_t file; // An unsigned integer indicating the identity of the source
- // file corresponding to a machine instruction.
- uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
- // the beginning of a statement.
- basic_block : 1, // A boolean indicating that the current instruction is
- // the beginning of a basic block.
- end_sequence : 1, // A boolean indicating that the current address is
- // that of the first byte after the end of a sequence
- // of target machine instructions.
- prologue_end : 1, // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an entry breakpoint of a function.
- epilogue_begin : 1; // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an exit breakpoint of a function.
- uint32_t isa; // An unsigned integer whose value encodes the applicable
- // instruction set architecture for the current instruction.
- };
-
- // LineTable
- struct LineTable {
- typedef std::shared_ptr<LineTable> shared_ptr;
-
- LineTable() : prologue(), rows() {}
-
- void AppendRow(const DWARFDebugLine::Row &state);
- void Clear() {
- prologue.reset();
- rows.clear();
- }
-
- uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
-
- Prologue::shared_ptr prologue;
- Row::collection rows;
- };
-
- // State
- struct State : public Row {
- typedef void (*Callback)(dw_offset_t offset, const State &state,
- void *userData);
-
- // Special row codes used when calling the callback
- enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
-
- State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
- Callback callback, void *userData);
-
- void AppendRowToMatrix(dw_offset_t offset);
-
- void Finalize(dw_offset_t offset);
-
- void Reset();
-
- Prologue::shared_ptr prologue;
- lldb_private::Log *log;
- Callback callback; // Callback function that gets called each time an entry
- // is to be added to the matrix
- void *callbackUserData;
- int row; // The row number that starts at zero for the prologue, and
- // increases for each row added to the matrix
- private:
- DISALLOW_COPY_AND_ASSIGN(State);
- };
-
- static bool
- ParseSupportFiles(const lldb::ModuleSP &module_sp,
- const lldb_private::DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files,
- DWARFUnit *dwarf_cu);
- static bool
- ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, Prologue *prologue,
- DWARFUnit *dwarf_cu = nullptr);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, State::Callback callback,
- void *userData, DWARFUnit *dwarf_cu);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, LineTable *line_table,
- DWARFUnit *dwarf_cu);
- static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback, void *userData);
- // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
- // const DWARFDebugLine::Row::collection& state_coll, const uint32_t
- // addr_size, BinaryStreamBuf &debug_line_data);
-
- DWARFDebugLine() : m_lineTableMap() {}
-
- void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
- void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
- LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
-
-protected:
- typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
- typedef LineTableMap::iterator LineTableIter;
- typedef LineTableMap::const_iterator LineTableConstIter;
-
- LineTableMap m_lineTableMap;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 207c71211c9a..0b08fa09f906 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -123,11 +123,6 @@ bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
return false;
}
-uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
- lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
- return 0;
-}
-
bool DWARFDebugRngLists::ExtractRangeList(
const DWARFDataExtractor &data, uint8_t addrSize,
lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index baf2667f0afe..c398259056b3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -24,7 +24,6 @@ public:
virtual void Extract(lldb_private::DWARFContext &context) = 0;
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const = 0;
- virtual uint64_t GetOffset(size_t Index) const = 0;
};
class DWARFDebugRanges final : public DWARFDebugRangesBase {
@@ -34,7 +33,6 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
static void Dump(lldb_private::Stream &s,
const lldb_private::DWARFDataExtractor &debug_ranges_data,
@@ -62,7 +60,7 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
+ uint64_t GetOffset(size_t Index) const;
protected:
bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index d0d70dd5123e..6501ac27f27d 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -23,7 +23,7 @@
class DWARFDeclContext {
public:
struct Entry {
- Entry() : tag(0), name(nullptr) {}
+ Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {}
Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
bool NameMatches(const Entry &rhs) const {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 3bf0bb088227..2ae1bbc9f507 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -59,6 +59,8 @@ const char *DW_OP_value_to_name(uint32_t val) {
}
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;
@@ -358,6 +360,8 @@ DRC_class DW_OP_value_to_class(uint32_t val) {
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:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 33e83d1fe57f..9964cf4b893c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -438,7 +438,7 @@ lldb::ByteOrder DWARFUnit::GetByteOrder() const {
return m_dwarf.GetObjectFile()->GetByteOrder();
}
-TypeSystem *DWARFUnit::GetTypeSystem() {
+llvm::Expected<TypeSystem &> DWARFUnit::GetTypeSystem() {
return m_dwarf.GetTypeSystemForLanguage(GetLanguageType());
}
@@ -540,19 +540,15 @@ void DWARFUnit::ParseProducerInfo() {
} else if (strstr(producer_cstr, "clang")) {
static RegularExpression g_clang_version_regex(
llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
- RegularExpression::Match regex_match(3);
+ llvm::SmallVector<llvm::StringRef, 4> matches;
if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
- &regex_match)) {
- std::string str;
- if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
- m_producer_version_major =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
- m_producer_version_minor =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
- m_producer_version_update =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ &matches)) {
+ m_producer_version_major =
+ StringConvert::ToUInt32(matches[1].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_minor =
+ StringConvert::ToUInt32(matches[2].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_update =
+ StringConvert::ToUInt32(matches[3].str().c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
} else if (strstr(producer_cstr, "GNU"))
@@ -870,7 +866,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
- const DWARFDebugRangesBase *debug_rnglists = m_dwarf.GetDebugRngLists();
+ const DWARFDebugRngLists *debug_rnglists = m_dwarf.GetDebugRngLists();
if (!debug_rnglists)
return llvm::make_error<llvm::object::GenericBinaryError>(
"No debug_rnglists section");
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 8aa1e449f3ed..87e0de283de4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -153,7 +153,7 @@ public:
lldb::ByteOrder GetByteOrder() const;
- lldb_private::TypeSystem *GetTypeSystem();
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem();
const DWARFDebugAranges &GetFunctionAranges();
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 9746ad76c930..007ef2e05e59 100644
--- a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -24,7 +24,7 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
return llvm::make_error<llvm::StringError>("debug info null",
llvm::inconvertibleErrorCode());
}
- auto index_up = llvm::make_unique<DebugNames>(debug_names.GetAsLLVM(),
+ auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
@@ -105,7 +105,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -125,7 +125,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
uint64_t cu_offset = cu.GetOffset();
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -248,7 +248,7 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
Tag tag = entry_or->tag();
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 62b0ad37a9fc..88a29f4a2672 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -125,7 +125,7 @@ DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
: die_base_offset(_die_base_offset), atoms(), atom_mask(0),
min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
// Define an array of DIE offsets by first defining an array, and then define
- // the atom type for the array, in this case we have an array of DIE offsets
+ // the atom type for the array, in this case we have an array of DIE offsets.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
}
@@ -208,9 +208,10 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
const uint32_t atom_count = data.GetU32(&offset);
if (atom_count == 0x00060003u) {
- // Old format, deal with contents of old pre-release format
- while (data.GetU32(&offset))
+ // Old format, deal with contents of old pre-release format.
+ while (data.GetU32(&offset)) {
/* do nothing */;
+ }
// Hardcode to the only known value for now.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
@@ -226,7 +227,7 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
size_t DWARFMappedHash::Prologue::GetByteSize() const {
// Add an extra count to the atoms size for the zero termination Atom that
- // gets written to disk
+ // gets written to disk.
return sizeof(die_base_offset) + sizeof(uint32_t) +
atoms.size() * sizeof(Atom);
}
@@ -286,7 +287,7 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
break;
default:
- // We can always skip atoms we don't know about
+ // We can always skip atoms we don't know about.
break;
}
}
@@ -308,8 +309,8 @@ DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
HashData &hash_data) const {
lldb::offset_t offset = hash_data_offset;
- offset += 4; // Skip string table offset that contains offset of hash name in
- // .debug_str
+ // Skip string table offset that contains offset of hash name in .debug_str.
+ offset += 4;
const uint32_t count = m_data.GetU32(&offset);
if (count > 0) {
hash_data.resize(count);
@@ -335,7 +336,7 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr) {
*hash_data_offset_ptr = UINT32_MAX;
@@ -345,9 +346,8 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
// We have at least one HashData entry, and we have enough data to parse at
// least "count" HashData entries.
@@ -370,21 +370,22 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
if (match)
pair.value.push_back(die_info);
} else {
- // Something went wrong while reading the data
+ // Something went wrong while reading the data.
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
}
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -402,7 +403,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr)
return eResultError;
@@ -410,9 +411,8 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
const bool match = regex.Execute(llvm::StringRef(strp_cstr));
if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
@@ -438,14 +438,15 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -466,7 +467,7 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
if (prev_hash_data_offset == hash_data_offset)
break;
- // Check the result of getting our hash data
+ // Check the result of getting our hash data.
switch (hash_result) {
case eResultKeyMatch:
case eResultKeyMismatch:
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index a01612b59528..56d9bc548877 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -24,37 +24,41 @@ class DWARFMappedHash {
public:
enum AtomType : uint16_t {
eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that
- // contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1
- // (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
- eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name
- // (since all hash entries are basename only)
- // For example a type like "std::vector<int>::iterator" would have a name of
- // "iterator"
- // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not
- // have to pull
- // in debug info for a type when we know the fully qualified name.
+ /// DIE offset, check form for encoding.
+ eAtomTypeDIEOffset = 1u,
+ /// DIE offset of the compiler unit header that contains the item in
+ /// question.
+ eAtomTypeCUOffset = 2u,
+ /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed
+ /// 255) or DW_FORM_data2.
+ eAtomTypeTag = 3u,
+ // Flags from enum NameFlags.
+ eAtomTypeNameFlags = 4u,
+ // Flags from enum TypeFlags.
+ eAtomTypeTypeFlags = 5u,
+ /// A 32 bit hash of the full qualified name (since all hash entries are
+ /// basename only) For example a type like "std::vector<int>::iterator"
+ /// would have a name of "iterator" and a 32 bit hash for
+ /// "std::vector<int>::iterator" to allow us to not have to pull in debug
+ /// info for a type when we know the fully qualified name.
+ eAtomTypeQualNameHash = 6u
};
- // Bit definitions for the eAtomTypeTypeFlags flags
+ /// Bit definitions for the eAtomTypeTypeFlags flags.
enum TypeFlags {
- // Always set for C++, only set for ObjC if this is the
- // @implementation for class
+ /// Always set for C++, only set for ObjC if this is the
+ /// @implementation for class.
eTypeFlagClassIsImplementation = (1u << 1)
};
struct DIEInfo {
dw_offset_t die_offset = DW_INVALID_OFFSET;
- dw_tag_t tag = 0;
+ dw_tag_t tag = llvm::dwarf::DW_TAG_null;
- /// Any flags for this DIEInfo
+ /// Any flags for this DIEInfo.
uint32_t type_flags = 0;
- /// A 32 bit hash of the fully qualified name
+ /// A 32 bit hash of the fully qualified name.
uint32_t qualified_name_hash = 0;
DIEInfo() = default;
@@ -94,7 +98,7 @@ public:
bool HashDataHasFixedByteSize() const;
- // DIE offset base so die offsets in hash_data can be CU relative
+ /// DIE offset base so die offsets in hash_data can be CU relative.
dw_offset_t die_base_offset;
AtomArray atoms;
uint32_t atom_mask;
@@ -113,8 +117,8 @@ public:
lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
};
- // A class for reading and using a saved hash table from a block of data
- // in memory
+ /// A class for reading and using a saved hash table from a block of data in
+ /// memory.
class MemoryTable
: public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
DIEInfoArray> {
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index e2ddcfc5d64b..c982d59c2830 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -8,6 +8,7 @@
#include "SymbolFileDWARF.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -43,7 +44,7 @@
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
@@ -58,7 +59,6 @@
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
-#include "DWARFDebugLine.h"
#include "DWARFDebugMacro.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
@@ -72,6 +72,7 @@
#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDwp.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/FileSystem.h"
#include <algorithm>
@@ -113,18 +114,12 @@ using namespace lldb_private;
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- {},
- "If the DW_AT_comp_dir matches any of these paths the symbolic "
- "links will be resolved at DWARF parse time."},
- {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {},
- "Ignore indexes present in the object files and always index DWARF "
- "manually."}};
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFProperties.inc"
enum {
- ePropertySymLinkPaths,
- ePropertyIgnoreIndexes,
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFPropertiesEnum.inc"
};
class PluginProperties : public Properties {
@@ -135,7 +130,7 @@ public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_symbolfiledwarf_properties);
}
FileSpecList GetSymLinkPaths() {
@@ -159,7 +154,66 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-} // anonymous namespace end
+} // namespace
+
+static const llvm::DWARFDebugLine::LineTable *
+ParseLLVMLineTable(lldb_private::DWARFContext &context,
+ llvm::DWARFDebugLine &line, dw_offset_t line_offset,
+ dw_offset_t unit_offset) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+
+ llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = context.GetAsLLVM();
+ 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");
+ });
+
+ if (!line_table) {
+ LLDB_LOG_ERROR(log, line_table.takeError(),
+ "SymbolFileDWARF::ParseLineTable failed to parse");
+ return nullptr;
+ }
+ return *line_table;
+}
+
+static FileSpecList ParseSupportFilesFromPrologue(
+ const lldb::ModuleSP &module,
+ const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,
+ llvm::StringRef compile_dir = {}, FileSpec first_file = {}) {
+ FileSpecList support_files;
+ support_files.Append(first_file);
+
+ const size_t number_of_files = prologue.FileNames.size();
+ for (size_t idx = 1; idx <= number_of_files; ++idx) {
+ std::string original_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::Default, original_file,
+ style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack();
+ continue;
+ }
+
+ std::string remapped_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ remapped_file, style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack(original_file, style);
+ continue;
+ }
+
+ module->RemapSourceFile(llvm::StringRef(original_file), remapped_file);
+ support_files.EmplaceBack(remapped_file, style);
+ }
+
+ return support_files;
+}
FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
return GetGlobalPluginProperties()->GetSymLinkPaths();
@@ -197,20 +251,16 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader.";
}
-SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARF(obj_file,
+SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARF(std::move(objfile_sp),
/*dwo_section_list*/ nullptr);
}
-TypeList *SymbolFileDWARF::GetTypeList() {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
+TypeList &SymbolFileDWARF::GetTypeList() {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
return debug_map_symfile->GetTypeList();
- else
- return m_obj_file->GetModule()->GetTypeList();
+ return SymbolFile::GetTypeList();
}
void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
@@ -264,6 +314,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
case DW_TAG_ptr_to_member_type:
add_type = (type_mask & eTypeClassMemberPointer) != 0;
break;
+ default:
+ break;
}
if (add_type) {
@@ -283,11 +335,11 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
}
}
-size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask, TypeList &type_list)
+void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask, TypeList &type_list)
{
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeSet type_set;
CompileUnit *comp_unit = nullptr;
@@ -297,8 +349,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
if (comp_unit) {
dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == nullptr)
- return 0;
+ if (!dwarf_cu)
+ return;
GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
} else {
@@ -315,16 +367,13 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
}
std::set<CompilerType> compiler_type_set;
- size_t num_types_added = 0;
for (Type *type : type_set) {
CompilerType compiler_type = type->GetForwardCompilerType();
if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
compiler_type_set.insert(compiler_type);
type_list.Insert(type->shared_from_this());
- ++num_types_added;
}
}
- return num_types_added;
}
// Gets the first parent that is a lexical block, function or inlined
@@ -342,19 +391,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
return die;
+ default:
+ break;
}
}
return DWARFDIE();
}
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile,
+SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
SectionList *dwo_section_list)
- : SymbolFile(objfile),
+ : SymbolFile(std::move(objfile_sp)),
UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to
// when this class parses .o files to
// contain the .o file index/ID
m_debug_map_module_wp(), m_debug_map_symfile(nullptr),
- m_context(objfile->GetModule()->GetSectionList(), dwo_section_list),
+ 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() {}
@@ -374,17 +425,17 @@ UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
return m_unique_ast_type_map;
}
-TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- TypeSystem *type_system;
- if (debug_map_symfile) {
- type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
- } else {
- type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
+llvm::Expected<TypeSystem &>
+SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
+ return debug_map_symfile->GetTypeSystemForLanguage(language);
+
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
}
- return type_system;
+ return type_system_or_err;
}
void SymbolFileDWARF::InitializeObject() {
@@ -420,7 +471,7 @@ void SymbolFileDWARF::InitializeObject() {
}
}
- m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+ m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
DebugInfo());
}
@@ -430,9 +481,9 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
uint32_t SymbolFileDWARF::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file != nullptr) {
+ if (m_objfile_sp != nullptr) {
const Section *section = nullptr;
- const SectionList *section_list = m_obj_file->GetSectionList();
+ const SectionList *section_list = m_objfile_sp->GetSectionList();
if (section_list == nullptr)
return 0;
@@ -462,10 +513,12 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
abbrev->GetUnsupportedForms(invalid_forms);
if (!invalid_forms.empty()) {
StreamString error;
- error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+ error.Printf("unsupported DW_FORM value%s:",
+ invalid_forms.size() > 1 ? "s" : "");
for (auto form : invalid_forms)
error.Printf(" %#x", form);
- m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+ m_objfile_sp->GetModule()->ReportWarning(
+ "%s", error.GetString().str().c_str());
return 0;
}
}
@@ -477,10 +530,10 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
debug_line_file_size = section->GetFileSize();
} else {
const char *symfile_dir_cstr =
- m_obj_file->GetFileSpec().GetDirectory().GetCString();
+ m_objfile_sp->GetFileSpec().GetDirectory().GetCString();
if (symfile_dir_cstr) {
if (strcasestr(symfile_dir_cstr, ".dsym")) {
- if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
+ if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {
// We have a dSYM file that didn't have a any debug info. If the
// string table has a size of 1, then it was made from an
// executable with no debug info, or from an executable that was
@@ -489,7 +542,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
.get();
if (section && section->GetFileSize() == 1) {
- m_obj_file->GetModule()->ReportWarning(
+ m_objfile_sp->GetModule()->ReportWarning(
"empty dSYM file detected, dSYM was created with an "
"executable with no debug info.");
}
@@ -519,7 +572,7 @@ SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
const SectionList *section_list = module_sp->GetSectionList();
if (!section_list)
return;
@@ -529,7 +582,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
return;
data.Clear();
- m_obj_file->ReadSectionData(section_sp.get(), data);
+ m_objfile_sp->ReadSectionData(section_sp.get(), data);
}
const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() {
@@ -556,7 +609,7 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (debug_abbrev_data.GetByteSize() == 0)
return nullptr;
- auto abbr = llvm::make_unique<DWARFDebugAbbrev>();
+ auto abbr = std::make_unique<DWARFDebugAbbrev>();
llvm::Error error = abbr->parse(debug_abbrev_data);
if (error) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
@@ -579,7 +632,7 @@ DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
- m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context);
+ m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
}
return m_info.get();
}
@@ -604,7 +657,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return nullptr;
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
+DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
if (!m_ranges) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -619,7 +672,7 @@ DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
return m_ranges.get();
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() {
+DWARFDebugRngLists *SymbolFileDWARF::GetDebugRngLists() {
if (!m_rnglists) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -648,7 +701,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
dwarf_cu.SetUserData(cu_sp.get());
} else {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
if (module_sp) {
const DWARFDIE cu_die = dwarf_cu.DIE();
if (cu_die) {
@@ -677,8 +730,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
dwarf_cu.SetUserData(cu_sp.get());
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- dwarf_cu.GetID(), cu_sp);
+ SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
}
}
}
@@ -715,7 +767,7 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
return m_lldb_cu_to_dwarf_unit[cu_idx];
}
-uint32_t SymbolFileDWARF::GetNumCompileUnits() {
+uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
DWARFDebugInfo *info = DebugInfo();
if (!info)
return 0;
@@ -741,17 +793,21 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
const DWARFDIE &die) {
ASSERT_MODULE_LOCK(this);
- if (die.IsValid()) {
- TypeSystem *type_system =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system) {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
- }
+ if (!die.IsValid())
+ return nullptr;
+
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse function");
+ return nullptr;
}
- return nullptr;
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+ if (!dwarf_ast)
+ return nullptr;
+
+ return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
}
bool SymbolFileDWARF::FixupAddress(Address &addr) {
@@ -763,7 +819,7 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {
return true;
}
lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetLanguageType();
@@ -772,7 +828,7 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (!dwarf_cu)
return 0;
@@ -790,21 +846,23 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
return functions_added;
}
+void SymbolFileDWARF::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ UpdateExternalModuleListIfNeeded();
+
+ for (auto &p : m_external_type_modules) {
+ ModuleSP module = p.second;
+ f(module);
+ for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i)
+ module->GetCompileUnitAtIndex(i)->ForEachExternalModule(f);
+ }
+}
+
bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
- ASSERT_MODULE_LOCK(this);
- if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) {
- const dw_offset_t stmt_list = unit->GetLineTableOffset();
- if (stmt_list != DW_INVALID_OFFSET) {
- // All file indexes in DWARF are one based and a file of index zero is
- // supposed to be the compile unit itself.
- support_files.Append(comp_unit);
- return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(),
- m_context.getOrLoadLineData(),
- stmt_list, support_files, unit);
- }
- }
- return false;
+ if (!comp_unit.GetLineTable())
+ ParseLineTable(comp_unit);
+ return true;
}
FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
@@ -833,16 +891,26 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
auto iter_bool = m_type_unit_support_files.try_emplace(offset);
FileSpecList &list = iter_bool.first->second;
if (iter_bool.second) {
- list.Append(FileSpec());
- DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(),
- m_context.getOrLoadLineData(), offset,
- list, &tu);
+ uint64_t line_table_offset = offset;
+ 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) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
+ "the line table prologue");
+ } else {
+ list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(),
+ prologue, tu.GetPathStyle());
+ }
}
return list;
}
bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetIsOptimized();
@@ -852,7 +920,7 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<SourceModule> &imported_modules) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
assert(sc.comp_unit);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (!dwarf_cu)
@@ -901,102 +969,63 @@ bool SymbolFileDWARF::ParseImportedModules(
return true;
}
-struct ParseDWARFLineTableCallbackInfo {
- LineTable *line_table;
- std::unique_ptr<LineSequence> sequence_up;
- lldb::addr_t addr_mask;
-};
-
-// ParseStatementTableCallback
-static void ParseDWARFLineTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- ParseDWARFLineTableCallbackInfo *info =
- (ParseDWARFLineTableCallbackInfo *)userData;
- LineTable *line_table = info->line_table;
-
- // If this is our first time here, we need to create a sequence container.
- if (!info->sequence_up) {
- info->sequence_up.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_up.get());
- }
- line_table->AppendLineEntryToSequence(
- info->sequence_up.get(), state.address & info->addr_mask, state.line,
- state.column, state.file, state.is_stmt, state.basic_block,
- state.prologue_end, state.epilogue_begin, state.end_sequence);
- if (state.end_sequence) {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->sequence_up.get());
- // Then, empty it to prepare for the next sequence.
- info->sequence_up->Clear();
- }
- }
-}
-
bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable() != nullptr)
return true;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
- if (dwarf_cu) {
- const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
- if (dwarf_cu_die) {
- 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) {
- std::unique_ptr<LineTable> line_table_up(new LineTable(&comp_unit));
- if (line_table_up) {
- ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_up.get();
-
- /*
- * MIPS:
- * The SymbolContext may not have a valid target, thus we may not be
- * able
- * to call Address::GetOpcodeLoadAddress() which would clear the bit
- * #0
- * for MIPS. Use ArchSpec to clear the bit #0.
- */
- switch (GetObjectFile()->GetArchitecture().GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- info.addr_mask = ~((lldb::addr_t)1);
- break;
- default:
- info.addr_mask = ~((lldb::addr_t)0);
- break;
- }
+ if (!dwarf_cu)
+ return false;
- lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(
- m_context.getOrLoadLineData(), &offset,
- ParseDWARFLineTableCallback, &info, dwarf_cu);
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile) {
- // 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 are relative to the .o file into addresses for
- // the main executable.
- comp_unit.SetLineTable(
- debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
- } else {
- comp_unit.SetLineTable(line_table_up.release());
- return true;
- }
- }
- }
+ 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)
+ return false;
+
+ llvm::DWARFDebugLine line;
+ const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(
+ m_context, line, cu_line_offset, dwarf_cu->GetOffset());
+
+ if (!line_table)
+ return false;
+
+ // 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();
+ for (auto &row : line_table->Rows) {
+ line_table_up->AppendLineEntryToSequence(
+ sequence, 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();
}
}
- return false;
+
+ 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
+ // are relative to the .o file into addresses for the main executable.
+ comp_unit.SetLineTable(
+ debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
+ } else {
+ comp_unit.SetLineTable(line_table_up.release());
+ }
+
+ comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
+ comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(),
+ dwarf_cu->GetCompilationDirectory().GetCString(), FileSpec(comp_unit)));
+
+ return true;
}
lldb_private::DebugMacrosSP
@@ -1022,7 +1051,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
}
bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu == nullptr)
@@ -1114,7 +1143,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
"0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64
") which has a base that is less than the function's low PC "
"0x%" PRIx64 ". Please file a bug and attach the file at the "
- "start of this error message",
+ "start of this error message",
block->GetID(), range_base, range.GetRangeEnd(),
subprogram_low_pc);
}
@@ -1188,15 +1217,10 @@ bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
}
void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
- TypeSystem *type_system = decl_ctx.GetTypeSystem();
- DWARFASTParser *ast_parser = type_system->GetDWARFParser();
- std::vector<DWARFDIE> decl_ctx_die_list =
- ast_parser->GetDIEForDeclContext(decl_ctx);
-
- for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
- for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl;
- decl = decl.GetSibling())
- ast_parser->GetDeclForUIDFromDWARF(decl);
+ auto *type_system = decl_ctx.GetTypeSystem();
+ if (type_system != nullptr)
+ type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(
+ decl_ctx);
}
user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
@@ -1281,8 +1305,6 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIE(). See comments inside the
@@ -1293,8 +1315,6 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
}
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIE(). See comments inside the
@@ -1341,8 +1361,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
// Get the type, which could be a forward declaration
if (log)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
- "resolve parent forward type for 0x%8.8x",
+ log,
+ "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
+ "resolve parent forward type for 0x%8.8x",
die.GetOffset(), die.GetTagAsCString(), die.GetName(),
decl_ctx_die.GetOffset());
} break;
@@ -1504,7 +1525,6 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
->GetDIE(die_ref);
}
-
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info)
return debug_info->GetDIE(die_ref);
@@ -1567,7 +1587,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (dwo_obj_file == nullptr)
return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
+ return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
}
void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
@@ -1607,7 +1627,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
}
dwo_module_spec.GetArchitecture() =
- m_obj_file->GetModule()->GetArchitecture();
+ m_objfile_sp->GetModule()->GetArchitecture();
// When LLDB loads "external" modules it looks at the presence of
// DW_AT_GNU_dwo_name. However, when the already created module
@@ -1621,8 +1641,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
// printed. However, as one can notice in this case we don't
// actually need to try to load the already loaded module
// (corresponding to .dwo) so we simply skip it.
- if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" &&
- llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
+ if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
+ llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
.endswith(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
}
@@ -1694,6 +1714,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARF::"
@@ -1837,6 +1858,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool check_inlines,
SymbolContextItem resolve_scope,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
@@ -1849,7 +1871,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool file_spec_matches_cu_file_spec =
FileSpec::Equal(file_spec, *dc_cu, full_match);
if (check_inlines || file_spec_matches_cu_file_spec) {
- SymbolContext sc(m_obj_file->GetModule());
+ SymbolContext sc(m_objfile_sp->GetModule());
sc.comp_unit = dc_cu;
uint32_t file_idx = UINT32_MAX;
@@ -1961,9 +1983,16 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
}
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to match namespace decl using TypeSystem");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
// The namespace AST was valid, and it does not match...
@@ -1976,9 +2005,10 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
return false;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(
+void SymbolFileDWARF::FindGlobalVariables(
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));
if (log)
@@ -1990,11 +2020,11 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
max_matches);
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2012,7 +2042,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
// Loop invariant: Variables up to this index have been checked for context
@@ -2081,12 +2111,12 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
name.GetCString(), static_cast<const void *>(parent_decl_ctx),
max_matches, num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
+void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
+ uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2098,8 +2128,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
}
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2108,7 +2138,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->GetGlobalVariables(regex, die_offsets);
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
const size_t num_matches = die_offsets.size();
@@ -2132,9 +2162,6 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->ReportInvalidDIERef(die_ref, regex.GetText());
}
}
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
@@ -2210,10 +2237,12 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
return false;
}
-uint32_t SymbolFileDWARF::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(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());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
@@ -2226,21 +2255,17 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, append=%u, sc_list)",
- name.GetCString(), name_type_mask, append);
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+ name.GetCString(), name_type_mask);
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
// If name is empty then we won't find anything.
if (name.IsEmpty())
- return 0;
+ return;
// Remember how many sc_list are in the list before we search in case we are
// appending the results to a variable list.
@@ -2255,7 +2280,7 @@ uint32_t SymbolFileDWARF::FindFunctions(
std::vector<DWARFDIE> dies;
m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies);
- for (const DWARFDIE &die: dies) {
+ for (const DWARFDIE &die : dies) {
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
@@ -2265,18 +2290,18 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log && num_matches > 0) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => "
- "%u",
- name.GetCString(), name_type_mask, include_inlines, append,
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
+ name.GetCString(), name_type_mask, include_inlines,
num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
@@ -2285,22 +2310,13 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
- regex.GetText().str().c_str(), append);
+ log, "SymbolFileDWARF::FindFunctions (regex=\"%s\", sc_list)",
+ regex.GetText().str().c_str());
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
DWARFDebugInfo *info = DebugInfo();
if (!info)
- return 0;
-
- // Remember how many sc_list are in the list before we search in case we are
- // appending the results to a variable list.
- uint32_t original_size = sc_list.GetSize();
+ return;
DIEArray offsets;
m_index->GetFunctions(regex, offsets);
@@ -2315,9 +2331,6 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
-
- // Return the number of variable that were appended to the list
- return sc_list.GetSize() - original_size;
}
void SymbolFileDWARF::GetMangledNamesForFunction(
@@ -2345,156 +2358,141 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
}
-uint32_t SymbolFileDWARF::FindTypes(
+void SymbolFileDWARF::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Make sure we haven't already searched this SymbolFile before...
if (searched_symbol_files.count(this))
- return 0;
- else
- searched_symbol_files.insert(this);
+ return;
+
+ searched_symbol_files.insert(this);
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
if (parent_decl_ctx)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "%p (\"%s\"), append=%u, max_matches=%u, type_list)",
+ 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>"), append, max_matches);
+ parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches);
else
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "NULL, append=%u, max_matches=%u, type_list)",
- name.GetCString(), append, max_matches);
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "NULL, max_matches=%u, type_list)",
+ name.GetCString(), max_matches);
}
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- const uint32_t initial_types_size = types.GetSize();
- 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());
- }
- }
- const uint32_t num_matches = types.GetSize() - initial_types_size;
- if (log && num_matches) {
- if (parent_decl_ctx) {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
- "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches,
- num_matches);
- } else {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
- "= NULL, append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), append, max_matches, num_matches);
+ 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());
}
- return num_matches;
- } else {
+ }
+
+ // 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) {
UpdateExternalModuleListIfNeeded();
- for (const auto &pair : m_external_type_modules) {
- ModuleSP external_module_sp = pair.second;
- if (external_module_sp) {
- SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
- if (sym_vendor) {
- const uint32_t num_external_matches =
- sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types);
- if (num_external_matches)
- return num_external_matches;
- }
- }
- }
+ for (const auto &pair : m_external_type_modules)
+ 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);
}
- return 0;
+ if (log && types.GetSize()) {
+ if (parent_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ 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,
+ types.GetSize());
+ } else {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= NULL, max_matches=%u, type_list) => %u",
+ name.GetCString(), max_matches, types.GetSize());
+ }
+ }
}
-size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
-
- if (context.empty())
- return 0;
+void SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (pattern.empty())
+ return;
- ConstString name = context.back().name;
+ ConstString name = pattern.back().name;
if (!name)
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- size_t num_matches = 0;
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
- if (die) {
- std::vector<CompilerContext> die_context;
- die.GetDeclContext(die_context);
- if (die_context != context)
- continue;
-
- 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());
- ++num_matches;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
+ if (!die) {
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
+ continue;
}
- return num_matches;
+ if (!languages[die.GetCU()->GetLanguageType()])
+ continue;
+
+ llvm::SmallVector<CompilerContext, 4> die_context;
+ die.GetDeclContext(die_context);
+ if (!contextMatches(die_context, pattern))
+ continue;
+
+ 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 0;
}
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2536,8 +2534,9 @@ SymbolFileDWARF::FindNamespace(ConstString name,
}
if (log && namespace_decl_ctx) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
- "CompilerDeclContext(%p/%p) \"%s\"",
+ log,
+ "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
+ "CompilerDeclContext(%p/%p) \"%s\"",
name.GetCString(),
static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
@@ -2632,11 +2631,10 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
return DWARFDIE();
}
-Symbol *
-SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
+Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
Symbol *objc_class_symbol = nullptr;
- if (m_obj_file) {
- Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
@@ -2653,8 +2651,7 @@ SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
// worry about the debug map
// DWARF file
// if we are doing darwin DWARF in .o file debugging.
-bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
- DWARFUnit *cu) {
+bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
@@ -2681,8 +2678,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
- const DWARFDIE &die, ConstString type_name,
- bool must_be_implementation) {
+ const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {
TypeSP type_sp;
@@ -2727,7 +2723,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
" (cu 0x%8.8" PRIx64 ")\n",
die.GetID(),
- m_obj_file->GetFileSpec().GetFilename().AsCString(
+ m_objfile_sp->GetFileSpec().GetFilename().AsCString(
"<Unknown>"),
type_die.GetID(), type_cu->GetID());
@@ -2849,8 +2845,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
DWARF_LOG_LOOKUPS));
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
- "s, qualified-name='%s')",
+ log,
+ "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
+ "s, qualified-name='%s')",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName());
}
@@ -2863,10 +2860,18 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
// use this to ensure any matches we find are in a language that this
// type system supports
const LanguageType language = dwarf_decl_ctx.GetLanguage();
- TypeSystem *type_system = (language == eLanguageTypeUnknown)
- ? nullptr
- : GetTypeSystemForLanguage(language);
-
+ TypeSystem *type_system = nullptr;
+ if (language != eLanguageTypeUnknown) {
+ auto type_system_or_err = GetTypeSystemForLanguage(language);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Cannot get TypeSystem for language {}",
+ Language::GetNameForLanguageType(language));
+ } else {
+ 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];
@@ -2916,9 +2921,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') trying die=0x%8.8x (%s)",
+ 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());
@@ -2937,9 +2943,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
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)",
+ 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());
@@ -2960,21 +2967,21 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
if (!die)
return {};
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
- if (!type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse type");
return {};
+ }
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
if (!dwarf_ast)
return {};
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);
if (type_sp) {
- TypeList *type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
+ GetTypeList().Insert(type_sp);
if (die.Tag() == DW_TAG_subprogram) {
std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
@@ -2995,12 +3002,21 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
bool parse_siblings, bool parse_children) {
size_t types_added = 0;
DWARFDIE die = orig_die;
+
while (die) {
+ const dw_tag_t tag = die.Tag();
bool type_is_new = false;
- if (ParseType(sc, die, &type_is_new).get()) {
- if (type_is_new)
- ++types_added;
- }
+
+ Tag dwarf_tag = static_cast<Tag>(tag);
+
+ // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
+ // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
+ // not.
+ if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
+ ParseType(sc, die, &type_is_new);
+
+ if (type_is_new)
+ ++types_added;
if (parse_children && die.HasChildren()) {
if (die.Tag() == DW_TAG_subprogram) {
@@ -3020,7 +3036,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
}
size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
lldbassert(comp_unit);
@@ -3040,7 +3056,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t types_added = 0;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
@@ -3056,7 +3072,7 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (sc.comp_unit != nullptr) {
DWARFDebugInfo *info = DebugInfo();
if (info == nullptr)
@@ -3193,15 +3209,18 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, debug_info_data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU());
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Retrieve the value as a data expression.
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, data_offset, *data_length),
+ die.GetCU());
else {
const uint8_t *data_pointer = form_value.BlockData();
if (data_pointer) {
@@ -3217,17 +3236,21 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (form_value.Form() == DW_FORM_strp) {
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ data_offset,
+ *data_length),
+ die.GetCU());
} else {
const char *str = form_value.AsCString();
uint32_t string_offset =
str - (const char *)debug_info_data.GetDataStart();
uint32_t string_length = strlen(str) + 1;
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- string_offset, string_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ string_offset,
+ string_length),
+ die.GetCU());
}
}
}
@@ -3241,17 +3264,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length),
+ die.GetCU());
} else {
- const DWARFDataExtractor &debug_loc_data = DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- die.GetCU(), debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- location = DWARFExpression(module, debug_loc_data, die.GetCU(),
- debug_loc_offset, loc_list_length);
+ DataExtractor data = DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ location = DWARFExpression(module, data, die.GetCU());
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide(
func_low_pc -
@@ -3522,6 +3543,8 @@ SymbolFileDWARF::FindBlockContainingSpecification(
spec_block_die_offset)
return die;
} break;
+ default:
+ break;
}
// Give the concrete function die specified by "func_die_offset", find the
@@ -3577,8 +3600,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
} else {
GetObjectFile()->GetModule()->ReportError(
"parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
- "symbol context for 0x%8.8" PRIx64
- " %s.\n",
+ "symbol context for 0x%8.8" PRIx64 " %s.\n",
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
orig_die.GetID(), orig_die.GetTagAsCString());
}
@@ -3654,9 +3676,57 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
return vars_added;
}
+/// Collect call site parameters in a DW_TAG_call_site DIE.
+static CallSiteParameterArray
+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)
+ continue;
+
+ llvm::Optional<DWARFExpression> LocationInCallee = {};
+ llvm::Optional<DWARFExpression> LocationInCaller = {};
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = child.GetAttributes(attributes);
+
+ // Parse the location at index \p attr_index within this call site parameter
+ // DIE, or return None on failure.
+ auto parse_simple_location =
+ [&](int attr_index) -> llvm::Optional<DWARFExpression> {
+ DWARFFormValue form_value;
+ if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
+ return {};
+ if (!DWARFFormValue::IsBlockForm(form_value.Form()))
+ return {};
+ auto data = child.GetData();
+ uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ return DWARFExpression(module,
+ DataExtractor(data, block_offset, block_length),
+ child.GetCU());
+ };
+
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attr == DW_AT_location)
+ LocationInCallee = parse_simple_location(i);
+ if (attr == DW_AT_call_value)
+ LocationInCaller = parse_simple_location(i);
+ }
+
+ if (LocationInCallee && LocationInCaller) {
+ CallSiteParameter param = {*LocationInCallee, *LocationInCaller};
+ parameters.push_back(param);
+ }
+ }
+ return parameters;
+}
+
/// Collect call graph edges present in a function DIE.
static std::vector<lldb_private::CallEdge>
-CollectCallEdges(DWARFDIE function_die) {
+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 =
@@ -3693,9 +3763,28 @@ CollectCallEdges(DWARFDIE function_die) {
addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc,
LLDB_INVALID_ADDRESS);
+ // Extract call site parameters.
+ CallSiteParameterArray parameters =
+ CollectCallSiteParameters(module, child);
+
LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
call_origin.GetPubname(), return_pc);
- call_edges.emplace_back(call_origin.GetMangledName(), return_pc);
+ if (log && parameters.size()) {
+ for (const CallSiteParameter &param : parameters) {
+ StreamString callee_loc_desc, caller_loc_desc;
+ param.LocationInCallee.GetDescription(&callee_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ param.LocationInCaller.GetDescription(&caller_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",
+ callee_loc_desc.GetString(), caller_loc_desc.GetString());
+ }
+ }
+
+ call_edges.emplace_back(call_origin.GetMangledName(), return_pc,
+ std::move(parameters));
}
return call_edges;
}
@@ -3704,7 +3793,7 @@ std::vector<lldb_private::CallEdge>
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
DWARFDIE func_die = GetDIE(func_id.GetID());
if (func_die.IsValid())
- return CollectCallEdges(func_die);
+ return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
return {};
}
@@ -3713,11 +3802,17 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
-void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); }
+void SymbolFileDWARF::Dump(lldb_private::Stream &s) {
+ SymbolFile::Dump(s);
+ m_index->Dump(s);
+}
void SymbolFileDWARF::DumpClangAST(Stream &s) {
- TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
- ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts);
+ 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());
if (!clang)
return;
clang->Dump(s);
@@ -3727,10 +3822,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- m_debug_map_symfile =
- (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
+ m_debug_map_symfile =
+ (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile();
}
}
return m_debug_map_symfile;
@@ -3746,9 +3839,9 @@ SymbolFileDWARF::GetLocationListFormat() const {
SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
ModuleSpec module_spec;
- module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
+ module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
module_spec.GetSymbolFileSpec() =
- FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp");
+ FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp");
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dwp_filespec =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 018af47305f4..04cb11d426be 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -46,7 +46,8 @@ class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
-class DWARFDebugRangesBase;
+class DWARFDebugRanges;
+class DWARFDebugRngLists;
class DWARFDeclContext;
class DWARFFormValue;
class DWARFTypeUnit;
@@ -78,13 +79,13 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
static lldb_private::FileSpecList GetSymlinkPaths();
// Constructors and Destructors
- SymbolFileDWARF(lldb_private::ObjectFile *ofile,
+ SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,
lldb_private::SectionList *dwo_section_list);
~SymbolFileDWARF() override;
@@ -95,10 +96,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -108,6 +105,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -156,47 +157,46 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- 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;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
- lldb_private::TypeList *GetTypeList() override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
-
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -223,8 +223,8 @@ public:
const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugRangesBase *GetDebugRanges();
- DWARFDebugRangesBase *GetDebugRngLists();
+ DWARFDebugRanges *GetDebugRanges();
+ DWARFDebugRngLists *GetDebugRngLists();
const lldb_private::DWARFDataExtractor &DebugLocData();
@@ -331,6 +331,12 @@ protected:
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb_private::TypeList &GetTypeList() override;
+
virtual DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
@@ -477,8 +483,8 @@ protected:
typedef std::set<lldb::user_id_t> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
- std::unique_ptr<DWARFDebugRangesBase> m_ranges;
- std::unique_ptr<DWARFDebugRangesBase> m_rnglists;
+ std::unique_ptr<DWARFDebugRanges> m_ranges;
+ std::unique_ptr<DWARFDebugRngLists> m_rnglists;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 8ec64dbaf764..a50d4e460bae 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -41,7 +41,7 @@ using namespace lldb_private;
// Subclass lldb_private::Module so we can intercept the
// "Module::GetObjectFile()" (so we can fixup the object file sections) and
-// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
+// also for "Module::GetSymbolFile()" (so we can fixup the symbol file id.
const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
@@ -60,11 +60,11 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
return file_range_map;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf(
- "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
- static_cast<void *>(this),
- oso_module->GetSpecificationDescription().c_str());
+ LLDB_LOGF(
+ log,
+ "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ static_cast<void *>(this),
+ oso_module->GetSpecificationDescription().c_str());
std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
@@ -173,12 +173,12 @@ public:
~DebugMapModule() override = default;
- SymbolVendor *
- GetSymbolVendor(bool can_create = true,
- lldb_private::Stream *feedback_strm = nullptr) override {
+ SymbolFile *
+ GetSymbolFile(bool can_create = true,
+ lldb_private::Stream *feedback_strm = nullptr) override {
// Scope for locker
if (m_symfile_up.get() || !can_create)
- return m_symfile_up.get();
+ return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
ModuleSP exe_module_sp(m_exe_module_wp.lock());
if (exe_module_sp) {
@@ -186,30 +186,28 @@ public:
ObjectFile *oso_objfile = GetObjectFile();
if (oso_objfile) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor *symbol_vendor =
- Module::GetSymbolVendor(can_create, feedback_strm);
- if (symbol_vendor) {
+ if (SymbolFile *symfile =
+ Module::GetSymbolFile(can_create, feedback_strm)) {
// Set a pointer to this class to set our OSO DWARF file know that
// the DWARF is being used along with a debug map and that it will
// have the remapped sections that we do below.
SymbolFileDWARF *oso_symfile =
- SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
- symbol_vendor->GetSymbolFile());
+ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile);
if (!oso_symfile)
return nullptr;
ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+ SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile();
- if (exe_objfile && exe_sym_vendor) {
+ if (exe_objfile && exe_symfile) {
oso_symfile->SetDebugMapModule(exe_module_sp);
// Set the ID of the symbol file DWARF to the index of the OSO
// shifted left by 32 bits to provide a unique prefix for any
// UserID's that get created in the symbol file.
oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
}
- return symbol_vendor;
+ return symfile;
}
}
}
@@ -239,13 +237,13 @@ const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader (debug map).";
}
-SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARFDebugMap(obj_file);
+SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARFDebugMap(std::move(objfile_sp));
}
-SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
- : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
- m_glob_indexes(),
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
+ m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
@@ -260,12 +258,12 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// If the object file has been stripped, there is no sense in looking further
// as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
+ if (m_objfile_sp->IsStripped())
return;
// Also make sure the file type is some sort of executable. Core files, debug
// info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType()) {
+ switch (m_objfile_sp->GetType()) {
case ObjectFile::eTypeInvalid:
case ObjectFile::eTypeCoreFile:
case ObjectFile::eTypeDebugInfo:
@@ -286,7 +284,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// these files exist and also contain valid DWARF. If we get any of that then
// we return the abilities of the first N_OSO's DWARF.
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
@@ -352,7 +350,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// The sibling index can't be less that or equal to the current index
// "i"
if (sibling_idx == UINT32_MAX) {
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO in symbol with UID %u has invalid sibling in debug map, "
"please file a bug and attach the binary listed in this error",
so_symbol->GetID());
@@ -363,28 +361,27 @@ void SymbolFileDWARFDebugMap::InitOSO() {
m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
- oso_symbol->GetName().GetCString());
+ LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i,
+ oso_symbol->GetName().GetCString());
}
} else {
if (oso_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO symbol[%u] can't be found, please file a bug and attach "
"the binary listed in this error",
oso_idx);
else if (so_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO not found for N_OSO symbol[%u], please file a bug and "
"attach the binary listed in this error",
oso_idx);
else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
so_symbol->GetType(), oso_idx);
else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
oso_symbol->GetType(), oso_idx);
@@ -421,7 +418,11 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// than the one from the CU.
auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
FileSystem::Instance().GetModificationTime(oso_file));
- if (oso_mod_time != comp_unit_info->oso_mod_time) {
+ // A timestamp of 0 means that the linker was in deterministic mode. In
+ // that case, we should skip the check against the filesystem last
+ // modification timestamp, since it will never match.
+ if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
+ oso_mod_time != comp_unit_info->oso_mod_time) {
obj_file->GetModule()->ReportError(
"debug map object file '%s' has changed (actual time is "
"%s, debug map time is %s"
@@ -448,7 +449,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// since .o files for "i386-apple-ios" will historically show up as "i386
// -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
// LC_VERSION_MIN_IPHONEOS load command...
- oso_arch.SetTriple(m_obj_file->GetModule()
+ oso_arch.SetTriple(m_objfile_sp->GetModule()
->GetArchitecture()
.GetTriple()
.getArchName()
@@ -534,12 +535,8 @@ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
CompileUnitInfo *comp_unit_info) {
- Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
- if (oso_module) {
- SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
- if (sym_vendor)
- return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
- }
+ if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info))
+ return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile());
return nullptr;
}
@@ -562,7 +559,7 @@ uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
return 0;
}
-uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
+uint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() {
InitOSO();
return m_compile_unit_infos.size();
}
@@ -581,13 +578,12 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
lldb::user_id_t cu_id = 0;
m_compile_unit_infos[cu_idx].compile_unit_sp =
std::make_shared<CompileUnit>(
- m_obj_file->GetModule(), nullptr, so_file_spec, cu_id,
+ m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id,
eLanguageTypeUnknown, eLazyBoolCalculate);
if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
- // Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
+ SetCompileUnitAtIndex(cu_idx,
+ m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
@@ -625,6 +621,7 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
lldb::LanguageType
SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLanguage(comp_unit);
@@ -632,6 +629,7 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseFunctions(comp_unit);
@@ -639,6 +637,7 @@ size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLineTable(comp_unit);
@@ -646,14 +645,24 @@ bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseDebugMacros(comp_unit);
return false;
}
+void SymbolFileDWARFDebugMap::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
+ if (oso_dwarf)
+ oso_dwarf->ForEachExternalModule(comp_unit, f);
+}
+
bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
@@ -661,6 +670,7 @@ bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
}
bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseIsOptimized(comp_unit);
@@ -669,6 +679,7 @@ bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARFDebugMap::ParseImportedModules(
const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseImportedModules(sc, imported_modules);
@@ -676,6 +687,7 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules(
}
size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
if (!comp_unit)
return 0;
@@ -687,6 +699,7 @@ size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseTypes(comp_unit);
@@ -695,6 +708,7 @@ size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseVariablesForContext(sc);
@@ -702,6 +716,7 @@ SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
}
Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf)
@@ -738,8 +753,9 @@ uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
@@ -766,7 +782,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
Address oso_so_addr;
if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
resolved_flags |=
- oso_module->GetSymbolVendor()->ResolveSymbolContext(
+ oso_module->GetSymbolFile()->ResolveSymbolContext(
oso_so_addr, resolve_scope, sc);
}
}
@@ -780,6 +796,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
@@ -807,12 +824,11 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
return sc_list.GetSize() - initial;
}
-uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
+void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
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) {
- const uint32_t original_size = variables.GetSize();
const size_t match_count = indexes.size();
for (size_t i = 0; i < match_count; ++i) {
uint32_t oso_idx;
@@ -821,28 +837,26 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
if (comp_unit_info) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf) {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
- variables))
- if (variables.GetSize() > max_matches)
- break;
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ if (variables.GetSize() > max_matches)
+ break;
}
}
}
- return variables.GetSize() - original_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
-
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
- name, parent_decl_ctx, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -861,22 +875,18 @@ uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
+ const RegularExpression &regex, uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches =
- oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -895,9 +905,6 @@ SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
@@ -993,71 +1000,58 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
}
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(
+void SymbolFileDWARFDebugMap::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
name.GetCString());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
- bool include_inlines,
- bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- TypeList &type_list) {
+void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
type_mask);
- uint32_t initial_size = type_list.GetSize();
SymbolFileDWARF *oso_dwarf = nullptr;
if (sc_scope) {
SymbolContext sc;
@@ -1075,7 +1069,6 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
return false;
});
}
- return type_list.GetSize() - initial_size;
}
std::vector<lldb_private::CallEdge>
@@ -1124,7 +1117,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
// N_SO.
SymbolFileDWARF *oso_dwarf = nullptr;
TypeSP type_sp;
- ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+ ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile();
if (module_objfile) {
Symtab *symtab = module_objfile->GetSymtab();
if (symtab) {
@@ -1177,23 +1170,17 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
return TypeSP();
}
-uint32_t SymbolFileDWARFDebugMap::FindTypes(
+void SymbolFileDWARFDebugMap::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- if (!append)
- types.Clear();
-
- const uint32_t initial_types_size = types.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
+ oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
return types.GetSize() >= max_matches;
});
-
- return types.GetSize() - initial_types_size;
}
//
@@ -1212,6 +1199,7 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes(
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
lldb_private::ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompilerDeclContext matching_namespace;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1284,8 +1272,7 @@ void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
cu_sp.get());
} else {
m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, cu_sp);
+ SetCompileUnitAtIndex(cu_idx, cu_sp);
}
}
}
@@ -1388,8 +1375,8 @@ bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
if (addr_module == exe_module)
return true; // Address is already in terms of the main executable module
- CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
- addr_module->GetSymbolVendor()->GetSymbolFile()));
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(
+ GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile()));
if (cu_info) {
const lldb::addr_t oso_file_addr = addr.GetFileAddress();
const FileRangeMap::Entry *oso_range_entry =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index afc6142e8231..7adee1b356ce 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -34,19 +34,16 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
+ SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
~SymbolFileDWARFDebugMap() override;
uint32_t CalculateAbilities() override;
void InitializeObject() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -56,6 +53,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -91,34 +92,34 @@ public:
bool check_inlines,
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ 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,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
lldb_private::CompilerDeclContext FindNamespace(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
std::vector<lldb_private::CallEdge>
ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
@@ -174,6 +175,9 @@ protected:
// Protected Member Functions
void InitOSO();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
return (uint32_t)((uid >> 32ull) - 1ull);
}
@@ -232,7 +236,7 @@ protected:
static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
const CompileUnitInfo *comp_unit_info);
- uint32_t PrivateFindGlobalVariables(
+ void PrivateFindGlobalVariables(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c5b54b65ea29..b0f7e813d4f8 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -23,21 +23,21 @@ using namespace lldb_private;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
DWARFCompileUnit &dwarf_cu)
- : SymbolFileDWARF(objfile.get(), objfile->GetSectionList(
- /*update_module_section_list*/ false)),
- m_obj_file_sp(objfile), m_base_dwarf_cu(dwarf_cu) {
+ : 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_obj_file->GetSectionList(false /* update_module_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) {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
return;
data.Clear();
@@ -140,7 +140,7 @@ SymbolFileDWARFDwo::GetLocationListFormat() const {
return DWARFExpression::SplitDwarfLocationList;
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 9b2f3bb84c4f..ad290cdcf65e 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -30,7 +30,7 @@ public:
size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
DWARFDIE
@@ -71,7 +71,6 @@ protected:
DWARFCompileUnit *ComputeCompileUnit();
- lldb::ObjectFileSP m_obj_file_sp;
DWARFCompileUnit &m_base_dwarf_cu;
DWARFCompileUnit *m_cu = nullptr;
};
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
new file mode 100644
index 000000000000..ef6ae3498588
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
@@ -0,0 +1,12 @@
+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,
+ Desc<"Ignore indexes present in the object files and always index DWARF manually.">;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 8da7e2226266..4862fea8d079 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -55,6 +55,8 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
case DW_TAG_partial_unit:
done = true;
break;
+ default:
+ break;
}
}
parent_arg_die = parent_arg_die.GetParent();
diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 1838204e4ca6..830d78f81679 100644
--- a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -130,7 +130,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
if (!stream_data) {
llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, nullptr);
- cci = llvm::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
+ cci = std::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
return *cci;
}
@@ -139,7 +139,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
cantFail(debug_stream.reload());
- cci = llvm::make_unique<CompilandIndexItem>(
+ cci = std::make_unique<CompilandIndexItem>(
PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
ParseExtendedInfo(m_index, *cci);
diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3d8bfb058721..6aaff06cc134 100644
--- a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
@@ -247,6 +247,6 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
.take_front(size);
buffer->CopyData(bytes.data(), size);
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
- DWARFExpression result(nullptr, extractor, nullptr, 0, size);
+ DWARFExpression result(nullptr, extractor, nullptr);
return result;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 4991be8e70ce..986b0b785d87 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -121,13 +121,6 @@ AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
return false;
}
-static ClangASTContext &GetClangASTContext(ObjectFile &obj) {
- TypeSystem *ts =
- obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- lldbassert(ts);
- return static_cast<ClangASTContext &>(*ts);
-}
-
static llvm::Optional<clang::CallingConv>
TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
using CC = llvm::codeview::CallingConvention;
@@ -209,8 +202,8 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) {
return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
- : m_index(index), m_clang(GetClangASTContext(obj)) {
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang)
+ : m_index(index), m_clang(clang) {
BuildParentMap();
}
@@ -465,9 +458,9 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
}
}
-clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
+llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
if (clang::Decl *result = TryGetDecl(uid))
- return result;
+ return ToCompilerDecl(*result);
clang::Decl *result = nullptr;
switch (uid.kind()) {
@@ -480,13 +473,13 @@ clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
result = tag;
break;
}
- return nullptr;
+ return llvm::None;
}
default:
- return nullptr;
+ return llvm::None;
}
m_uid_to_decl[toOpaqueUid(uid)] = result;
- return result;
+ return ToCompilerDecl(*result);
}
clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
@@ -494,8 +487,10 @@ clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
if (uid.asCompilandSym().offset == 0)
return FromCompilerDeclContext(GetTranslationUnitDecl());
}
-
- clang::Decl *decl = GetOrCreateDeclForUid(uid);
+ auto option = GetOrCreateDeclForUid(uid);
+ if (!option)
+ return nullptr;
+ clang::Decl *decl = FromCompilerDecl(option.getValue());
if (!decl)
return nullptr;
@@ -1089,7 +1084,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr());
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
&function_decl, param_name.str().c_str(), param_type_ct,
- clang::SC_None);
+ clang::SC_None, true);
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 67d024741e0d..a4242e90810d 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -51,11 +51,12 @@ struct DeclStatus {
class PdbAstBuilder {
public:
// Constructors and Destructors
- PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
+ PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
lldb_private::CompilerDeclContext GetTranslationUnitDecl();
- clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
+ llvm::Optional<lldb_private::CompilerDecl>
+ GetOrCreateDeclForUid(PdbSymUid uid);
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
@@ -76,7 +77,7 @@ public:
CompilerDecl ToCompilerDecl(clang::Decl &decl);
CompilerType ToCompilerType(clang::QualType qt);
CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
- clang::Decl * FromCompilerDecl(CompilerDecl decl);
+ clang::Decl *FromCompilerDecl(CompilerDecl decl);
clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
ClangASTContext &clang() { return m_clang; }
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index 79dd010ff311..a7bc23519710 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -51,54 +51,23 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::A
return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
}
-static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
- llvm::BumpPtrAllocator &alloc,
- llvm::StringRef &register_name,
- Node *&ast) {
- // lvalue of assignment is always first token
- // rvalue program goes next
- std::tie(register_name, program) = getToken(program);
- if (register_name.empty())
- return false;
-
- ast = Parse(program, alloc);
- return ast != nullptr;
-}
-
-static Node *ParseFPOProgram(llvm::StringRef program,
+static Node *ResolveFPOProgram(llvm::StringRef program,
llvm::StringRef register_name,
llvm::Triple::ArchType arch_type,
llvm::BumpPtrAllocator &alloc) {
- llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
-
- size_t cur = 0;
- while (true) {
- size_t assign_index = program.find('=', cur);
- if (assign_index == llvm::StringRef::npos) {
- llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
- if (!tail.trim().empty()) {
- // missing assign operator
- return nullptr;
- }
- break;
- }
- llvm::StringRef assignment_program = program.slice(cur, assign_index);
-
- llvm::StringRef lvalue_name;
- Node *rvalue_ast = nullptr;
- if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
- rvalue_ast)) {
- return nullptr;
- }
-
- lldbassert(rvalue_ast);
+ std::vector<std::pair<llvm::StringRef, Node *>> parsed =
+ postfix::ParseFPOProgram(program, alloc);
+ for (auto it = parsed.begin(), end = parsed.end(); it != end; ++it) {
// Emplace valid dependent subtrees to make target assignment independent
// from predecessors. Resolve all other SymbolNodes as registers.
bool success =
- ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
- if (Node *node = dependent_programs.lookup(symbol.GetName()))
- return node;
+ ResolveSymbols(it->second, [&](SymbolNode &symbol) -> Node * {
+ for (const auto &pair : llvm::make_range(parsed.begin(), it)) {
+ if (pair.first == symbol.GetName())
+ return pair.second;
+ }
+
uint32_t reg_num =
ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
@@ -110,13 +79,10 @@ static Node *ParseFPOProgram(llvm::StringRef program,
if (!success)
return nullptr;
- if (lvalue_name == register_name) {
+ if (it->first == register_name) {
// found target assignment program - no need to parse further
- return rvalue_ast;
+ return it->second;
}
-
- dependent_programs[lvalue_name] = rvalue_ast;
- cur = assign_index + 1;
}
return nullptr;
@@ -127,7 +93,7 @@ bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
llvm::Triple::ArchType arch_type, Stream &stream) {
llvm::BumpPtrAllocator node_alloc;
Node *target_program =
- ParseFPOProgram(program, register_name, arch_type, node_alloc);
+ ResolveFPOProgram(program, register_name, arch_type, node_alloc);
if (target_program == nullptr) {
return false;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 1f5c97da81cf..fc047e25a2f4 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -641,14 +641,14 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
llvm::StringRef program;
if (GetFrameDataProgram(index, ranges, program)) {
result.location =
- MakeVFrameRelLocationExpression(program, loc.Offset, module);
+ MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
} else {
// invalid variable
}
} else {
result.location =
- MakeRegRelLocationExpression(base_reg, loc.Offset, module);
+ MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
}
} else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index e27d4699ae2f..33b8da3b543b 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -20,7 +20,6 @@
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -30,6 +29,7 @@
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/Log.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
@@ -90,10 +90,10 @@ static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
llvm::StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>(
+ auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
std::move(Buffer), llvm::support::little);
- auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
if (auto EC = File->parseFileHeaders()) {
llvm::consumeError(std::move(EC));
return nullptr;
@@ -119,6 +119,8 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
}
OwningBinary<Binary> binary = std::move(*expected_binary);
+ // TODO: Avoid opening the PE/COFF binary twice by reading this information
+ // directly from the lldb_private::ObjectFile.
auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
if (!obj)
return nullptr;
@@ -264,27 +266,27 @@ const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
return "Microsoft PDB debug symbol cross-platform file reader.";
}
-SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileNativePDB(obj_file);
+SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileNativePDB(std::move(objfile_sp));
}
-SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file)
- : SymbolFile(object_file) {}
+SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
SymbolFileNativePDB::~SymbolFileNativePDB() {}
uint32_t SymbolFileNativePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_index) {
// Lazily load and match the PDB file, but only do this once.
std::unique_ptr<PDBFile> file_up =
- loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator);
+ loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), m_allocator);
if (!file_up) {
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -317,19 +319,24 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
}
void SymbolFileNativePDB::InitializeObject() {
- m_obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ m_obj_load_address = m_objfile_sp->GetBaseAddress().GetFileAddress();
m_index->SetLoadAddress(m_obj_load_address);
m_index->ParseSectionContribs();
- TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage(
+ auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
lldb::eLanguageTypeC_plus_plus);
- if (ts)
- ts->SetSymbolFile(this);
-
- m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index);
+ if (auto err = ts_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Failed to initialize");
+ } else {
+ ts_or_err->SetSymbolFile(this);
+ auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get());
+ lldbassert(clang);
+ m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
+ }
}
-uint32_t SymbolFileNativePDB::GetNumCompileUnits() {
+uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
const DbiModuleList &modules = m_index->dbi().modules();
uint32_t count = modules.getModuleCount();
if (count == 0)
@@ -430,11 +437,10 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
FileSpec fs(source_file_name);
CompUnitSP cu_sp =
- std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs,
+ std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
toOpaqueUid(cci.m_id), lang, optimized);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cci.m_id.modi, cu_sp);
+ SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
return cu_sp;
}
@@ -730,7 +736,7 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
TypeSP type = CreateAndCacheType(type_id);
if (type)
- m_obj_file->GetModule()->GetTypeList()->Insert(type);
+ GetTypeList().Insert(type);
return type;
}
@@ -900,6 +906,7 @@ lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid(comp_unit.GetID());
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
@@ -915,6 +922,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid{comp_unit.GetID()};
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
uint16_t modi = uid.asCompiland().modi;
@@ -948,6 +956,7 @@ static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
uint32_t SymbolFileNativePDB::ResolveSymbolContext(
const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
lldb::addr_t file_addr = addr.GetFileAddress();
@@ -1052,12 +1061,13 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
// all at once, even if all it really needs is line info for a specific
// function. In the future it would be nice if it could set the sc.m_function
// member, and we could only get the line info for the function in question.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
lldbassert(cci);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// This is basically a copy of the .debug$S subsections from all original COFF
// object files merged together with address relocations applied. We are
@@ -1130,6 +1140,7 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
@@ -1160,6 +1171,7 @@ bool SymbolFileNativePDB::ParseImportedModules(
}
size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
// FIXME: Parse child blocks
return 1;
@@ -1167,9 +1179,10 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
-uint32_t SymbolFileNativePDB::FindGlobalVariables(
+void SymbolFileNativePDB::FindGlobalVariables(
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>;
std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
@@ -1191,16 +1204,16 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables(
continue;
}
}
- return variables.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(
+void SymbolFileNativePDB::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// For now we only support lookup by method name.
if (!(name_type_mask & eFunctionNameTypeMethod))
- return 0;
+ return;
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
@@ -1225,45 +1238,34 @@ uint32_t SymbolFileNativePDB::FindFunctions(
sc_list.Append(sc);
}
-
- return sc_list.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- return 0;
-}
+void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {}
-uint32_t SymbolFileNativePDB::FindTypes(
+void SymbolFileNativePDB::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
// There is an assumption 'name' is not a regex
- size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types);
-
- return match_count;
+ FindTypesByName(name.GetStringRef(), max_matches, types);
}
-size_t
-SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- return 0;
-}
+void SymbolFileNativePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
-size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
- uint32_t max_matches,
- TypeMap &types) {
+void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
+ uint32_t max_matches,
+ TypeMap &types) {
- size_t match_count = 0;
std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
if (max_matches > 0 && max_matches < matches.size())
matches.resize(max_matches);
@@ -1274,17 +1276,16 @@ size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
continue;
types.Insert(type);
- ++match_count;
}
- return match_count;
}
size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Only do the full type scan the first time.
if (m_done_full_type_scan)
return 0;
- size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t old_count = GetTypeList().GetSize();
LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
// First process the entire TPI stream.
@@ -1314,7 +1315,7 @@ size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
GetOrCreateTypedef(global);
}
- size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t new_count = GetTypeList().GetSize();
m_done_full_type_scan = true;
@@ -1476,6 +1477,7 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
}
size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert(sc.function || sc.comp_unit);
VariableListSP variables;
@@ -1506,9 +1508,10 @@ size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
}
CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
- clang::Decl *decl = m_ast->GetOrCreateDeclForUid(PdbSymUid(uid));
-
- return m_ast->ToCompilerDecl(*decl);
+ if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
+ return decl.getValue();
+ else
+ return CompilerDecl();
}
CompilerDeclContext
@@ -1528,6 +1531,7 @@ SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
}
Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto iter = m_types.find(type_uid);
// lldb should not be passing us non-sensical type uids. the only way it
// could have a type uid in the first place is if we handed it out, in which
@@ -1561,11 +1565,9 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
return m_ast->CompleteType(qt);
}
-size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
CompilerDeclContext
SymbolFileNativePDB::FindNamespace(ConstString name,
@@ -1573,13 +1575,14 @@ SymbolFileNativePDB::FindNamespace(ConstString name,
return {};
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
ConstString SymbolFileNativePDB::GetPluginName() {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 20daff219a0a..ca7de0e7d1ed 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -9,7 +9,6 @@
#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/SymbolFile.h"
#include "llvm/ADT/DenseMap.h"
@@ -35,7 +34,6 @@ struct UnionRecord;
} // namespace llvm
namespace lldb_private {
-class ClangASTImporter;
namespace npdb {
class PdbAstBuilder;
@@ -55,10 +53,10 @@ public:
static const char *GetPluginDescriptionStatic();
- static SymbolFile *CreateInstance(ObjectFile *obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileNativePDB(ObjectFile *ofile);
+ SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFileNativePDB() override;
@@ -68,13 +66,9 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
void
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -94,10 +88,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override;
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override;
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override;
size_t ParseVariablesForContext(const SymbolContext &sc) override;
@@ -120,28 +114,27 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override;
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
CompilerDeclContext
FindNamespace(ConstString name,
@@ -157,9 +150,12 @@ public:
void DumpClangAST(Stream &s) override;
private:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches,
- TypeMap &types);
+ void FindTypesByName(llvm::StringRef name, uint32_t max_matches,
+ TypeMap &types);
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id,
const llvm::codeview::ModifierRecord &mr,
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 82cfcfbb040f..47c4ad088494 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -120,24 +120,31 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
return clang_ast.GetBasicType(eBasicTypeBool);
case PDB_BuiltinType::Long:
if (width == ast->getTypeSize(ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::ULong:
if (width == ast->getTypeSize(ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::WCharT:
if (width == ast->getTypeSize(ast->WCharTy))
- return CompilerType(ast, ast->WCharTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->WCharTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::Char16:
- return CompilerType(ast, ast->Char16Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char16Ty.getAsOpaquePtr());
case PDB_BuiltinType::Char32:
- return CompilerType(ast, ast->Char32Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char32Ty.getAsOpaquePtr());
case PDB_BuiltinType::Float:
// Note: types `long double` and `double` have same bit size in MSVC and
// there is no information in the PDB to distinguish them. So when falling
@@ -940,7 +947,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
decl, nullptr, arg_type->GetForwardCompilerType(),
- clang::SC_None);
+ clang::SC_None, true);
if (param)
params.push_back(param);
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 1c17bf6563b3..42bf1b34c956 100644
--- a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -174,7 +174,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 17dfcdaceb9c..854e735b5f83 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -24,6 +24,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
@@ -118,29 +119,28 @@ const char *SymbolFilePDB::GetPluginDescriptionStatic() {
}
lldb_private::SymbolFile *
-SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
- return new SymbolFilePDB(obj_file);
+SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFilePDB(std::move(objfile_sp));
}
-SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
- m_cached_compile_unit_count(0) {}
+SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
SymbolFilePDB::~SymbolFilePDB() {}
uint32_t SymbolFilePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_session_up) {
// Lazily load and match the PDB file, but only do this once.
- std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ std::string exePath = m_objfile_sp->GetFileSpec().GetPath();
auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
m_session_up);
if (error) {
llvm::consumeError(std::move(error));
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -183,7 +183,8 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
}
void SymbolFilePDB::InitializeObject() {
- lldb::addr_t obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ lldb::addr_t obj_load_address =
+ m_objfile_sp->GetBaseAddress().GetFileAddress();
lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
m_session_up->setLoadAddress(obj_load_address);
if (!m_global_scope_up)
@@ -191,33 +192,30 @@ void SymbolFilePDB::InitializeObject() {
lldbassert(m_global_scope_up.get());
}
-uint32_t SymbolFilePDB::GetNumCompileUnits() {
- if (m_cached_compile_unit_count == 0) {
- auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
- if (!compilands)
- return 0;
+uint32_t SymbolFilePDB::CalculateNumCompileUnits() {
+ auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!compilands)
+ return 0;
- // The linker could link *.dll (compiland language = LINK), or import
- // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
- // found as a child of the global scope (PDB executable). Usually, such
- // compilands contain `thunk` symbols in which we are not interested for
- // now. However we still count them in the compiland list. If we perform
- // any compiland related activity, like finding symbols through
- // llvm::pdb::IPDBSession methods, such compilands will all be searched
- // automatically no matter whether we include them or not.
- m_cached_compile_unit_count = compilands->getChildCount();
-
- // The linker can inject an additional "dummy" compilation unit into the
- // PDB. Ignore this special compile unit for our purposes, if it is there.
- // It is always the last one.
- auto last_compiland_up =
- compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- lldbassert(last_compiland_up.get());
- std::string name = last_compiland_up->getName();
- if (name == "* Linker *")
- --m_cached_compile_unit_count;
- }
- return m_cached_compile_unit_count;
+ // The linker could link *.dll (compiland language = LINK), or import
+ // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
+ // found as a child of the global scope (PDB executable). Usually, such
+ // compilands contain `thunk` symbols in which we are not interested for
+ // now. However we still count them in the compiland list. If we perform
+ // any compiland related activity, like finding symbols through
+ // llvm::pdb::IPDBSession methods, such compilands will all be searched
+ // automatically no matter whether we include them or not.
+ uint32_t compile_unit_count = compilands->getChildCount();
+
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB. Ignore this special compile unit for our purposes, if it is there.
+ // It is always the last one.
+ auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1);
+ lldbassert(last_compiland_up.get());
+ std::string name = last_compiland_up->getName();
+ if (name == "* Linker *")
+ --compile_unit_count;
+ return compile_unit_count;
}
void SymbolFilePDB::GetCompileUnitIndex(
@@ -261,6 +259,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return lldb::eLanguageTypeUnknown;
@@ -302,11 +301,15 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
comp_unit.AddFunction(func_sp);
LanguageType lang = ParseLanguage(comp_unit);
- TypeSystem *type_system = GetTypeSystemForLanguage(lang);
- if (!type_system)
+ auto type_system_or_err = GetTypeSystemForLanguage(lang);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse PDBFunc");
return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
@@ -315,6 +318,7 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
}
size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t func_added = 0;
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
@@ -333,6 +337,7 @@ size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable())
return true;
return ParseCompileUnitLineTable(comp_unit, 0);
@@ -351,6 +356,7 @@ bool SymbolFilePDB::ParseSupportFiles(
// second time seems like a waste. Unfortunately, there's no good way around
// this short of a moderate refactor since SymbolVendor depends on being able
// to cache this list.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return false;
@@ -428,6 +434,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
}
size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto uid = func.GetID();
auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
@@ -440,6 +447,7 @@ size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
@@ -492,6 +500,7 @@ size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!sc.comp_unit)
return 0;
@@ -540,14 +549,21 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
}
lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto find_result = m_types.find(type_uid);
if (find_result != m_types.end())
return find_result->second.get();
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to ResolveTypeUID");
+ return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
PDBASTParser *pdb = clang_type_system->GetPDBParser();
@@ -561,9 +577,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
if (result) {
m_types.insert(std::make_pair(type_uid, result));
- auto type_list = GetTypeList();
- if (type_list)
- type_list->Insert(result);
+ GetTypeList().Insert(result);
}
return result.get();
}
@@ -577,8 +591,17 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
std::lock_guard<std::recursive_mutex> guard(
GetObjectFile()->GetModule()->GetMutex());
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get dynamic array info for UID");
+ return false;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+
if (!clang_ast_ctx)
return false;
@@ -590,8 +613,16 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
}
lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get decl for UID");
+ return CompilerDecl();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDecl();
@@ -612,8 +643,16 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext for UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -634,8 +673,16 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext containing UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -655,8 +702,16 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
void SymbolFilePDB::ParseDeclsForContext(
lldb_private::CompilerDeclContext decl_ctx) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse decls for context");
+ return;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return;
@@ -672,6 +727,7 @@ uint32_t
SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextCompUnit ||
resolve_scope & eSymbolContextVariable ||
@@ -680,7 +736,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
resolve_scope & eSymbolContextLineEntry) {
auto cu_sp = GetCompileUnitContainsAddress(so_addr);
if (!cu_sp) {
- if (resolved_flags | eSymbolContextVariable) {
+ if (resolved_flags & eSymbolContextVariable) {
// TODO: Resolve variables
}
return 0;
@@ -732,6 +788,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
uint32_t SymbolFilePDB::ResolveSymbolContext(
const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const size_t old_size = sc_list.GetSize();
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
@@ -1040,18 +1097,19 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
return num_added;
}
-uint32_t SymbolFilePDB::FindGlobalVariables(
+void SymbolFilePDB::FindGlobalVariables(
lldb_private::ConstString name,
const lldb_private::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))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1061,7 +1119,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
break;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
if (!name.GetStringRef().equals(
@@ -1080,19 +1138,17 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) {
+void SymbolFilePDB::FindGlobalVariables(
+ const lldb_private::RegularExpression &regex, uint32_t max_matches,
+ lldb_private::VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1106,7 +1162,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
if (!regex.Execute(var_name))
continue;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
@@ -1117,8 +1173,6 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
@@ -1240,23 +1294,21 @@ void SymbolFilePDB::CacheFunctionNames() {
m_func_base_names.SizeToFit();
}
-uint32_t SymbolFilePDB::FindFunctions(
+void SymbolFilePDB::FindFunctions(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
if (name_type_mask == eFunctionNameTypeNone)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
if (name_type_mask & eFunctionNameTypeFull ||
name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod) {
@@ -1286,26 +1338,20 @@ uint32_t SymbolFilePDB::FindFunctions(
ResolveFn(m_func_base_names);
ResolveFn(m_func_method_names);
}
- if (name_type_mask & eFunctionNameTypeBase) {
+ if (name_type_mask & eFunctionNameTypeBase)
ResolveFn(m_func_base_names);
- }
- if (name_type_mask & eFunctionNameTypeMethod) {
+ if (name_type_mask & eFunctionNameTypeMethod)
ResolveFn(m_func_method_names);
- }
}
- return sc_list.GetSize() - old_size;
}
-uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
CacheFunctionNames();
std::set<uint32_t> resolved_ids;
@@ -1322,8 +1368,6 @@ SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
};
ResolveFn(m_func_full_names);
ResolveFn(m_func_base_names);
-
- return sc_list.GetSize() - old_size;
}
void SymbolFilePDB::GetMangledNamesForFunction(
@@ -1339,7 +1383,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
if (!results)
return;
- auto section_list = m_obj_file->GetSectionList();
+ auto section_list = m_objfile_sp->GetSectionList();
if (!section_list)
return;
@@ -1361,7 +1405,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.AddSymbol(
Symbol(pub_symbol->getSymIndexId(), // symID
pub_symbol->getName().c_str(), // name
- true, // name_is_mangled
pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
true, // external
false, // is_debug
@@ -1380,34 +1423,39 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.Finalize();
}
-uint32_t SymbolFilePDB::FindTypes(
+void SymbolFilePDB::FindTypes(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) {
- if (!append)
- types.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
// There is an assumption 'name' is not a regex
FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
-
- return types.GetSize();
}
void SymbolFilePDB::DumpClangAST(Stream &s) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang)
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to dump ClangAST");
+ return;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ if (!clang_type_system)
return;
- clang->Dump(s);
+ clang_type_system->Dump(s);
}
void SymbolFilePDB::FindTypesByRegex(
@@ -1514,15 +1562,9 @@ void SymbolFilePDB::FindTypesByName(
}
}
-size_t SymbolFilePDB::FindTypes(
- const std::vector<lldb_private::CompilerContext> &contexts, bool append,
- lldb_private::TypeMap &types) {
- return 0;
-}
-
-lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
- return m_obj_file->GetModule()->GetTypeList();
-}
+void SymbolFilePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages,
+ lldb_private::TypeMap &types) {}
void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
uint32_t type_mask,
@@ -1574,17 +1616,17 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
}
-size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
+void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeCollection type_collection;
- uint32_t old_size = type_list.GetSize();
CompileUnit *cu =
sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
if (cu) {
auto compiland_up = GetPDBCompilandByUID(cu->GetID());
if (!compiland_up)
- return 0;
+ return;
GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
} else {
for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
@@ -1600,21 +1642,29 @@ size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
type->GetForwardCompilerType();
type_list.Insert(type->shared_from_this());
}
- return type_list.GetSize() - old_size;
}
-lldb_private::TypeSystem *
+llvm::Expected<lldb_private::TypeSystem &>
SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get PDB AST parser");
+ return nullptr;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
@@ -1625,8 +1675,18 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to find namespace {}",
+ name.AsCString());
+ return CompilerDeclContext();
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return CompilerDeclContext();
@@ -1644,7 +1704,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
if (!namespace_decl)
return CompilerDeclContext();
- return CompilerDeclContext(type_system,
+ return CompilerDeclContext(clang_type_system,
static_cast<clang::DeclContext *>(namespace_decl));
}
@@ -1688,7 +1748,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
// Don't support optimized code for now, DebugInfoPDB does not return this
// information.
LazyBool optimized = eLazyBoolNo;
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
path.c_str(), id, lang, optimized);
if (!cu_sp)
@@ -1698,8 +1758,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
if (index == UINT32_MAX)
GetCompileUnitIndex(*compiland_up, index);
lldbassert(index != UINT32_MAX);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
- cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -1715,7 +1774,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
// to do a mapping so that we can hand out indices.
llvm::DenseMap<uint32_t, uint32_t> index_map;
BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// Find contributions to `compiland` from all source and header files.
std::string path = comp_unit.GetPath();
@@ -1925,9 +1984,17 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
if (!decl_ctx_type_system)
return false;
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to determine if DeclContext matches this symbol file");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
return false;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index ba3099aaec4d..df717bbbbdb0 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -35,10 +35,10 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFilePDB(lldb_private::ObjectFile *ofile);
+ SymbolFilePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFilePDB() override;
@@ -48,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -103,25 +99,25 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- 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;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
@@ -129,26 +125,25 @@ public:
void AddSymbols(lldb_private::Symtab &symtab) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
- lldb_private::TypeList *GetTypeList() override;
-
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -173,6 +168,10 @@ private:
};
using SecContribsMap = std::map<uint32_t, std::vector<SecContribInfo>>;
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
uint32_t index = UINT32_MAX);
@@ -245,7 +244,6 @@ private:
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
std::unique_ptr<llvm::pdb::PDBSymbolExe> m_global_scope_up;
- uint32_t m_cached_compile_unit_count;
lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;
lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index a1b21e51b0fe..62da76581c3e 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -43,26 +43,24 @@ const char *SymbolFileSymtab::GetPluginDescriptionStatic() {
return "Reads debug symbols from an object file's symbol table.";
}
-SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileSymtab(obj_file);
+SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileSymtab(std::move(objfile_sp));
}
-size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
-SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file)
- : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(),
+SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(),
m_code_indexes(), m_objc_class_name_to_index() {}
SymbolFileSymtab::~SymbolFileSymtab() {}
uint32_t SymbolFileSymtab::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file) {
- const Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
// The snippet of code below will get the indexes the module symbol table
// entries that are code, data, or function related (debug info), sort
@@ -104,7 +102,7 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
return abilities;
}
-uint32_t SymbolFileSymtab::GetNumCompileUnits() {
+uint32_t SymbolFileSymtab::CalculateNumCompileUnits() {
// If we don't have any source file symbols we will just have one compile
// unit for the entire object file
if (m_source_indexes.empty())
@@ -122,10 +120,10 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
// unit for the entire object file
if (idx < m_source_indexes.size()) {
const Symbol *cu_symbol =
- m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
- cu_symbol->GetName().AsCString(), 0,
+ cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
+ cu_symbol->GetName().AsCString(), 0,
eLanguageTypeUnknown, eLazyBoolNo);
}
return cu_sp;
@@ -136,12 +134,13 @@ lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
// We must at least have a valid compile unit
- const Symtab *symtab = m_obj_file->GetSymtab();
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
const Symbol *curr_symbol = nullptr;
const Symbol *next_symbol = nullptr;
- // const char *prefix = m_obj_file->SymbolPrefix();
+ // const char *prefix = m_objfile_sp->SymbolPrefix();
// if (prefix == NULL)
// prefix == "";
//
@@ -246,12 +245,13 @@ bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
- if (m_obj_file->GetSymtab() == nullptr)
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (m_objfile_sp->GetSymtab() == nullptr)
return 0;
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextSymbol) {
- sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(
+ sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
so_addr.GetFileAddress());
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index bc9a531419ae..2ac4660f0125 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -18,7 +18,7 @@
class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
// Constructors and Destructors
- SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
+ SymbolFileSymtab(lldb::ObjectFileSP objfile_sp);
~SymbolFileSymtab() override;
@@ -32,15 +32,11 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
uint32_t CalculateAbilities() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -75,9 +71,9 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -85,6 +81,10 @@ public:
uint32_t GetPluginVersion() override;
protected:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
lldb_private::Symtab::IndexCollection m_source_indexes;
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index f279af61a131..e61e5763fabb 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -10,6 +10,7 @@
#include <string.h>
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -61,99 +62,86 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!module_sp)
return nullptr;
- ObjectFile *obj_file = module_sp->GetObjectFile();
+ ObjectFileELF *obj_file =
+ llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile());
if (!obj_file)
return nullptr;
- static ConstString obj_file_elf("elf");
- ConstString obj_name = obj_file->GetPluginName();
- if (obj_name != obj_file_elf)
- return nullptr;
-
lldb_private::UUID uuid = obj_file->GetUUID();
if (!uuid)
return nullptr;
- // Get the .gnu_debuglink file (if specified).
- FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
-
- // If the module specified a filespec, use it first.
- FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
- if (debug_symbol_fspec)
- file_spec_list.Insert(0, debug_symbol_fspec);
-
- // If we have no debug symbol files, then nothing to do.
- if (file_spec_list.IsEmpty())
+ // If the main object file already contains debug info, then we are done.
+ if (obj_file->GetSectionList()->FindSectionByType(
+ lldb::eSectionTypeDWARFDebugInfo, true))
return nullptr;
+ // If the module specified a filespec, use that.
+ FileSpec fspec = module_sp->GetSymbolFileFileSpec();
+ // Otherwise, try gnu_debuglink, if one exists.
+ if (!fspec)
+ fspec = obj_file->GetDebugLink().getValueOr(FileSpec());
+
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
module_sp->GetFileSpec().GetPath().c_str());
- for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
- ModuleSpec module_spec;
- const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
-
- module_spec.GetFileSpec() = obj_file->GetFileSpec();
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- module_spec.GetSymbolFileSpec() = fspec;
- module_spec.GetUUID() = uuid;
- FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
- FileSpec dsym_fspec =
- Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
- if (dsym_fspec) {
- DataBufferSP dsym_file_data_sp;
- lldb::offset_t dsym_file_data_offset = 0;
- ObjectFileSP dsym_objfile_sp =
- ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
- FileSystem::Instance().GetByteSize(dsym_fspec),
- dsym_file_data_sp, dsym_file_data_offset);
- if (dsym_objfile_sp) {
- // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
- // be able to figure this out consistently as the symbol file may not
- // have stripped the code sections, etc.
- dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
-
- SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
- if (symbol_vendor) {
- // Get the module unified section list and add our debug sections to
- // that.
- SectionList *module_section_list = module_sp->GetSectionList();
- SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
-
- static const SectionType g_sections[] = {
- eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
- eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
- eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
- eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
- eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
- eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
- eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
- eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
- };
- for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
- ++idx) {
- SectionType section_type = g_sections[idx];
- SectionSP section_sp(
- objfile_section_list->FindSectionByType(section_type, true));
- if (section_sp) {
- SectionSP module_section_sp(
- module_section_list->FindSectionByType(section_type, true));
- if (module_section_sp)
- module_section_list->ReplaceSection(module_section_sp->GetID(),
- section_sp);
- else
- module_section_list->AddSection(section_sp);
- }
- }
-
- symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
- return symbol_vendor;
- }
- }
+ ModuleSpec module_spec;
+
+ module_spec.GetFileSpec() = obj_file->GetFileSpec();
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ module_spec.GetSymbolFileSpec() = fspec;
+ module_spec.GetUUID() = uuid;
+ FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+ FileSpec dsym_fspec =
+ Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+ if (!dsym_fspec)
+ return nullptr;
+
+ DataBufferSP dsym_file_data_sp;
+ lldb::offset_t dsym_file_data_offset = 0;
+ ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
+ module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
+ dsym_file_data_sp, dsym_file_data_offset);
+ if (!dsym_objfile_sp)
+ return nullptr;
+
+ // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
+ // be able to figure this out consistently as the symbol file may not
+ // have stripped the code sections, etc.
+ dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+ SymbolVendorELF *symbol_vendor = new SymbolVendorELF(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 = dsym_objfile_sp->GetSectionList();
+
+ static const SectionType g_sections[] = {
+ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
+ eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
+ eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
+ eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
+ eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
+ eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
+ eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
+ eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
+ };
+ 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);
}
}
- return nullptr;
+
+ symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ return symbol_vendor;
}
// PluginInterface protocol
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 43041ca1bb2f..bf6f60a2d26c 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -1328,6 +1328,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
unwind_plan.SetSourceName("assembly insn profiling");
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
return true;
}
@@ -1370,7 +1371,6 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
int row_id = 1;
bool unwind_plan_updated = false;
UnwindPlan::RowSP row(new UnwindPlan::Row(*first_row));
- m_cur_insn = data + offset;
// After a mid-function epilogue we will need to re-insert the original
// unwind rules so unwinds work for the remainder of the function. These
@@ -1380,19 +1380,17 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
while (offset < size) {
m_cur_insn = data + offset;
int insn_len;
- if (!instruction_length(m_cur_insn, insn_len, size - offset)
- || insn_len == 0
- || insn_len > kMaxInstructionByteSize) {
+ if (!instruction_length(m_cur_insn, insn_len, size - offset) ||
+ insn_len == 0 || insn_len > kMaxInstructionByteSize) {
// An unrecognized/junk instruction.
break;
}
// Advance offsets.
offset += insn_len;
- m_cur_insn = data + offset;
// offset is pointing beyond the bounds of the function; stop looping.
- if (offset >= size)
+ if (offset >= size)
continue;
if (reinstate_unwind_state) {
@@ -1546,16 +1544,18 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
// [0x5d] pop %rbp/%ebp
// => [0xc3] ret
if (pop_rbp_pattern_p() || leave_pattern_p()) {
- offset += 1;
- row->SetOffset(offset);
- row->GetCFAValue().SetIsRegisterPlusOffset(
- first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
-
- UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
- unwind_plan.InsertRow(new_row);
- unwind_plan_updated = true;
- reinstate_unwind_state = true;
- continue;
+ m_cur_insn++;
+ if (ret_pattern_p()) {
+ row->SetOffset(offset);
+ row->GetCFAValue().SetIsRegisterPlusOffset(
+ first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
+
+ UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
+ unwind_plan.InsertRow(new_row);
+ unwind_plan_updated = true;
+ reinstate_unwind_state = true;
+ continue;
+ }
}
} else {
// CFA register is not sp or fp.
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index b9fd84b1e706..fdf4e30b2db5 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -344,6 +344,7 @@ bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr,
unwind_plan.SetSourceName("ARM.exidx unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
return true;
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index 6fe617080f96..77a4830dea7c 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -12,7 +12,6 @@
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Utility/Log.h"
@@ -337,22 +336,24 @@ void Block::AddRange(const Range &range) {
const Declaration &func_decl = func_type->GetDeclaration();
if (func_decl.GetLine()) {
- log->Printf("warning: %s:%u block {0x%8.8" PRIx64
- "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
- ") which is not contained in parent block {0x%8.8" PRIx64
- "} in function {0x%8.8" PRIx64 "} from %s",
- func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
- GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
- block_end_addr, parent_block->GetID(), function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
+ LLDB_LOGF(log,
+ "warning: %s:%u block {0x%8.8" PRIx64
+ "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
} else {
- log->Printf("warning: block {0x%8.8" PRIx64
- "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
- ") which is not contained in parent block {0x%8.8" PRIx64
- "} in function {0x%8.8" PRIx64 "} from %s",
- GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
- block_end_addr, parent_block->GetID(), function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
+ LLDB_LOGF(log,
+ "warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64
+ " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
}
}
parent_block->AddRange(range);
@@ -391,7 +392,7 @@ VariableListSP Block::GetBlockVariableList(bool can_create) {
SymbolContext sc;
CalculateSymbolContext(&sc);
assert(sc.module_sp);
- sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+ sc.module_sp->GetSymbolFile()->ParseVariablesForContext(sc);
}
}
return m_variable_list_sp;
@@ -462,8 +463,7 @@ uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables,
SymbolFile *Block::GetSymbolFile() {
if (ModuleSP module_sp = CalculateSymbolContextModule())
- if (SymbolVendor *sym_vendor = module_sp->GetSymbolVendor())
- return sym_vendor->GetSymbolFile();
+ return module_sp->GetSymbolFile();
return nullptr;
}
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 205523355ce0..565b15a007da 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -47,11 +47,11 @@
#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/Frontend/LangStandard.h"
#include "clang/Sema/Sema.h"
#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
@@ -65,6 +65,7 @@
#include "llvm/Support/Threading.h"
#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
#include "lldb/Utility/ArchSpec.h"
@@ -76,14 +77,12 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/VerifyDecl.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
@@ -104,17 +103,24 @@
using namespace lldb;
using namespace lldb_private;
-using namespace llvm;
using namespace clang;
+using llvm::StringSwitch;
namespace {
+#ifdef LLDB_CONFIGURATION_DEBUG
+static void VerifyDecl(clang::Decl *decl) {
+ assert(decl && "VerifyDecl called with nullptr?");
+ decl->getAccess();
+}
+#endif
+
static inline bool
ClangASTContextSupportsLanguage(lldb::LanguageType language) {
return language == eLanguageTypeUnknown || // Clang is the default type system
- Language::LanguageIsC(language) ||
- Language::LanguageIsCPlusPlus(language) ||
- Language::LanguageIsObjC(language) ||
- Language::LanguageIsPascal(language) ||
+ 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 ||
@@ -331,219 +337,82 @@ static ClangASTMap &GetASTMap() {
return *g_map_ptr;
}
-bool ClangASTContext::IsOperator(const char *name,
+bool ClangASTContext::IsOperator(llvm::StringRef name,
clang::OverloadedOperatorKind &op_kind) {
- if (name == nullptr || name[0] == '\0')
- return false;
-
-#define OPERATOR_PREFIX "operator"
-#define OPERATOR_PREFIX_LENGTH (sizeof(OPERATOR_PREFIX) - 1)
-
- const char *post_op_name = nullptr;
-
- bool no_space = true;
-
- if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+ // All operators have to start with "operator".
+ if (!name.consume_front("operator"))
return false;
- post_op_name = name + OPERATOR_PREFIX_LENGTH;
-
- if (post_op_name[0] == ' ') {
- post_op_name++;
- no_space = false;
- }
-
-#undef OPERATOR_PREFIX
-#undef OPERATOR_PREFIX_LENGTH
-
- // This is an operator, set the overloaded operator kind to invalid in case
- // this is a conversion operator...
- op_kind = clang::NUM_OVERLOADED_OPERATORS;
-
- switch (post_op_name[0]) {
- default:
- if (no_space)
- return false;
- break;
- case 'n':
- if (no_space)
- return false;
- if (strcmp(post_op_name, "new") == 0)
- op_kind = clang::OO_New;
- else if (strcmp(post_op_name, "new[]") == 0)
- op_kind = clang::OO_Array_New;
- break;
-
- case 'd':
- if (no_space)
- return false;
- if (strcmp(post_op_name, "delete") == 0)
- op_kind = clang::OO_Delete;
- else if (strcmp(post_op_name, "delete[]") == 0)
- op_kind = clang::OO_Array_Delete;
- break;
-
- case '+':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Plus;
- else if (post_op_name[2] == '\0') {
- if (post_op_name[1] == '=')
- op_kind = clang::OO_PlusEqual;
- else if (post_op_name[1] == '+')
- op_kind = clang::OO_PlusPlus;
- }
- break;
-
- case '-':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Minus;
- else if (post_op_name[2] == '\0') {
- switch (post_op_name[1]) {
- case '=':
- op_kind = clang::OO_MinusEqual;
- break;
- case '-':
- op_kind = clang::OO_MinusMinus;
- break;
- case '>':
- op_kind = clang::OO_Arrow;
- break;
- }
- } else if (post_op_name[3] == '\0') {
- if (post_op_name[2] == '*')
- op_kind = clang::OO_ArrowStar;
- break;
- }
- break;
-
- case '*':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Star;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_StarEqual;
- break;
-
- case '/':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Slash;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_SlashEqual;
- break;
-
- case '%':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Percent;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_PercentEqual;
- break;
-
- case '^':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Caret;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_CaretEqual;
- break;
-
- case '&':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Amp;
- else if (post_op_name[2] == '\0') {
- switch (post_op_name[1]) {
- case '=':
- op_kind = clang::OO_AmpEqual;
- break;
- case '&':
- op_kind = clang::OO_AmpAmp;
- break;
- }
- }
- break;
-
- case '|':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Pipe;
- else if (post_op_name[2] == '\0') {
- switch (post_op_name[1]) {
- case '=':
- op_kind = clang::OO_PipeEqual;
- break;
- case '|':
- op_kind = clang::OO_PipePipe;
- break;
- }
- }
- break;
-
- case '~':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Tilde;
- break;
-
- case '!':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Exclaim;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_ExclaimEqual;
- break;
-
- case '=':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Equal;
- else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
- op_kind = clang::OO_EqualEqual;
- break;
-
- case '<':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Less;
- else if (post_op_name[2] == '\0') {
- switch (post_op_name[1]) {
- case '<':
- op_kind = clang::OO_LessLess;
- break;
- case '=':
- op_kind = clang::OO_LessEqual;
- break;
- }
- } else if (post_op_name[3] == '\0') {
- if (post_op_name[2] == '=')
- op_kind = clang::OO_LessLessEqual;
- }
- break;
-
- case '>':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Greater;
- else if (post_op_name[2] == '\0') {
- switch (post_op_name[1]) {
- case '>':
- op_kind = clang::OO_GreaterGreater;
- break;
- case '=':
- op_kind = clang::OO_GreaterEqual;
- break;
- }
- } else if (post_op_name[1] == '>' && post_op_name[2] == '=' &&
- post_op_name[3] == '\0') {
- op_kind = clang::OO_GreaterGreaterEqual;
- }
- break;
-
- case ',':
- if (post_op_name[1] == '\0')
- op_kind = clang::OO_Comma;
- break;
-
- case '(':
- if (post_op_name[1] == ')' && post_op_name[2] == '\0')
- op_kind = clang::OO_Call;
- break;
+ // 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;
- case '[':
- if (post_op_name[1] == ']' && post_op_name[2] == '\0')
- op_kind = clang::OO_Subscript;
- break;
- }
+ // 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;
}
@@ -571,7 +440,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
// 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() == InputKind::Asm) {
+ if (IK.getLanguage() == clang::Language::Asm) {
Opts.AsmPreprocessor = 1;
} else if (IK.isObjectiveC()) {
Opts.ObjC = 1;
@@ -582,26 +451,26 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
if (LangStd == LangStandard::lang_unspecified) {
// Based on the base language, pick one.
switch (IK.getLanguage()) {
- case InputKind::Unknown:
- case InputKind::LLVM_IR:
- case InputKind::RenderScript:
+ case clang::Language::Unknown:
+ case clang::Language::LLVM_IR:
+ case clang::Language::RenderScript:
llvm_unreachable("Invalid input kind!");
- case InputKind::OpenCL:
+ case clang::Language::OpenCL:
LangStd = LangStandard::lang_opencl10;
break;
- case InputKind::CUDA:
+ case clang::Language::CUDA:
LangStd = LangStandard::lang_cuda;
break;
- case InputKind::Asm:
- case InputKind::C:
- case InputKind::ObjC:
+ case clang::Language::Asm:
+ case clang::Language::C:
+ case clang::Language::ObjC:
LangStd = LangStandard::lang_gnu99;
break;
- case InputKind::CXX:
- case InputKind::ObjCXX:
+ case clang::Language::CXX:
+ case clang::Language::ObjCXX:
LangStd = LangStandard::lang_gnucxx98;
break;
- case InputKind::HIP:
+ case clang::Language::HIP:
LangStd = LangStandard::lang_hip;
break;
}
@@ -625,7 +494,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
Opts.OpenCL = 1;
Opts.AltiVec = 1;
Opts.CXXOperatorNames = 1;
- Opts.LaxVectorConversions = 1;
+ Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All);
}
// OpenCL and C++ both have bool, true, false keywords.
@@ -653,15 +522,29 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
Opts.NoInlineDefine = !Opt;
}
-ClangASTContext::ClangASTContext(const char *target_triple)
- : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_up(),
- m_language_options_up(), m_source_manager_up(), m_diagnostics_engine_up(),
- m_target_options_rp(), m_target_info_up(), m_identifier_table_up(),
- m_selector_table_up(), m_builtins_up(), m_callback_tag_decl(nullptr),
- m_callback_objc_decl(nullptr), m_callback_baton(nullptr),
- m_pointer_byte_size(0), m_ast_owned(false) {
- if (target_triple && target_triple[0])
+ClangASTContext::ClangASTContext(llvm::StringRef target_triple)
+ : TypeSystem(TypeSystem::eKindClang) {
+ if (!target_triple.empty())
SetTargetTriple(target_triple);
+ // The caller didn't pass an ASTContext so create a new one for this
+ // ClangASTContext.
+ CreateASTContext();
+}
+
+ClangASTContext::ClangASTContext(ArchSpec arch)
+ : TypeSystem(TypeSystem::eKindClang) {
+ SetTargetTriple(arch.GetTriple().str());
+ // The caller didn't pass an ASTContext so create a new one for this
+ // ClangASTContext.
+ CreateASTContext();
+}
+
+ClangASTContext::ClangASTContext(ASTContext &existing_ctxt)
+ : TypeSystem(TypeSystem::eKindClang) {
+ SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str());
+
+ m_ast_up.reset(&existing_ctxt);
+ GetASTMap().Insert(&existing_ctxt, this);
}
// Destructor
@@ -695,6 +578,7 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64_32 ||
fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
} else {
@@ -703,58 +587,57 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
}
if (module) {
- std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
- if (ast_sp) {
- ast_sp->SetArchitecture(fixed_arch);
- }
+ std::shared_ptr<ClangASTContext> ast_sp(
+ new ClangASTContext(fixed_arch));
return ast_sp;
} else if (target && target->IsValid()) {
std::shared_ptr<ClangASTContextForExpressions> ast_sp(
- new ClangASTContextForExpressions(*target));
- if (ast_sp) {
- ast_sp->SetArchitecture(fixed_arch);
- ast_sp->m_scratch_ast_source_up.reset(
- new ClangASTSource(target->shared_from_this()));
- lldbassert(ast_sp->getFileManager());
- ast_sp->m_scratch_ast_source_up->InstallASTContext(
- *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
- ast_sp->m_scratch_ast_source_up->CreateProxy());
- ast_sp->SetExternalSource(proxy_ast_source);
- return ast_sp;
- }
+ new ClangASTContextForExpressions(*target, fixed_arch));
+ ast_sp->m_scratch_ast_source_up.reset(
+ new ClangASTSource(target->shared_from_this()));
+ lldbassert(ast_sp->getFileManager());
+ ast_sp->m_scratch_ast_source_up->InstallASTContext(
+ *ast_sp->getASTContext(), *ast_sp->getFileManager(), true);
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
+ ast_sp->m_scratch_ast_source_up->CreateProxy());
+ ast_sp->SetExternalSource(proxy_ast_source);
+ return ast_sp;
}
}
}
return lldb::TypeSystemSP();
}
-void ClangASTContext::EnumerateSupportedLanguages(
- std::set<lldb::LanguageType> &languages_for_types,
- std::set<lldb::LanguageType> &languages_for_expressions) {
- static std::vector<lldb::LanguageType> s_supported_languages_for_types(
- {lldb::eLanguageTypeC89, lldb::eLanguageTypeC, lldb::eLanguageTypeC11,
- lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeC99,
- lldb::eLanguageTypeObjC, lldb::eLanguageTypeObjC_plus_plus,
- lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
- lldb::eLanguageTypeC11, lldb::eLanguageTypeC_plus_plus_14});
-
- static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
- {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC_plus_plus,
- lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
- lldb::eLanguageTypeC_plus_plus_14});
-
- languages_for_types.insert(s_supported_languages_for_types.begin(),
- s_supported_languages_for_types.end());
- languages_for_expressions.insert(
- s_supported_languages_for_expressions.begin(),
- s_supported_languages_for_expressions.end());
+LanguageSet ClangASTContext::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 ClangASTContext::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 ClangASTContext::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- "clang base AST context plug-in",
- CreateInstance, EnumerateSupportedLanguages);
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance,
+ GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions());
}
void ClangASTContext::Terminate() {
@@ -762,11 +645,10 @@ void ClangASTContext::Terminate() {
}
void ClangASTContext::Finalize() {
- if (m_ast_up) {
- GetASTMap().Erase(m_ast_up.get());
- if (!m_ast_owned)
- m_ast_up.release();
- }
+ 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();
@@ -776,23 +658,9 @@ void ClangASTContext::Finalize() {
m_diagnostics_engine_up.reset();
m_source_manager_up.reset();
m_language_options_up.reset();
- m_ast_up.reset();
m_scratch_ast_source_up.reset();
}
-void ClangASTContext::Clear() {
- m_ast_up.reset();
- m_language_options_up.reset();
- m_source_manager_up.reset();
- m_diagnostics_engine_up.reset();
- m_target_options_rp.reset();
- m_target_info_up.reset();
- m_identifier_table_up.reset();
- m_selector_table_up.reset();
- m_builtins_up.reset();
- m_pointer_byte_size = 0;
-}
-
void ClangASTContext::setSema(Sema *s) {
// Ensure that the new sema actually belongs to our ASTContext.
assert(s == nullptr || &s->getASTContext() == m_ast_up.get());
@@ -803,20 +671,8 @@ const char *ClangASTContext::GetTargetTriple() {
return m_target_triple.c_str();
}
-void ClangASTContext::SetTargetTriple(const char *target_triple) {
- Clear();
- m_target_triple.assign(target_triple);
-}
-
-void ClangASTContext::SetArchitecture(const ArchSpec &arch) {
- SetTargetTriple(arch.GetTriple().str().c_str());
-}
-
-bool ClangASTContext::HasExternalSource() {
- ASTContext *ast = getASTContext();
- if (ast)
- return ast->getExternalSource() != nullptr;
- return false;
+void ClangASTContext::SetTargetTriple(llvm::StringRef target_triple) {
+ m_target_triple = target_triple.str();
}
void ClangASTContext::SetExternalSource(
@@ -828,56 +684,40 @@ void ClangASTContext::SetExternalSource(
}
}
-void ClangASTContext::RemoveExternalSource() {
- ASTContext *ast = getASTContext();
-
- if (ast) {
- llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_up;
- ast->setExternalSource(empty_ast_source_up);
- ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
- }
-}
-
-void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) {
- if (!m_ast_owned) {
- m_ast_up.release();
- }
- m_ast_owned = false;
- m_ast_up.reset(ast_ctx);
- GetASTMap().Insert(ast_ctx, this);
+ASTContext *ClangASTContext::getASTContext() {
+ assert(m_ast_up);
+ return m_ast_up.get();
}
-ASTContext *ClangASTContext::getASTContext() {
- if (m_ast_up == nullptr) {
- m_ast_owned = true;
- m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
- *getIdentifierTable(), *getSelectorTable(),
- *getBuiltinContext()));
+void ClangASTContext::CreateASTContext() {
+ assert(!m_ast_up);
+ m_ast_owned = true;
+ m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
+ *getIdentifierTable(), *getSelectorTable(),
+ *getBuiltinContext()));
- m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false);
+ m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), 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);
+ // 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);
- if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
- m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage();
- // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage();
- }
+ if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
+ m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage();
+ // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage();
+ }
- GetASTMap().Insert(m_ast_up.get(), this);
+ GetASTMap().Insert(m_ast_up.get(), this);
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
- new ClangExternalASTSourceCallbacks(
- ClangASTContext::CompleteTagDecl,
- ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
- ClangASTContext::LayoutRecordType, this));
- SetExternalSource(ast_source_up);
- }
- return m_ast_up.get();
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up(
+ new ClangExternalASTSourceCallbacks(
+ ClangASTContext::CompleteTagDecl,
+ ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
+ ClangASTContext::LayoutRecordType, this));
+ SetExternalSource(ast_source_up);
}
ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
@@ -901,8 +741,9 @@ IdentifierTable *ClangASTContext::getIdentifierTable() {
LangOptions *ClangASTContext::getLanguageOptions() {
if (m_language_options_up == nullptr) {
m_language_options_up.reset(new LangOptions());
- ParseLangArgs(*m_language_options_up, InputKind::ObjCXX, GetTargetTriple());
- // InitializeLangOptions(*m_language_options_up, InputKind::ObjCXX);
+ ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
+ GetTargetTriple());
+ // InitializeLangOptions(*m_language_options_up, Language::ObjCXX);
}
return m_language_options_up.get();
}
@@ -956,7 +797,7 @@ public:
llvm::SmallVector<char, 32> diag_str(10);
info.FormatDiagnostic(diag_str);
diag_str.push_back('\0');
- m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
+ LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data());
}
}
@@ -1009,60 +850,71 @@ ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
ASTContext *ast, Encoding encoding, uint32_t bit_size) {
+ auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
if (!ast)
return CompilerType();
switch (encoding) {
case eEncodingInvalid:
if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
- return CompilerType(ast, ast->VoidPtrTy);
+ return CompilerType(clang_ast_context, ast->VoidPtrTy.getAsOpaquePtr());
break;
case eEncodingUint:
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedLongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType(ast, ast->UnsignedInt128Ty);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedInt128Ty.getAsOpaquePtr());
break;
case eEncodingSint:
if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
- return CompilerType(ast, ast->SignedCharTy);
+ return CompilerType(clang_ast_context,
+ ast->SignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
- return CompilerType(ast, ast->ShortTy);
+ return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
- return CompilerType(ast, ast->IntTy);
+ return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(clang_ast_context, ast->LongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
- return CompilerType(ast, ast->Int128Ty);
+ return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
break;
case eEncodingIEEE754:
if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
- return CompilerType(ast, ast->FloatTy);
+ return CompilerType(clang_ast_context, ast->FloatTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
- return CompilerType(ast, ast->DoubleTy);
+ return CompilerType(clang_ast_context, ast->DoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
- return CompilerType(ast, ast->LongDoubleTy);
+ return CompilerType(clang_ast_context,
+ ast->LongDoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
- return CompilerType(ast, ast->HalfTy);
+ return CompilerType(clang_ast_context, ast->HalfTy.getAsOpaquePtr());
break;
case eEncodingVector:
// Sanity check that bit_size is a multiple of 8's.
if (bit_size && !(bit_size & 0x7u))
return CompilerType(
- ast, ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8));
+ clang_ast_context,
+ ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8)
+ .getAsOpaquePtr());
break;
}
@@ -1182,18 +1034,18 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
case DW_ATE_address:
if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
- return CompilerType(ast, ast->VoidPtrTy);
+ return CompilerType(this, ast->VoidPtrTy.getAsOpaquePtr());
break;
case DW_ATE_boolean:
if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
- return CompilerType(ast, ast->BoolTy);
+ return CompilerType(this, ast->BoolTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
+ return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
break;
case DW_ATE_lo_user:
@@ -1203,47 +1055,51 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
CompilerType complex_int_clang_type =
GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
bit_size / 2);
- return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
- complex_int_clang_type)));
+ return CompilerType(
+ this, ast->getComplexType(
+ ClangUtil::GetQualType(complex_int_clang_type))
+ .getAsOpaquePtr());
}
}
break;
case DW_ATE_complex_float:
if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
- return CompilerType(ast, ast->FloatComplexTy);
+ return CompilerType(this, ast->FloatComplexTy.getAsOpaquePtr());
else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
- return CompilerType(ast, ast->DoubleComplexTy);
+ return CompilerType(this, ast->DoubleComplexTy.getAsOpaquePtr());
else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
- return CompilerType(ast, ast->LongDoubleComplexTy);
+ return CompilerType(this, ast->LongDoubleComplexTy.getAsOpaquePtr());
else {
CompilerType complex_float_clang_type =
GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
bit_size / 2);
- return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
- complex_float_clang_type)));
+ return CompilerType(
+ this, ast->getComplexType(
+ ClangUtil::GetQualType(complex_float_clang_type))
+ .getAsOpaquePtr());
}
break;
case DW_ATE_float:
if (streq(type_name, "float") &&
QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
- return CompilerType(ast, ast->FloatTy);
+ return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
if (streq(type_name, "double") &&
QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
- return CompilerType(ast, ast->DoubleTy);
+ return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
if (streq(type_name, "long double") &&
QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
- return CompilerType(ast, ast->LongDoubleTy);
+ return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
// Fall back to not requiring a name match
if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
- return CompilerType(ast, ast->FloatTy);
+ return CompilerType(this, ast->FloatTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
- return CompilerType(ast, ast->DoubleTy);
+ return CompilerType(this, ast->DoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
- return CompilerType(ast, ast->LongDoubleTy);
+ return CompilerType(this, ast->LongDoubleTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
- return CompilerType(ast, ast->HalfTy);
+ return CompilerType(this, ast->HalfTy.getAsOpaquePtr());
break;
case DW_ATE_signed:
@@ -1252,55 +1108,55 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
(getTargetInfo() &&
TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
- return CompilerType(ast, ast->WCharTy);
+ return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
if (streq(type_name, "void") &&
QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
- return CompilerType(ast, ast->VoidTy);
+ return CompilerType(this, ast->VoidTy.getAsOpaquePtr());
if (strstr(type_name, "long long") &&
QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
if (strstr(type_name, "long") &&
QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(this, ast->LongTy.getAsOpaquePtr());
if (strstr(type_name, "short") &&
QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
- return CompilerType(ast, ast->ShortTy);
+ return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
if (strstr(type_name, "char")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
- return CompilerType(ast, ast->CharTy);
+ return CompilerType(this, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
- return CompilerType(ast, ast->SignedCharTy);
+ return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
}
if (strstr(type_name, "int")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
- return CompilerType(ast, ast->IntTy);
+ return CompilerType(this, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
- return CompilerType(ast, ast->Int128Ty);
+ return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
}
}
// We weren't able to match up a type name, just search by size
if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
- return CompilerType(ast, ast->CharTy);
+ return CompilerType(this, ast->CharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
- return CompilerType(ast, ast->ShortTy);
+ return CompilerType(this, ast->ShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
- return CompilerType(ast, ast->IntTy);
+ return CompilerType(this, ast->IntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(this, ast->LongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(this, ast->LongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
- return CompilerType(ast, ast->Int128Ty);
+ return CompilerType(this, ast->Int128Ty.getAsOpaquePtr());
break;
case DW_ATE_signed_char:
if (ast->getLangOpts().CharIsSigned && type_name &&
streq(type_name, "char")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
- return CompilerType(ast, ast->CharTy);
+ return CompilerType(this, ast->CharTy.getAsOpaquePtr());
}
if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
- return CompilerType(ast, ast->SignedCharTy);
+ return CompilerType(this, ast->SignedCharTy.getAsOpaquePtr());
break;
case DW_ATE_unsigned:
@@ -1309,53 +1165,53 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
if (!(getTargetInfo() &&
TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
- return CompilerType(ast, ast->WCharTy);
+ return CompilerType(this, ast->WCharTy.getAsOpaquePtr());
}
}
if (strstr(type_name, "long long")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
} else if (strstr(type_name, "long")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
} else if (strstr(type_name, "short")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
} else if (strstr(type_name, "char")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
} else if (strstr(type_name, "int")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
+ return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType(ast, ast->UnsignedInt128Ty);
+ return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
}
}
// We weren't able to match up a type name, just search by size
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
+ return CompilerType(this, ast->UnsignedIntTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(this, ast->UnsignedLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(this, ast->UnsignedLongLongTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType(ast, ast->UnsignedInt128Ty);
+ return CompilerType(this, ast->UnsignedInt128Ty.getAsOpaquePtr());
break;
case DW_ATE_unsigned_char:
if (!ast->getLangOpts().CharIsSigned && type_name &&
streq(type_name, "char")) {
if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
- return CompilerType(ast, ast->CharTy);
+ return CompilerType(this, ast->CharTy.getAsOpaquePtr());
}
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(this, ast->UnsignedCharTy.getAsOpaquePtr());
if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(this, ast->UnsignedShortTy.getAsOpaquePtr());
break;
case DW_ATE_imaginary_float:
@@ -1363,11 +1219,12 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
case DW_ATE_UTF:
if (type_name) {
- if (streq(type_name, "char16_t")) {
- return CompilerType(ast, ast->Char16Ty);
- } else if (streq(type_name, "char32_t")) {
- return CompilerType(ast, ast->Char32Ty);
- }
+ if (streq(type_name, "char16_t"))
+ return CompilerType(this, ast->Char16Ty.getAsOpaquePtr());
+ if (streq(type_name, "char32_t"))
+ return CompilerType(this, ast->Char32Ty.getAsOpaquePtr());
+ if (streq(type_name, "char8_t"))
+ return CompilerType(this, ast->Char8Ty.getAsOpaquePtr());
}
break;
}
@@ -1390,7 +1247,8 @@ CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
if (ast)
- return CompilerType(ast, ast->UnknownAnyTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnknownAnyTy.getAsOpaquePtr());
return CompilerType();
}
@@ -1401,7 +1259,7 @@ CompilerType ClangASTContext::GetCStringType(bool is_const) {
if (is_const)
char_type.addConst();
- return CompilerType(ast, ast->getPointerType(char_type));
+ return CompilerType(this, ast->getPointerType(char_type).getAsOpaquePtr());
}
clang::DeclContext *
@@ -1446,6 +1304,16 @@ bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
}
+CompilerType ClangASTContext::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();
+}
+
CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
if (clang::ObjCInterfaceDecl *interface_decl =
llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
@@ -1461,7 +1329,8 @@ CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
// AST if our AST didn't already exist...
ASTContext *ast = &decl->getASTContext();
if (ast)
- return CompilerType(ast, ast->getTagDeclType(decl));
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->getTagDeclType(decl).getAsOpaquePtr());
return CompilerType();
}
@@ -1471,7 +1340,8 @@ CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
// AST if our AST didn't already exist...
ASTContext *ast = &decl->getASTContext();
if (ast)
- return CompilerType(ast, ast->getObjCInterfaceType(decl));
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->getObjCInterfaceType(decl).getAsOpaquePtr());
return CompilerType();
}
@@ -1501,14 +1371,43 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
// something is struct or a class, so we default to always use the more
// complete definition just in case.
- bool is_anonymous = (!name) || (!name[0]);
+ bool has_name = name && name[0];
CXXRecordDecl *decl = CXXRecordDecl::Create(
*ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
- SourceLocation(), is_anonymous ? nullptr : &ast->Idents.get(name));
+ SourceLocation(), has_name ? &ast->Idents.get(name) : nullptr);
- if (is_anonymous)
- decl->setAnonymousStructOrUnion(true);
+ 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.
+ //
+ // FIXME: An unnamed class within a class is also wrongly recognized as an
+ // anonymous struct.
+ if (isa<CXXRecordDecl>(decl_ctx))
+ decl->setAnonymousStructOrUnion(true);
+ }
if (decl) {
if (metadata)
@@ -1520,7 +1419,7 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
if (decl_ctx)
decl_ctx->addDecl(decl);
- return CompilerType(ast, ast->getTagDeclType(decl));
+ return CompilerType(this, ast->getTagDeclType(decl).getAsOpaquePtr());
}
return CompilerType();
}
@@ -1743,7 +1642,8 @@ CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
ASTContext *ast = getASTContext();
if (ast)
return CompilerType(
- ast, ast->getTagDeclType(class_template_specialization_decl));
+ this, ast->getTagDeclType(class_template_specialization_decl)
+ .getAsOpaquePtr());
}
return CompilerType();
}
@@ -1874,7 +1774,7 @@ CompilerType ClangASTContext::CreateObjCClass(const char *name,
if (decl && metadata)
SetMetadata(ast, decl, *metadata);
- return CompilerType(ast, ast->getObjCInterfaceType(decl));
+ return CompilerType(this, ast->getObjCInterfaceType(decl).getAsOpaquePtr());
}
static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
@@ -2220,14 +2120,14 @@ CompilerType ClangASTContext::CreateFunctionType(
proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
proto_info.RefQualifier = RQ_None;
- return CompilerType(ast,
+ return CompilerType(ClangASTContext::GetASTContext(ast),
ast->getFunctionType(ClangUtil::GetQualType(result_type),
- qual_type_args, proto_info));
+ qual_type_args, proto_info).getAsOpaquePtr());
}
ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
clang::DeclContext *decl_ctx, const char *name,
- const CompilerType &param_type, int storage) {
+ const CompilerType &param_type, int storage, bool add_decl) {
ASTContext *ast = getASTContext();
assert(ast != nullptr);
auto *decl =
@@ -2235,7 +2135,9 @@ ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
name && name[0] ? &ast->Idents.get(name) : nullptr,
ClangUtil::GetQualType(param_type), nullptr,
(clang::StorageClass)storage, nullptr);
- decl_ctx->addDecl(decl);
+ if (add_decl)
+ decl_ctx->addDecl(decl);
+
return decl;
}
@@ -2265,20 +2167,23 @@ CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
if (is_vector) {
return CompilerType(
- ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
- element_count));
+ this, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
+ element_count)
+ .getAsOpaquePtr());
} else {
llvm::APInt ap_element_count(64, element_count);
if (element_count == 0) {
- return CompilerType(ast, ast->getIncompleteArrayType(
- ClangUtil::GetQualType(element_type),
- clang::ArrayType::Normal, 0));
+ return CompilerType(this, ast->getIncompleteArrayType(
+ ClangUtil::GetQualType(element_type),
+ clang::ArrayType::Normal, 0)
+ .getAsOpaquePtr());
} else {
- return CompilerType(
- ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
- ap_element_count,
- clang::ArrayType::Normal, 0));
+ return CompilerType(this, ast->getConstantArrayType(
+ ClangUtil::GetQualType(element_type),
+ ap_element_count, nullptr,
+ clang::ArrayType::Normal, 0)
+ .getAsOpaquePtr());
}
}
}
@@ -2352,7 +2257,7 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
- return CompilerType(ast, ast->getTagDeclType(enum_decl));
+ return CompilerType(this, ast->getTagDeclType(enum_decl).getAsOpaquePtr());
}
return CompilerType();
}
@@ -2361,42 +2266,51 @@ CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
size_t bit_size,
bool is_signed) {
if (ast) {
+ auto *clang_ast_context = ClangASTContext::GetASTContext(ast);
if (is_signed) {
if (bit_size == ast->getTypeSize(ast->SignedCharTy))
- return CompilerType(ast, ast->SignedCharTy);
+ return CompilerType(clang_ast_context,
+ ast->SignedCharTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->ShortTy))
- return CompilerType(ast, ast->ShortTy);
+ return CompilerType(clang_ast_context, ast->ShortTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->IntTy))
- return CompilerType(ast, ast->IntTy);
+ return CompilerType(clang_ast_context, ast->IntTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(clang_ast_context, ast->LongTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(clang_ast_context,
+ ast->LongLongTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->Int128Ty))
- return CompilerType(ast, ast->Int128Ty);
+ return CompilerType(clang_ast_context, ast->Int128Ty.getAsOpaquePtr());
} else {
if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedCharTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedShortTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedIntTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedLongTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedLongLongTy.getAsOpaquePtr());
if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
- return CompilerType(ast, ast->UnsignedInt128Ty);
+ return CompilerType(clang_ast_context,
+ ast->UnsignedInt128Ty.getAsOpaquePtr());
}
}
return CompilerType();
@@ -2926,8 +2840,9 @@ bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
case clang::Type::ConstantArray:
if (element_type_ptr)
element_type_ptr->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
+ this, llvm::cast<clang::ConstantArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
if (size)
*size = llvm::cast<clang::ConstantArrayType>(qual_type)
->getSize()
@@ -2939,8 +2854,9 @@ bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
case clang::Type::IncompleteArray:
if (element_type_ptr)
element_type_ptr->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
+ this, llvm::cast<clang::IncompleteArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
if (size)
*size = 0;
if (is_incomplete)
@@ -2950,8 +2866,9 @@ bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
case clang::Type::VariableArray:
if (element_type_ptr)
element_type_ptr->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
+ this, llvm::cast<clang::VariableArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
if (size)
*size = 0;
if (is_incomplete)
@@ -2961,8 +2878,9 @@ bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
case clang::Type::DependentSizedArray:
if (element_type_ptr)
element_type_ptr->SetCompilerType(
- getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)
- ->getElementType());
+ this, llvm::cast<clang::DependentSizedArrayType>(qual_type)
+ ->getElementType()
+ .getAsOpaquePtr());
if (size)
*size = 0;
if (is_incomplete)
@@ -3013,7 +2931,7 @@ bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
*size = vector_type->getNumElements();
if (element_type)
*element_type =
- CompilerType(getASTContext(), vector_type->getElementType());
+ CompilerType(this, vector_type->getElementType().getAsOpaquePtr());
}
return true;
} break;
@@ -3025,7 +2943,7 @@ bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
*size = ext_vector_type->getNumElements();
if (element_type)
*element_type =
- CompilerType(getASTContext(), ext_vector_type->getElementType());
+ CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr());
}
return true;
}
@@ -3218,7 +3136,7 @@ ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
++num_fields;
}
if (base_type_ptr)
- *base_type_ptr = CompilerType(getASTContext(), base_qual_type);
+ *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr());
return num_fields;
}
}
@@ -3270,7 +3188,7 @@ ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
if (func) {
if (index < func->getNumParams())
- return CompilerType(getASTContext(), func->getParamType(index));
+ return CompilerType(this, func->getParamType(index).getAsOpaquePtr());
}
}
return CompilerType();
@@ -3330,7 +3248,7 @@ bool ClangASTContext::IsBlockPointerType(
QualType pointee_type = block_pointer_type->getPointeeType();
QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
*function_pointer_type_ptr =
- CompilerType(getASTContext(), function_pointer_type);
+ CompilerType(this, function_pointer_type.getAsOpaquePtr());
}
return true;
}
@@ -3427,26 +3345,30 @@ bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
case clang::Type::ObjCObjectPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
- ->getPointeeType());
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::BlockPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+ this, llvm::cast<clang::BlockPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::Pointer:
if (pointee_type)
- pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+ pointee_type->SetCompilerType(this,
+ llvm::cast<clang::PointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::MemberPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+ this, llvm::cast<clang::MemberPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::Typedef:
return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
@@ -3495,38 +3417,43 @@ bool ClangASTContext::IsPointerOrReferenceType(
case clang::Type::ObjCObjectPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
- ->getPointeeType());
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType().getAsOpaquePtr());
return true;
case clang::Type::BlockPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+ this, llvm::cast<clang::BlockPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::Pointer:
if (pointee_type)
- pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+ pointee_type->SetCompilerType(this,
+ llvm::cast<clang::PointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::MemberPointer:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+ this, llvm::cast<clang::MemberPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
case clang::Type::LValueReference:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+ this, llvm::cast<clang::LValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
return true;
case clang::Type::RValueReference:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+ this, llvm::cast<clang::RValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
return true;
case clang::Type::Typedef:
return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
@@ -3569,16 +3496,18 @@ bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
case clang::Type::LValueReference:
if (pointee_type)
pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+ 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(
- getASTContext(),
- llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+ this, llvm::cast<clang::RValueReferenceType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
if (is_rvalue)
*is_rvalue = true;
return true;
@@ -3770,9 +3699,9 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
}
if (dynamic_pointee_type)
dynamic_pointee_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::ObjCObjectPointerType>(qual_type)
- ->getPointeeType());
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType()
+ .getAsOpaquePtr());
return true;
}
break;
@@ -3832,8 +3761,8 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::UnknownAny:
case clang::BuiltinType::Void:
if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(),
- pointee_qual_type);
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
return true;
default:
break;
@@ -3855,8 +3784,9 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
if (metadata)
success = metadata->GetIsDynamicCXXType();
else {
- is_complete = CompilerType(getASTContext(), pointee_qual_type)
- .GetCompleteType();
+ is_complete =
+ CompilerType(this, pointee_qual_type.getAsOpaquePtr())
+ .GetCompleteType();
if (is_complete)
success = cxx_record_decl->isDynamicClass();
else
@@ -3866,8 +3796,8 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
if (success) {
if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(),
- pointee_qual_type);
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
return true;
}
}
@@ -3878,8 +3808,8 @@ bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
case clang::Type::ObjCInterface:
if (check_objc) {
if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(),
- pointee_qual_type);
+ dynamic_pointee_type->SetCompilerType(
+ this, pointee_qual_type.getAsOpaquePtr());
return true;
}
break;
@@ -3987,25 +3917,6 @@ bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
return false;
}
-bool ClangASTContext::GetObjCClassName(const CompilerType &type,
- std::string &class_name) {
- if (!type)
- return false;
-
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
-
- const clang::ObjCObjectType *object_type =
- llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (object_type) {
- const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
- if (interface) {
- class_name = interface->getNameAsString();
- return true;
- }
- }
- return false;
-}
-
// Type Completion
bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
@@ -4062,14 +3973,14 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::ObjCClass:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(), getASTContext()->ObjCBuiltinClassTy);
+ 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(getASTContext(),
- getASTContext()->CharTy);
+ pointee_or_element_clang_type->SetCompilerType(
+ this, getASTContext()->CharTy.getAsOpaquePtr());
builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
break;
@@ -4112,7 +4023,7 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::BlockPointer:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(), qual_type->getPointeeType());
+ this, qual_type->getPointeeType().getAsOpaquePtr());
return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
case clang::Type::Complex: {
@@ -4136,8 +4047,9 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::VariableArray:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
- ->getElementType());
+ this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
+ ->getElementType()
+ .getAsOpaquePtr());
return eTypeHasChildren | eTypeIsArray;
case clang::Type::DependentName:
@@ -4147,31 +4059,34 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::DependentTemplateSpecialization:
return eTypeIsTemplate;
case clang::Type::Decltype:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::Enum:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
+ this, llvm::cast<clang::EnumType>(qual_type)
+ ->getDecl()
+ ->getIntegerType()
+ .getAsOpaquePtr());
return eTypeIsEnumeration | eTypeHasValue;
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::FunctionProto:
@@ -4185,9 +4100,9 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::RValueReference:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(),
- llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
- ->getPointeeType());
+ this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
+ ->getPointeeType()
+ .getAsOpaquePtr());
return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
case clang::Type::MemberPointer:
@@ -4196,7 +4111,7 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::ObjCObjectPointer:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(), qual_type->getPointeeType());
+ this, qual_type->getPointeeType().getAsOpaquePtr());
return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
eTypeHasValue;
@@ -4208,7 +4123,7 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::Pointer:
if (pointee_or_element_clang_type)
pointee_or_element_clang_type->SetCompilerType(
- getASTContext(), qual_type->getPointeeType());
+ this, qual_type->getPointeeType().getAsOpaquePtr());
return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
case clang::Type::Record:
@@ -4226,21 +4141,21 @@ ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
case clang::Type::Typedef:
return eTypeIsTypedef |
- CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::TypeOfExpr:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypeOfExprType>(qual_type)
- ->getUnderlyingExpr()
- ->getType())
+ return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::TypeOf:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetTypeInfo(pointee_or_element_clang_type);
case clang::Type::UnresolvedUsing:
return 0;
@@ -4339,10 +4254,10 @@ ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
}
break;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetMinimumLanguage();
}
}
@@ -4420,18 +4335,19 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
case clang::Type::UnresolvedUsing:
break;
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::Attributed:
@@ -4452,20 +4368,20 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::TypeOfExpr:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypeOfExprType>(qual_type)
- ->getUnderlyingExpr()
- ->getType())
+ return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::TypeOf:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::Decltype:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetTypeClass();
case clang::Type::TemplateSpecialization:
break;
@@ -4513,8 +4429,8 @@ ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
if (!array_eletype)
return CompilerType();
- CompilerType element_type(getASTContext(),
- array_eletype->getCanonicalTypeUnqualified());
+ CompilerType element_type(
+ this, array_eletype->getCanonicalTypeUnqualified().getAsOpaquePtr());
// TODO: the real stride will be >= this value.. find the real one!
if (stride)
@@ -4533,14 +4449,18 @@ CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
if (clang::ASTContext *ast_ctx = getASTContext()) {
if (size != 0)
return CompilerType(
- ast_ctx, ast_ctx->getConstantArrayType(
- qual_type, llvm::APInt(64, size),
- clang::ArrayType::ArraySizeModifier::Normal, 0));
+ this, ast_ctx
+ ->getConstantArrayType(
+ qual_type, llvm::APInt(64, size), nullptr,
+ clang::ArrayType::ArraySizeModifier::Normal, 0)
+ .getAsOpaquePtr());
else
return CompilerType(
- ast_ctx,
- ast_ctx->getIncompleteArrayType(
- qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
+ this,
+ ast_ctx
+ ->getIncompleteArrayType(
+ qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)
+ .getAsOpaquePtr());
}
}
@@ -4550,7 +4470,7 @@ CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
CompilerType
ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
if (type)
- return CompilerType(getASTContext(), GetCanonicalQualType(type));
+ return CompilerType(this, GetCanonicalQualType(type).getAsOpaquePtr());
return CompilerType();
}
@@ -4571,8 +4491,8 @@ CompilerType
ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
if (type)
return CompilerType(
- getASTContext(),
- GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
+ this,
+ GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)).getAsOpaquePtr());
return CompilerType();
}
@@ -4595,7 +4515,7 @@ CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
if (func) {
const uint32_t num_args = func->getNumParams();
if (idx < num_args)
- return CompilerType(getASTContext(), func->getParamType(idx));
+ return CompilerType(this, func->getParamType(idx).getAsOpaquePtr());
}
}
return CompilerType();
@@ -4608,7 +4528,7 @@ ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
const clang::FunctionProtoType *func =
llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
if (func)
- return CompilerType(getASTContext(), func->getReturnType());
+ return CompilerType(this, func->getReturnType().getAsOpaquePtr());
}
return CompilerType();
}
@@ -4667,27 +4587,28 @@ ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetNumMemberFunctions();
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetNumMemberFunctions();
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetNumMemberFunctions();
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetNumMemberFunctions();
default:
@@ -4843,8 +4764,8 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
CompilerType
ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
if (type)
- return CompilerType(getASTContext(),
- GetQualType(type).getNonReferenceType());
+ return CompilerType(
+ this, GetQualType(type).getNonReferenceType().getAsOpaquePtr());
return CompilerType();
}
@@ -4874,7 +4795,7 @@ CompilerType ClangASTContext::CreateTypedefType(
decl_ctx->addDecl(decl);
// Get a uniqued clang::QualType for the typedef decl type
- return CompilerType(clang_ast, clang_ast->getTypedefType(decl));
+ return CompilerType(ast, clang_ast->getTypedefType(decl).getAsOpaquePtr());
}
return CompilerType();
}
@@ -4883,8 +4804,8 @@ CompilerType
ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
if (type) {
clang::QualType qual_type(GetQualType(type));
- return CompilerType(getASTContext(),
- qual_type.getTypePtr()->getPointeeType());
+ return CompilerType(
+ this, qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr());
}
return CompilerType();
}
@@ -4898,12 +4819,13 @@ ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
switch (type_class) {
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
- return CompilerType(getASTContext(),
- getASTContext()->getObjCObjectPointerType(qual_type));
+ return CompilerType(this, getASTContext()
+ ->getObjCObjectPointerType(qual_type)
+ .getAsOpaquePtr());
default:
- return CompilerType(getASTContext(),
- getASTContext()->getPointerType(qual_type));
+ return CompilerType(
+ this, getASTContext()->getPointerType(qual_type).getAsOpaquePtr());
}
}
return CompilerType();
@@ -5005,8 +4927,8 @@ ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
const clang::TypedefType *typedef_type =
llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
if (typedef_type)
- return CompilerType(getASTContext(),
- typedef_type->getDecl()->getUnderlyingType());
+ return CompilerType(
+ this, typedef_type->getDecl()->getUnderlyingType().getAsOpaquePtr());
}
return CompilerType();
}
@@ -5018,6 +4940,22 @@ CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
}
// Exploring the type
+const llvm::fltSemantics &
+ClangASTContext::GetFloatTypeSemantics(size_t byte_size) {
+ if (auto *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>
ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) {
@@ -5041,7 +4979,7 @@ ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
if (objc_runtime) {
uint64_t bit_size = 0;
if (objc_runtime->GetTypeBitSize(
- CompilerType(getASTContext(), qual_type), bit_size))
+ CompilerType(this, qual_type.getAsOpaquePtr()), bit_size))
return bit_size;
}
} else {
@@ -5084,10 +5022,12 @@ ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
return None;
}
-size_t ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
+llvm::Optional<size_t>
+ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) {
if (GetCompleteType(type))
return getASTContext()->getTypeAlign(GetQualType(type));
- return 0;
+ return {};
}
lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
@@ -5255,6 +5195,20 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
break;
+
+ case clang::BuiltinType::SveBool:
+ case clang::BuiltinType::SveInt8:
+ case clang::BuiltinType::SveInt16:
+ case clang::BuiltinType::SveInt32:
+ case clang::BuiltinType::SveInt64:
+ case clang::BuiltinType::SveUint8:
+ case clang::BuiltinType::SveUint16:
+ case clang::BuiltinType::SveUint32:
+ case clang::BuiltinType::SveUint64:
+ case clang::BuiltinType::SveFloat16:
+ case clang::BuiltinType::SveFloat32:
+ case clang::BuiltinType::SveFloat64:
+ break;
}
break;
// All pointer types are represented as unsigned integer encodings. We may
@@ -5274,8 +5228,9 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
const clang::ComplexType *complex_type =
qual_type->getAsComplexIntegerType();
if (complex_type)
- encoding = CompilerType(getASTContext(), complex_type->getElementType())
- .GetEncoding(count);
+ encoding =
+ CompilerType(this, complex_type->getElementType().getAsOpaquePtr())
+ .GetEncoding(count);
else
encoding = lldb::eEncodingSint;
}
@@ -5290,43 +5245,44 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::Type::Enum:
return lldb::eEncodingSint;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::TypeOfExpr:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypeOfExprType>(qual_type)
- ->getUnderlyingExpr()
- ->getType())
+ return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::TypeOf:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::Decltype:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetEncoding(count);
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
@@ -5463,39 +5419,41 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
case clang::Type::Enum:
return lldb::eFormatEnum;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::Auto:
- return CompilerType(getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::TypeOfExpr:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypeOfExprType>(qual_type)
- ->getUnderlyingExpr()
- ->getType())
+ return CompilerType(this, llvm::cast<clang::TypeOfExprType>(qual_type)
+ ->getUnderlyingExpr()
+ ->getType()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::TypeOf:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::TypeOfType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypeOfType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::Decltype:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::DecltypeType>(qual_type)->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::DecltypeType>(qual_type)
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetFormat();
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
@@ -5657,7 +5615,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
clang::QualType pointee_type = pointer_type->getPointeeType();
uint32_t num_pointee_children =
- CompilerType(getASTContext(), pointee_type)
+ CompilerType(this, pointee_type.getAsOpaquePtr())
.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)
@@ -5691,7 +5649,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
llvm::cast<clang::PointerType>(qual_type.getTypePtr());
clang::QualType pointee_type(pointer_type->getPointeeType());
uint32_t num_pointee_children =
- CompilerType(getASTContext(), pointee_type)
+ CompilerType(this, pointee_type.getAsOpaquePtr())
.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
@@ -5707,7 +5665,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
clang::QualType pointee_type = reference_type->getPointeeType();
uint32_t num_pointee_children =
- CompilerType(getASTContext(), pointee_type)
+ CompilerType(this, pointee_type.getAsOpaquePtr())
.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)
@@ -5717,32 +5675,33 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
} break;
case clang::Type::Typedef:
- num_children =
- CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
+ num_children = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
->getDecl()
- ->getUnderlyingType())
- .GetNumChildren(omit_empty_base_classes, exe_ctx);
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Auto:
- num_children =
- CompilerType(getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
- .GetNumChildren(omit_empty_base_classes, exe_ctx);
+ num_children = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
+ .GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Elaborated:
num_children =
- CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
case clang::Type::Paren:
num_children =
- CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ CompilerType(
+ this,
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
.GetNumChildren(omit_empty_base_classes, exe_ctx);
break;
default:
@@ -5883,31 +5842,33 @@ uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::Typedef:
- count =
- CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
- .GetNumFields();
+ count = CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
+ .GetNumFields();
break;
case clang::Type::Auto:
- count =
- CompilerType(getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
- .GetNumFields();
+ count = CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
+ .GetNumFields();
break;
case clang::Type::Elaborated:
- count = CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ count = CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetNumFields();
break;
case clang::Type::Paren:
- count = CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
- .GetNumFields();
+ count =
+ CompilerType(
+ this,
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
+ .GetNumFields();
break;
case clang::Type::ObjCObjectPointer: {
@@ -6053,7 +6014,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
if (is_bitfield_ptr)
*is_bitfield_ptr = is_bitfield;
- return CompilerType(getASTContext(), field->getType());
+ return CompilerType(this, field->getType().getAsOpaquePtr());
}
}
}
@@ -6097,30 +6058,31 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
break;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
is_bitfield_ptr);
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
is_bitfield_ptr);
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
is_bitfield_ptr);
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
is_bitfield_ptr);
@@ -6311,9 +6273,9 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
if (superclass_interface_decl) {
if (bit_offset_ptr)
*bit_offset_ptr = 0;
- return CompilerType(getASTContext(),
+ return CompilerType(this,
getASTContext()->getObjCInterfaceType(
- superclass_interface_decl));
+ superclass_interface_decl).getAsOpaquePtr());
}
}
}
@@ -6333,9 +6295,10 @@ CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
if (superclass_interface_decl) {
if (bit_offset_ptr)
*bit_offset_ptr = 0;
- return CompilerType(getASTContext(),
- getASTContext()->getObjCInterfaceType(
- superclass_interface_decl));
+ return CompilerType(
+ this, getASTContext()
+ ->getObjCInterfaceType(superclass_interface_decl)
+ .getAsOpaquePtr());
}
}
}
@@ -6638,8 +6601,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
child_byte_size =
getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
CHAR_BIT;
- return CompilerType(getASTContext(),
- getASTContext()->ObjCBuiltinClassTy);
+ return CompilerType(
+ this, getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr());
default:
break;
@@ -6702,8 +6665,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// Base classes should be a multiple of 8 bits in size
child_byte_offset = bit_offset / 8;
- CompilerType base_class_clang_type(getASTContext(),
- base_class->getType());
+ CompilerType base_class_clang_type(
+ this, base_class->getType().getAsOpaquePtr());
child_name = base_class_clang_type.GetTypeName().AsCString("");
Optional<uint64_t> size =
base_class_clang_type.GetBitSize(get_exe_scope());
@@ -6735,7 +6698,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
// Figure out the type byte size (field_type_info.first) and
// alignment (field_type_info.second) from the AST context.
- CompilerType field_clang_type(getASTContext(), field->getType());
+ CompilerType field_clang_type(this,
+ field->getType().getAsOpaquePtr());
assert(field_idx < record_layout.getFieldCount());
Optional<uint64_t> size =
field_clang_type.GetByteSize(get_exe_scope());
@@ -6783,8 +6747,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (superclass_interface_decl) {
if (omit_empty_base_classes) {
CompilerType base_class_clang_type(
- getASTContext(), getASTContext()->getObjCInterfaceType(
- superclass_interface_decl));
+ this, getASTContext()
+ ->getObjCInterfaceType(superclass_interface_decl)
+ .getAsOpaquePtr());
if (base_class_clang_type.GetNumChildren(omit_empty_base_classes,
exe_ctx) > 0) {
if (idx == 0) {
@@ -6802,7 +6767,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
child_byte_offset = 0;
child_is_base_class = true;
- return CompilerType(getASTContext(), ivar_qual_type);
+ return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
}
++child_idx;
@@ -6846,8 +6811,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*process);
if (objc_runtime != nullptr) {
- CompilerType parent_ast_type(getASTContext(),
- parent_qual_type);
+ CompilerType parent_ast_type(
+ this, parent_qual_type.getAsOpaquePtr());
child_byte_offset = objc_runtime->GetByteOffsetForIvar(
parent_ast_type, ivar_decl->getNameAsString().c_str());
}
@@ -6878,7 +6843,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
child_bitfield_bit_offset = bit_offset % 8;
}
- return CompilerType(getASTContext(), ivar_qual_type);
+ return CompilerType(this, ivar_qual_type.getAsOpaquePtr());
}
++child_idx;
}
@@ -6929,7 +6894,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
const clang::VectorType *array =
llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
if (array) {
- CompilerType element_type(getASTContext(), array->getElementType());
+ CompilerType element_type(this,
+ array->getElementType().getAsOpaquePtr());
if (element_type.GetCompleteType()) {
char element_name[64];
::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
@@ -6951,7 +6917,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (ignore_array_bounds || idx_is_valid) {
const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
if (array) {
- CompilerType element_type(getASTContext(), array->getElementType());
+ CompilerType element_type(this,
+ array->getElementType().getAsOpaquePtr());
if (element_type.GetCompleteType()) {
child_name = llvm::formatv("[{0}]", idx);
if (Optional<uint64_t> size =
@@ -7009,8 +6976,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
if (idx_is_valid) {
const clang::ReferenceType *reference_type =
llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
- CompilerType pointee_clang_type(getASTContext(),
- reference_type->getPointeeType());
+ CompilerType pointee_clang_type(
+ this, reference_type->getPointeeType().getAsOpaquePtr());
if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
child_is_deref_of_parent = false;
bool tmp_child_is_deref_of_parent = false;
@@ -7043,9 +7010,10 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
case clang::Type::Typedef: {
CompilerType typedefed_clang_type(
- getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)
- ->getDecl()
- ->getUnderlyingType());
+ this, llvm::cast<clang::TypedefType>(parent_qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
return typedefed_clang_type.GetChildCompilerTypeAtIndex(
exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
@@ -7055,8 +7023,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
case clang::Type::Auto: {
CompilerType elaborated_clang_type(
- getASTContext(),
- llvm::cast<clang::AutoType>(parent_qual_type)->getDeducedType());
+ this, llvm::cast<clang::AutoType>(parent_qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
return elaborated_clang_type.GetChildCompilerTypeAtIndex(
exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
@@ -7066,8 +7035,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
case clang::Type::Elaborated: {
CompilerType elaborated_clang_type(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
+ this, llvm::cast<clang::ElaboratedType>(parent_qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
return elaborated_clang_type.GetChildCompilerTypeAtIndex(
exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
@@ -7076,9 +7046,10 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
}
case clang::Type::Paren: {
- CompilerType paren_clang_type(
- getASTContext(),
- llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
+ CompilerType paren_clang_type(this,
+ llvm::cast<clang::ParenType>(parent_qual_type)
+ ->desugar()
+ .getAsOpaquePtr());
return paren_clang_type.GetChildCompilerTypeAtIndex(
exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
@@ -7207,7 +7178,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
field != field_end; ++field, ++child_idx) {
llvm::StringRef field_name = field->getName();
if (field_name.empty()) {
- CompilerType field_type(getASTContext(), field->getType());
+ CompilerType field_type(this, field->getType().getAsOpaquePtr());
child_indexes.push_back(child_idx);
if (field_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes))
@@ -7319,8 +7290,9 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
child_indexes.push_back(0);
CompilerType superclass_clang_type(
- getASTContext(), getASTContext()->getObjCInterfaceType(
- superclass_interface_decl));
+ this, getASTContext()
+ ->getObjCInterfaceType(superclass_interface_decl)
+ .getAsOpaquePtr());
if (superclass_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes)) {
// We did find an ivar in a superclass so just return the
@@ -7339,9 +7311,9 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
case clang::Type::ObjCObjectPointer: {
CompilerType objc_object_clang_type(
- getASTContext(),
- llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
- ->getPointeeType());
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType()
+ .getAsOpaquePtr());
return objc_object_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes);
} break;
@@ -7391,7 +7363,7 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
const clang::ReferenceType *reference_type =
llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
clang::QualType pointee_type(reference_type->getPointeeType());
- CompilerType pointee_clang_type(getASTContext(), pointee_type);
+ CompilerType pointee_clang_type(this, pointee_type.getAsOpaquePtr());
if (pointee_clang_type.IsAggregateType()) {
return pointee_clang_type.GetIndexOfChildMemberWithName(
@@ -7409,30 +7381,31 @@ size_t ClangASTContext::GetIndexOfChildMemberWithName(
} break;
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
child_indexes);
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
child_indexes);
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
child_indexes);
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
child_indexes);
@@ -7485,8 +7458,8 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
!ClangASTContext::RecordHasFields(base_class_decl))
continue;
- CompilerType base_class_clang_type(getASTContext(),
- base_class->getType());
+ CompilerType base_class_clang_type(
+ this, base_class->getType().getAsOpaquePtr());
std::string base_class_type_name(
base_class_clang_type.GetTypeName().AsCString(""));
if (base_class_type_name == name)
@@ -7550,9 +7523,9 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
case clang::Type::ObjCObjectPointer: {
CompilerType pointee_clang_type(
- getASTContext(),
- llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
- ->getPointeeType());
+ this, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType()
+ .getAsOpaquePtr());
return pointee_clang_type.GetIndexOfChildWithName(
name, omit_empty_base_classes);
} break;
@@ -7601,8 +7574,8 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
case clang::Type::RValueReference: {
const clang::ReferenceType *reference_type =
llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- CompilerType pointee_type(getASTContext(),
- reference_type->getPointeeType());
+ CompilerType pointee_type(
+ this, reference_type->getPointeeType().getAsOpaquePtr());
if (pointee_type.IsAggregateType()) {
return pointee_type.GetIndexOfChildWithName(name,
@@ -7613,8 +7586,8 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
case clang::Type::Pointer: {
const clang::PointerType *pointer_type =
llvm::cast<clang::PointerType>(qual_type.getTypePtr());
- CompilerType pointee_type(getASTContext(),
- pointer_type->getPointeeType());
+ CompilerType pointee_type(
+ this, pointer_type->getPointeeType().getAsOpaquePtr());
if (pointee_type.IsAggregateType()) {
return pointee_type.GetIndexOfChildWithName(name,
@@ -7640,27 +7613,28 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
} break;
case clang::Type::Auto:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetIndexOfChildWithName(name, omit_empty_base_classes);
case clang::Type::Elaborated:
- return CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetIndexOfChildWithName(name, omit_empty_base_classes);
case clang::Type::Paren:
- return CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetIndexOfChildWithName(name, omit_empty_base_classes);
case clang::Type::Typedef:
- return CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType())
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetIndexOfChildWithName(name, omit_empty_base_classes);
default:
@@ -7693,27 +7667,28 @@ ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
break;
case clang::Type::Typedef:
- return (CompilerType(getASTContext(),
- llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType()))
+ return CompilerType(this, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr())
.GetNumTemplateArguments();
case clang::Type::Auto:
- return (CompilerType(
- getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType()))
+ return CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.GetNumTemplateArguments();
case clang::Type::Elaborated:
- return (CompilerType(
- getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()))
+ return CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.GetNumTemplateArguments();
case clang::Type::Paren:
- return (CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar()))
+ return CompilerType(this, llvm::cast<clang::ParenType>(qual_type)
+ ->desugar()
+ .getAsOpaquePtr())
.GetNumTemplateArguments();
default:
@@ -7821,7 +7796,7 @@ ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
if (template_arg.getKind() != clang::TemplateArgument::Type)
return CompilerType();
- return CompilerType(getASTContext(), template_arg.getAsType());
+ return CompilerType(this, template_arg.getAsType().getAsOpaquePtr());
}
Optional<CompilerType::IntegralTemplateArgument>
@@ -7837,8 +7812,9 @@ ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
if (template_arg.getKind() != clang::TemplateArgument::Integral)
return llvm::None;
- return {{template_arg.getAsIntegral(),
- CompilerType(getASTContext(), template_arg.getIntegralType())}};
+ return {
+ {template_arg.getAsIntegral(),
+ CompilerType(this, template_arg.getIntegralType().getAsOpaquePtr())}};
}
CompilerType ClangASTContext::GetTypeForFormatters(void *type) {
@@ -8201,7 +8177,8 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
getASTContext()->DeclarationNames.getCXXDestructorName(
getASTContext()->getCanonicalType(record_qual_type)),
clang::SourceLocation()),
- method_qual_type, nullptr, is_inline, is_artificial);
+ method_qual_type, nullptr, is_inline, is_artificial,
+ ConstexprSpecKind::CSK_unspecified);
cxx_method_decl = cxx_dtor_decl;
} else if (decl_name == cxx_record_decl->getDeclName()) {
cxx_ctor_decl = clang::CXXConstructorDecl::Create(
@@ -8272,8 +8249,8 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
if (mangled_name != nullptr) {
- cxx_method_decl->addAttr(
- clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
+ cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
+ *getASTContext(), mangled_name, /*literal=*/false));
}
// Populate the method decl with parameter decls
@@ -8327,24 +8304,6 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType(
VerifyDecl(cxx_method_decl);
#endif
- // printf ("decl->isPolymorphic() = %i\n",
- // cxx_record_decl->isPolymorphic());
- // printf ("decl->isAggregate() = %i\n",
- // cxx_record_decl->isAggregate());
- // printf ("decl->isPOD() = %i\n",
- // cxx_record_decl->isPOD());
- // printf ("decl->isEmpty() = %i\n",
- // cxx_record_decl->isEmpty());
- // printf ("decl->isAbstract() = %i\n",
- // cxx_record_decl->isAbstract());
- // printf ("decl->hasTrivialConstructor() = %i\n",
- // cxx_record_decl->hasTrivialConstructor());
- // printf ("decl->hasTrivialCopyConstructor() = %i\n",
- // cxx_record_decl->hasTrivialCopyConstructor());
- // printf ("decl->hasTrivialCopyAssignment() = %i\n",
- // cxx_record_decl->hasTrivialCopyAssignment());
- // printf ("decl->hasTrivialDestructor() = %i\n",
- // cxx_record_decl->hasTrivialDestructor());
return cxx_method_decl;
}
@@ -8364,7 +8323,7 @@ ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
if (!type)
return nullptr;
- return llvm::make_unique<clang::CXXBaseSpecifier>(
+ return std::make_unique<clang::CXXBaseSpecifier>(
clang::SourceRange(), is_virtual, base_of_class,
ClangASTContext::ConvertAccessTypeToAccessSpecifier(access),
getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)),
@@ -8435,7 +8394,7 @@ bool ClangASTContext::AddObjCClassProperty(
property_clang_type_to_access = property_clang_type;
else if (ivar_decl)
property_clang_type_to_access =
- CompilerType(clang_ast, ivar_decl->getType());
+ CompilerType(ast, ivar_decl->getType().getAsOpaquePtr());
if (class_interface_decl && property_clang_type_to_access.IsValid()) {
clang::TypeSourceInfo *prop_type_source;
@@ -8733,74 +8692,6 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType(
return objc_method_decl;
}
-bool ClangASTContext::GetHasExternalStorage(const CompilerType &type) {
- if (ClangUtil::IsClangType(type))
- return false;
-
- clang::QualType qual_type(ClangUtil::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)
- return cxx_record_decl->hasExternalLexicalStorage() ||
- cxx_record_decl->hasExternalVisibleStorage();
- } break;
-
- case clang::Type::Enum: {
- clang::EnumDecl *enum_decl =
- llvm::cast<clang::EnumType>(qual_type)->getDecl();
- if (enum_decl)
- return enum_decl->hasExternalLexicalStorage() ||
- enum_decl->hasExternalVisibleStorage();
- } 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)
- return class_interface_decl->hasExternalLexicalStorage() ||
- class_interface_decl->hasExternalVisibleStorage();
- }
- } break;
-
- case clang::Type::Typedef:
- return GetHasExternalStorage(CompilerType(
- type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)
- ->getDecl()
- ->getUnderlyingType()
- .getAsOpaquePtr()));
-
- case clang::Type::Auto:
- return GetHasExternalStorage(CompilerType(
- type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)
- ->getDeducedType()
- .getAsOpaquePtr()));
-
- case clang::Type::Elaborated:
- return GetHasExternalStorage(CompilerType(
- type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)
- ->getNamedType()
- .getAsOpaquePtr()));
-
- case clang::Type::Paren:
- return GetHasExternalStorage(CompilerType(
- type.GetTypeSystem(),
- llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
-
- default:
- break;
- }
- return false;
-}
-
bool ClangASTContext::SetHasExternalStorage(lldb::opaque_compiler_type_t type,
bool has_extern) {
if (!type)
@@ -9041,7 +8932,7 @@ ClangASTContext::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
if (enutype) {
clang::EnumDecl *enum_decl = enutype->getDecl();
if (enum_decl)
- return CompilerType(getASTContext(), enum_decl->getIntegerType());
+ return CompilerType(this, enum_decl->getIntegerType().getAsOpaquePtr());
}
}
return CompilerType();
@@ -9056,47 +8947,15 @@ ClangASTContext::CreateMemberPointerType(const CompilerType &type,
llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
if (!ast)
return CompilerType();
- return CompilerType(ast->getASTContext(),
- ast->getASTContext()->getMemberPointerType(
- ClangUtil::GetQualType(pointee_type),
- ClangUtil::GetQualType(type).getTypePtr()));
+ return CompilerType(ast, ast->getASTContext()
+ ->getMemberPointerType(
+ ClangUtil::GetQualType(pointee_type),
+ ClangUtil::GetQualType(type).getTypePtr())
+ .getAsOpaquePtr());
}
return CompilerType();
}
-size_t
-ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
- const char *s, uint8_t *dst,
- size_t dst_size) {
- if (type) {
- clang::QualType qual_type(GetCanonicalQualType(type));
- uint32_t count = 0;
- bool is_complex = false;
- if (IsFloatingPointType(type, count, is_complex)) {
- // TODO: handle complex and vector types
- if (count != 1)
- return false;
-
- llvm::StringRef s_sref(s);
- llvm::APFloat ap_float(getASTContext()->getFloatTypeSemantics(qual_type),
- s_sref);
-
- const uint64_t bit_size = getASTContext()->getTypeSize(qual_type);
- const uint64_t byte_size = bit_size / 8;
- if (dst_size >= byte_size) {
- Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(
- llvm::NextPowerOf2(byte_size) * 8);
- lldb_private::Status get_data_error;
- if (scalar.GetAsMemoryData(dst, byte_size,
- lldb_private::endian::InlHostByteOrder(),
- get_data_error))
- return byte_size;
- }
- }
- }
- return 0;
-}
-
// Dumping types
#define DEPTH_INCREMENT 2
@@ -9115,6 +8974,39 @@ void ClangASTContext::Dump(Stream &s) {
tu->dump(s.AsRawOstream());
}
+void ClangASTContext::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.compare(type->GetName().GetStringRef()) != 0)
+ continue;
+
+ s << type->GetName().AsCString() << "\n";
+
+ if (clang::TagDecl *tag_decl =
+ GetAsTagDecl(type->GetFullCompilerType()))
+ tag_decl->dump(s.AsRawOstream());
+ else if (clang::TypedefNameDecl *typedef_decl =
+ GetAsTypedefDecl(type->GetFullCompilerType()))
+ typedef_decl->dump(s.AsRawOstream());
+ else {
+ GetCanonicalQualType(type->GetFullCompilerType().GetOpaqueQualType())
+ .dump(s.AsRawOstream());
+ }
+ }
+}
+
void ClangASTContext::DumpValue(
lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
lldb::Format format, const DataExtractor &data,
@@ -9182,7 +9074,8 @@ void ClangASTContext::DumpValue(
getASTContext()->getTypeInfo(base_class_qual_type);
// Dump the value of the member
- CompilerType base_clang_type(getASTContext(), base_class_qual_type);
+ CompilerType base_clang_type(this,
+ base_class_qual_type.getAsOpaquePtr());
base_clang_type.DumpValue(
exe_ctx,
s, // Stream to dump to
@@ -9249,7 +9142,7 @@ void ClangASTContext::DumpValue(
s->Printf("%s = ", field->getNameAsString().c_str());
// Dump the value of the member
- CompilerType field_clang_type(getASTContext(), field_type);
+ CompilerType field_clang_type(this, field_type.getAsOpaquePtr());
field_clang_type.DumpValue(
exe_ctx,
s, // Stream to dump to
@@ -9329,7 +9222,7 @@ void ClangASTContext::DumpValue(
s->PutChar('"');
return;
} else {
- CompilerType element_clang_type(getASTContext(), element_qual_type);
+ CompilerType element_clang_type(this, element_qual_type.getAsOpaquePtr());
lldb::Format element_format = element_clang_type.GetFormat();
for (element_idx = 0; element_idx < element_count; ++element_idx) {
@@ -9380,7 +9273,7 @@ void ClangASTContext::DumpValue(
->getDecl()
->getUnderlyingType();
- CompilerType typedef_clang_type(getASTContext(), typedef_qual_type);
+ CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
lldb::Format typedef_format = typedef_clang_type.GetFormat();
clang::TypeInfo typedef_type_info =
getASTContext()->getTypeInfo(typedef_qual_type);
@@ -9405,7 +9298,8 @@ void ClangASTContext::DumpValue(
case clang::Type::Auto: {
clang::QualType elaborated_qual_type =
llvm::cast<clang::AutoType>(qual_type)->getDeducedType();
- CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
+ CompilerType elaborated_clang_type(this,
+ elaborated_qual_type.getAsOpaquePtr());
lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
clang::TypeInfo elaborated_type_info =
getASTContext()->getTypeInfo(elaborated_qual_type);
@@ -9430,7 +9324,8 @@ void ClangASTContext::DumpValue(
case clang::Type::Elaborated: {
clang::QualType elaborated_qual_type =
llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
- CompilerType elaborated_clang_type(getASTContext(), elaborated_qual_type);
+ CompilerType elaborated_clang_type(this,
+ elaborated_qual_type.getAsOpaquePtr());
lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
clang::TypeInfo elaborated_type_info =
getASTContext()->getTypeInfo(elaborated_qual_type);
@@ -9455,7 +9350,7 @@ void ClangASTContext::DumpValue(
case clang::Type::Paren: {
clang::QualType desugar_qual_type =
llvm::cast<clang::ParenType>(qual_type)->desugar();
- CompilerType desugar_clang_type(getASTContext(), desugar_qual_type);
+ CompilerType desugar_clang_type(this, desugar_qual_type.getAsOpaquePtr());
lldb::Format desugar_format = desugar_clang_type.GetFormat();
clang::TypeInfo desugar_type_info =
@@ -9490,6 +9385,86 @@ void ClangASTContext::DumpValue(
}
}
+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 enumrator 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 ClangASTContext::DumpTypeValue(
lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
@@ -9503,13 +9478,20 @@ bool ClangASTContext::DumpTypeValue(
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(getASTContext(), typedef_qual_type);
+ CompilerType typedef_clang_type(this, typedef_qual_type.getAsOpaquePtr());
if (format == eFormatDefault)
format = typedef_clang_type.GetFormat();
clang::TypeInfo typedef_type_info =
@@ -9533,45 +9515,9 @@ bool ClangASTContext::DumpTypeValue(
// 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)) {
- 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;
- const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
- lldb::offset_t offset = byte_offset;
- if (is_signed) {
- const int64_t enum_svalue = data.GetMaxS64Bitfield(
- &offset, 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().getSExtValue() == enum_svalue) {
- s->PutCString(enum_pos->getNameAsString());
- return true;
- }
- }
- // 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_svalue);
- } else {
- const uint64_t enum_uvalue = data.GetMaxU64Bitfield(
- &offset, 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().getZExtValue() == enum_uvalue) {
- s->PutCString(enum_pos->getNameAsString());
- return true;
- }
- }
- // If we have gotten here we didn't get find the enumerator in the
- // enum decl, so just print the integer.
- s->Printf("%" PRIu64, enum_uvalue);
- }
- return true;
- }
+ 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;
@@ -9739,20 +9685,23 @@ void ClangASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
} break;
case clang::Type::Auto:
- CompilerType(getASTContext(),
- llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ CompilerType(this, llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr())
.DumpTypeDescription(s);
return;
case clang::Type::Elaborated:
- CompilerType(getASTContext(),
- llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ CompilerType(this, llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr())
.DumpTypeDescription(s);
return;
case clang::Type::Paren:
- CompilerType(getASTContext(),
- llvm::cast<clang::ParenType>(qual_type)->desugar())
+ CompilerType(
+ this,
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())
.DumpTypeDescription(s);
return;
@@ -10348,9 +10297,9 @@ ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) {
return nullptr;
}
-ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target)
- : ClangASTContext(target.GetArchitecture().GetTriple().getTriple().c_str()),
- m_target_wp(target.shared_from_this()),
+ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target,
+ ArchSpec arch)
+ : ClangASTContext(arch), m_target_wp(target.shared_from_this()),
m_persistent_variables(new ClangPersistentVariables) {}
UserExpression *ClangASTContextForExpressions::GetUserExpression(
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 32d0c47693b0..92d51f79a007 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -30,28 +30,28 @@ ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0};
void ClangASTMetrics::DumpCounters(Log *log,
ClangASTMetrics::Counters &counters) {
- log->Printf(" Number of visible Decl queries by name : %" PRIu64,
- counters.m_visible_query_count);
- log->Printf(" Number of lexical Decl queries : %" PRIu64,
- counters.m_lexical_query_count);
- log->Printf(" Number of imports initiated by LLDB : %" PRIu64,
- counters.m_lldb_import_count);
- log->Printf(" Number of imports conducted by Clang : %" PRIu64,
- counters.m_clang_import_count);
- log->Printf(" Number of Decls completed : %" PRIu64,
- counters.m_decls_completed_count);
- log->Printf(" Number of records laid out : %" PRIu64,
- counters.m_record_layout_count);
+ LLDB_LOGF(log, " Number of visible Decl queries by name : %" PRIu64,
+ counters.m_visible_query_count);
+ LLDB_LOGF(log, " Number of lexical Decl queries : %" PRIu64,
+ counters.m_lexical_query_count);
+ LLDB_LOGF(log, " Number of imports initiated by LLDB : %" PRIu64,
+ counters.m_lldb_import_count);
+ LLDB_LOGF(log, " Number of imports conducted by Clang : %" PRIu64,
+ counters.m_clang_import_count);
+ LLDB_LOGF(log, " Number of Decls completed : %" PRIu64,
+ counters.m_decls_completed_count);
+ LLDB_LOGF(log, " Number of records laid out : %" PRIu64,
+ counters.m_record_layout_count);
}
void ClangASTMetrics::DumpCounters(Log *log) {
if (!log)
return;
- log->Printf("== ClangASTMetrics output ==");
- log->Printf("-- Global metrics --");
+ LLDB_LOGF(log, "== ClangASTMetrics output ==");
+ LLDB_LOGF(log, "-- Global metrics --");
DumpCounters(log, global_counters);
- log->Printf("-- Local metrics --");
+ LLDB_LOGF(log, "-- Local metrics --");
DumpCounters(log, local_counters);
}
@@ -127,14 +127,16 @@ clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
user_id = metadata->GetUserID();
if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s "
- "'%s', metadata 0x%" PRIx64,
- decl->getDeclKindName(),
- named_decl->getNameAsString().c_str(), user_id);
+ LLDB_LOGF(log,
+ " [ClangASTImporter] WARNING: Failed to import a %s "
+ "'%s', metadata 0x%" PRIx64,
+ decl->getDeclKindName(),
+ named_decl->getNameAsString().c_str(), user_id);
else
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, "
- "metadata 0x%" PRIx64,
- decl->getDeclKindName(), user_id);
+ LLDB_LOGF(log,
+ " [ClangASTImporter] WARNING: Failed to import a %s, "
+ "metadata 0x%" PRIx64,
+ decl->getDeclKindName(), user_id);
}
return nullptr;
}
@@ -211,12 +213,12 @@ private:
if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf(" [ClangASTImporter] DeclContextOverride couldn't "
- "override (%sDecl*)%p - its child (%sDecl*)%p escapes",
- decl->getDeclKindName(), static_cast<void *>(decl),
- escaped_child->getDeclKindName(),
- static_cast<void *>(escaped_child));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] DeclContextOverride couldn't "
+ "override (%sDecl*)%p - its child (%sDecl*)%p escapes",
+ decl->getDeclKindName(), static_cast<void *>(decl),
+ escaped_child->getDeclKindName(),
+ static_cast<void *>(escaped_child));
lldbassert(0 && "Couldn't override!");
}
@@ -248,40 +250,117 @@ public:
}
};
-lldb::opaque_compiler_type_t
-ClangASTImporter::DeportType(clang::ASTContext *dst_ctx,
- clang::ASTContext *src_ctx,
- lldb::opaque_compiler_type_t type) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+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;
+ // FIXME: Investigate how many decls we usually have in these sets and
+ // see if we can use SmallPtrSet instead here.
+ std::set<NamedDecl *> m_decls_to_complete;
+ std::set<NamedDecl *> m_decls_already_completed;
+ clang::ASTContext *m_dst_ctx;
+ clang::ASTContext *m_src_ctx;
+ ClangASTImporter &importer;
- if (log)
- log->Printf(" [ClangASTImporter] DeportType called on (%sType*)0x%llx "
- "from (ASTContext*)%p to (ASTContext*)%p",
- QualType::getFromOpaquePtr(type)->getTypeClassName(),
- (unsigned long long)type, static_cast<void *>(src_ctx),
- static_cast<void *>(dst_ctx));
+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);
+ }
- ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx));
+ virtual ~CompleteTagDeclsScope() {
+ ClangASTImporter::ASTContextMetadataSP to_context_md =
+ importer.GetContextMetadata(m_dst_ctx);
- if (!delegate_sp)
- return nullptr;
+ // Complete all decls we collected until now.
+ while (!m_decls_to_complete.empty()) {
+ NamedDecl *decl = *m_decls_to_complete.begin();
- std::set<NamedDecl *> decls_to_deport;
- std::set<NamedDecl *> decls_already_deported;
+ m_decls_already_completed.insert(decl);
+ m_decls_to_complete.erase(decl);
- DeclContextOverride decl_context_override;
+ // 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.
+ ClangASTContext::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);
+ }
- if (const clang::TagType *tag_type =
- clang::QualType::getFromOpaquePtr(type)->getAs<TagType>()) {
- decl_context_override.OverrideAllDeclsFromContainingFunction(
- tag_type->getDecl());
+ 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();
}
- delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);
+ 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.insert(to_named_decl);
+ }
+};
+} // namespace
+
+lldb::opaque_compiler_type_t
+ClangASTImporter::DeportType(clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ lldb::opaque_compiler_type_t type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOGF(log,
+ " [ClangASTImporter] DeportType called on (%sType*)0x%llx "
+ "from (ASTContext*)%p to (ASTContext*)%p",
+ QualType::getFromOpaquePtr(type)->getTypeClassName(),
+ (unsigned long long)type, static_cast<void *>(src_ctx),
+ static_cast<void *>(dst_ctx));
+
+ DeclContextOverride decl_context_override;
- lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type);
+ if (auto *t = QualType::getFromOpaquePtr(type)->getAs<TagType>())
+ decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl());
- delegate_sp->ExecuteDeportWorkQueues();
+ lldb::opaque_compiler_type_t result;
+ {
+ CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
+ result = CopyType(dst_ctx, src_ctx, type);
+ }
if (!result)
return nullptr;
@@ -294,38 +373,30 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
clang::Decl *decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from "
- "(ASTContext*)%p to (ASTContext*)%p",
- decl->getDeclKindName(), static_cast<void *>(decl),
- static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx));
-
- ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx));
-
- if (!delegate_sp)
- return nullptr;
-
- std::set<NamedDecl *> decls_to_deport;
- std::set<NamedDecl *> decls_already_deported;
+ LLDB_LOGF(log,
+ " [ClangASTImporter] DeportDecl called on (%sDecl*)%p from "
+ "(ASTContext*)%p to (ASTContext*)%p",
+ decl->getDeclKindName(), static_cast<void *>(decl),
+ static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx));
DeclContextOverride decl_context_override;
decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
- delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported);
-
- clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
-
- delegate_sp->ExecuteDeportWorkQueues();
+ clang::Decl *result;
+ {
+ CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
+ result = CopyDecl(dst_ctx, src_ctx, decl);
+ }
if (!result)
return nullptr;
- if (log)
- log->Printf(
- " [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
- decl->getDeclKindName(), static_cast<void *>(decl),
- result->getDeclKindName(), static_cast<void *>(result));
+ LLDB_LOGF(
+ log,
+ " [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
+ decl->getDeclKindName(), static_cast<void *>(decl),
+ result->getDeclKindName(), static_cast<void *>(result));
return result;
}
@@ -533,9 +604,8 @@ void ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl,
void ClangASTImporter::CompleteDecl(clang::Decl *decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
- decl->getDeclKindName(), static_cast<void *>(decl));
+ LLDB_LOGF(log, " [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
+ decl->getDeclKindName(), static_cast<void *>(decl));
if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) {
if (!interface_decl->getDefinition()) {
@@ -817,9 +887,9 @@ void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf(" [ClangASTImporter] Forgetting destination (ASTContext*)%p",
- static_cast<void *>(dst_ast));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Forgetting destination (ASTContext*)%p",
+ static_cast<void *>(dst_ast));
m_metadata_map.erase(dst_ast);
}
@@ -830,10 +900,10 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- log->Printf(" [ClangASTImporter] Forgetting source->dest "
- "(ASTContext*)%p->(ASTContext*)%p",
- static_cast<void *>(src_ast), static_cast<void *>(dst_ast));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Forgetting source->dest "
+ "(ASTContext*)%p->(ASTContext*)%p",
+ static_cast<void *>(src_ast), static_cast<void *>(dst_ast));
if (!md)
return;
@@ -869,63 +939,6 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
return ASTImporter::ImportImpl(From);
}
-void ClangASTImporter::ASTImporterDelegate::InitDeportWorkQueues(
- std::set<clang::NamedDecl *> *decls_to_deport,
- std::set<clang::NamedDecl *> *decls_already_deported) {
- assert(!m_decls_to_deport);
- assert(!m_decls_already_deported);
-
- m_decls_to_deport = decls_to_deport;
- m_decls_already_deported = decls_already_deported;
-}
-
-void ClangASTImporter::ASTImporterDelegate::ExecuteDeportWorkQueues() {
- assert(m_decls_to_deport);
- assert(m_decls_already_deported);
-
- ASTContextMetadataSP to_context_md =
- m_master.GetContextMetadata(&getToContext());
-
- while (!m_decls_to_deport->empty()) {
- NamedDecl *decl = *m_decls_to_deport->begin();
-
- m_decls_already_deported->insert(decl);
- m_decls_to_deport->erase(decl);
-
- DeclOrigin &origin = to_context_md->m_origins[decl];
- UNUSED_IF_ASSERT_DISABLED(origin);
-
- assert(origin.ctx ==
- m_source_ctx); // otherwise we should never have added this
- // because it doesn't need to be deported
-
- Decl *original_decl = to_context_md->m_origins[decl].decl;
-
- ClangASTContext::GetCompleteDecl(m_source_ctx, original_decl);
-
- if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
- if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
- if (original_tag_decl->isCompleteDefinition()) {
- ImportDefinitionTo(tag_decl, original_tag_decl);
- tag_decl->setCompleteDefinition(true);
- }
- }
-
- tag_decl->setHasExternalLexicalStorage(false);
- tag_decl->setHasExternalVisibleStorage(false);
- } else if (ObjCContainerDecl *container_decl =
- dyn_cast<ObjCContainerDecl>(decl)) {
- container_decl->setHasExternalLexicalStorage(false);
- container_decl->setHasExternalVisibleStorage(false);
- }
-
- to_context_md->m_origins.erase(decl);
- }
-
- m_decls_to_deport = nullptr;
- m_decls_already_deported = nullptr;
-}
-
void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
clang::Decl *to, clang::Decl *from) {
ASTImporter::Imported(from, to);
@@ -1045,15 +1058,17 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
from_named_decl->printName(name_stream);
name_stream.flush();
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
- "(Decl*)%p), metadata 0x%" PRIx64,
- from->getDeclKindName(), static_cast<void *>(to),
- name_string.c_str(), static_cast<void *>(from), user_id);
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
+ "(Decl*)%p), metadata 0x%" PRIx64,
+ from->getDeclKindName(), static_cast<void *>(to),
+ name_string.c_str(), static_cast<void *>(from), user_id);
} else {
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from "
- "(Decl*)%p), metadata 0x%" PRIx64,
- from->getDeclKindName(), static_cast<void *>(to),
- static_cast<void *>(from), user_id);
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Imported (%sDecl*)%p (from "
+ "(Decl*)%p), metadata 0x%" PRIx64,
+ from->getDeclKindName(), static_cast<void *>(to),
+ static_cast<void *>(from), user_id);
}
}
@@ -1080,37 +1095,27 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
if (direct_completer.get() != this)
direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
- if (log)
- log->Printf(" [ClangASTImporter] Propagated origin "
- "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
- "(ASTContext*)%p",
- static_cast<void *>(origin_iter->second.decl),
- static_cast<void *>(origin_iter->second.ctx),
- static_cast<void *>(&from->getASTContext()),
- static_cast<void *>(&to->getASTContext()));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Propagated origin "
+ "(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
+ "(ASTContext*)%p",
+ static_cast<void *>(origin_iter->second.decl),
+ static_cast<void *>(origin_iter->second.ctx),
+ static_cast<void *>(&from->getASTContext()),
+ static_cast<void *>(&to->getASTContext()));
} else {
- if (m_decls_to_deport && m_decls_already_deported) {
- if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to)) {
- RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
- if (from_record_decl == nullptr ||
- !from_record_decl->isInjectedClassName()) {
- NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
-
- if (!m_decls_already_deported->count(to_named_decl))
- m_decls_to_deport->insert(to_named_decl);
- }
- }
- }
+ 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);
}
- if (log)
- log->Printf(" [ClangASTImporter] Decl has no origin information in "
- "(ASTContext*)%p",
- static_cast<void *>(&from->getASTContext()));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Decl has no origin information in "
+ "(ASTContext*)%p",
+ static_cast<void *>(&from->getASTContext()));
}
if (clang::NamespaceDecl *to_namespace =
@@ -1130,11 +1135,11 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
} else {
to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
- if (log)
- log->Printf(" [ClangASTImporter] Sourced origin "
- "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
- static_cast<void *>(from), static_cast<void *>(m_source_ctx),
- static_cast<void *>(&to->getASTContext()));
+ LLDB_LOGF(log,
+ " [ClangASTImporter] Sourced origin "
+ "(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
+ static_cast<void *>(from), static_cast<void *>(m_source_ctx),
+ static_cast<void *>(&to->getASTContext()));
}
if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) {
@@ -1143,13 +1148,13 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
to_tag_decl->setHasExternalLexicalStorage();
to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();
- if (log)
- log->Printf(
- " [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
- (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
- (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
- (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
- (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
+ LLDB_LOGF(
+ log,
+ " [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
+ (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
+ (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
}
if (isa<NamespaceDecl>(from)) {
@@ -1171,15 +1176,16 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
if (log) {
if (ObjCInterfaceDecl *to_interface_decl =
llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
- log->Printf(
+ LLDB_LOGF(
+ log,
" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
"%s%s%s",
(to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
(to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
(to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
} else {
- log->Printf(
- " [ClangASTImporter] To is an %sDecl - attributes %s%s",
+ LLDB_LOGF(
+ log, " [ClangASTImporter] To is an %sDecl - attributes %s%s",
((Decl *)to_container_decl)->getDeclKindName(),
(to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
(to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index 3a2a4d3a09e6..3eee7f785f36 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -190,8 +190,8 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr,
Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments,
Address::DumpStyle::DumpStyleFileAddress,
arch.GetAddressByteSize());
- log->Printf("Got compact unwind encoding 0x%x for function %s",
- function_info.encoding, strm.GetData());
+ LLDB_LOGF(log, "Got compact unwind encoding 0x%x for function %s",
+ function_info.encoding, strm.GetData());
}
if (function_info.valid_range_offset_start != 0 &&
@@ -213,7 +213,8 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr,
return CreateUnwindPlan_x86_64(target, function_info, unwind_plan,
addr);
}
- if (arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
return CreateUnwindPlan_arm64(target, function_info, unwind_plan, addr);
}
if (arch.GetTriple().getArch() == llvm::Triple::x86) {
@@ -737,6 +738,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1008,6 +1010,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target,
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1304,6 +1307,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_arm64(Target &target,
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
@@ -1437,6 +1441,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_armv7(Target &target,
unwind_plan.SetSourceName("compact unwind info");
unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
unwind_plan.SetLSDAAddress(function_info.lsda_address);
diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp
index 5fb9b6b9f729..41086d2df3df 100644
--- a/source/Symbol/CompileUnit.cpp
+++ b/source/Symbol/CompileUnit.cpp
@@ -9,7 +9,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/LineTable.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Language.h"
@@ -119,49 +119,6 @@ void CompileUnit::AddFunction(FunctionSP &funcSP) {
m_functions_by_uid[funcSP->GetID()] = funcSP;
}
-// Find functions using the Mangled::Tokens token list. This function currently
-// implements an interactive approach designed to find all instances of certain
-// functions. It isn't designed to the quickest way to lookup functions as it
-// will need to iterate through all functions and see if they match, though it
-// does provide a powerful and context sensitive way to search for all
-// functions with a certain name, all functions in a namespace, or all
-// functions of a template type. See Mangled::Tokens::Parse() comments for more
-// information.
-//
-// The function prototype will need to change to return a list of results. It
-// was originally used to help debug the Mangled class and the
-// Mangled::Tokens::MatchesQuery() function and it currently will print out a
-// list of matching results for the functions that are currently in this
-// compile unit.
-//
-// A FindFunctions method should be called prior to this that takes
-// a regular function name (const char * or ConstString as a parameter) before
-// resorting to this slower but more complete function. The other FindFunctions
-// method should be able to take advantage of any accelerator tables available
-// in the debug information (which is parsed by the SymbolFile parser plug-ins
-// and registered with each Module).
-// void
-// CompileUnit::FindFunctions(const Mangled::Tokens& tokens)
-//{
-// if (!m_functions.empty())
-// {
-// Stream s(stdout);
-// std::vector<FunctionSP>::const_iterator pos;
-// std::vector<FunctionSP>::const_iterator end = m_functions.end();
-// for (pos = m_functions.begin(); pos != end; ++pos)
-// {
-// const ConstString& demangled = (*pos)->Mangled().Demangled();
-// if (demangled)
-// {
-// const Mangled::Tokens& func_tokens =
-// (*pos)->Mangled().GetTokens();
-// if (func_tokens.MatchesQuery (tokens))
-// s << "demangled MATCH found: " << demangled << "\n";
-// }
-// }
-// }
-//}
-
FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t func_uid) {
auto it = m_functions_by_uid.find(func_uid);
if (it == m_functions_by_uid.end())
@@ -173,10 +130,8 @@ lldb::LanguageType CompileUnit::GetLanguage() {
if (m_language == eLanguageTypeUnknown) {
if (m_flags.IsClear(flagsParsedLanguage)) {
m_flags.Set(flagsParsedLanguage);
- SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
- if (symbol_vendor) {
- m_language = symbol_vendor->ParseLanguage(*this);
- }
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+ m_language = symfile->ParseLanguage(*this);
}
}
return m_language;
@@ -186,9 +141,8 @@ LineTable *CompileUnit::GetLineTable() {
if (m_line_table_up == nullptr) {
if (m_flags.IsClear(flagsParsedLineTable)) {
m_flags.Set(flagsParsedLineTable);
- SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
- if (symbol_vendor)
- symbol_vendor->ParseLineTable(*this);
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+ symfile->ParseLineTable(*this);
}
}
return m_line_table_up.get();
@@ -202,14 +156,16 @@ void CompileUnit::SetLineTable(LineTable *line_table) {
m_line_table_up.reset(line_table);
}
+void CompileUnit::SetSupportFiles(const FileSpecList &support_files) {
+ m_support_files = support_files;
+}
+
DebugMacros *CompileUnit::GetDebugMacros() {
if (m_debug_macros_sp.get() == nullptr) {
if (m_flags.IsClear(flagsParsedDebugMacros)) {
m_flags.Set(flagsParsedDebugMacros);
- SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
- if (symbol_vendor) {
- symbol_vendor->ParseDebugMacros(*this);
- }
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+ symfile->ParseDebugMacros(*this);
}
}
@@ -229,7 +185,7 @@ VariableListSP CompileUnit::GetVariableList(bool can_create) {
SymbolContext sc;
CalculateSymbolContext(&sc);
assert(sc.module_sp);
- sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+ sc.module_sp->GetSymbolFile()->ParseVariablesForContext(sc);
}
return m_variables;
@@ -372,8 +328,8 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
bool CompileUnit::GetIsOptimized() {
if (m_is_optimized == eLazyBoolCalculate) {
m_is_optimized = eLazyBoolNo;
- if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
- if (symbol_vendor->ParseIsOptimized(*this))
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile()) {
+ if (symfile->ParseIsOptimized(*this))
m_is_optimized = eLazyBoolYes;
}
}
@@ -388,23 +344,26 @@ const std::vector<SourceModule> &CompileUnit::GetImportedModules() {
if (m_imported_modules.empty() &&
m_flags.IsClear(flagsParsedImportedModules)) {
m_flags.Set(flagsParsedImportedModules);
- if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) {
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile()) {
SymbolContext sc;
CalculateSymbolContext(&sc);
- symbol_vendor->ParseImportedModules(sc, m_imported_modules);
+ symfile->ParseImportedModules(sc, m_imported_modules);
}
}
return m_imported_modules;
}
+void CompileUnit::ForEachExternalModule(llvm::function_ref<void(ModuleSP)> f) {
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+ symfile->ForEachExternalModule(*this, f);
+}
+
const FileSpecList &CompileUnit::GetSupportFiles() {
if (m_support_files.GetSize() == 0) {
if (m_flags.IsClear(flagsParsedSupportFiles)) {
m_flags.Set(flagsParsedSupportFiles);
- SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor();
- if (symbol_vendor) {
- symbol_vendor->ParseSupportFiles(*this, m_support_files);
- }
+ if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+ symfile->ParseSupportFiles(*this, m_support_files);
}
}
return m_support_files;
diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp
index bb9a1a642e42..571a8570a43b 100644
--- a/source/Symbol/CompilerType.cpp
+++ b/source/Symbol/CompilerType.cpp
@@ -10,8 +10,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -32,13 +30,6 @@ CompilerType::CompilerType(TypeSystem *type_system,
lldb::opaque_compiler_type_t type)
: m_type(type), m_type_system(type_system) {}
-CompilerType::CompilerType(clang::ASTContext *ast, clang::QualType qual_type)
- : m_type(qual_type.getAsOpaquePtr()),
- m_type_system(ClangASTContext::GetASTContext(ast)) {
- if (m_type)
- assert(m_type_system != nullptr);
-}
-
CompilerType::~CompilerType() {}
// Tests
@@ -333,12 +324,6 @@ void CompilerType::SetCompilerType(TypeSystem *type_system,
m_type = type;
}
-void CompilerType::SetCompilerType(clang::ASTContext *ast,
- clang::QualType qual_type) {
- m_type_system = ClangASTContext::GetASTContext(ast);
- m_type = qual_type.getAsOpaquePtr();
-}
-
unsigned CompilerType::GetTypeQualifiers() const {
if (IsValid())
return m_type_system->GetTypeQualifiers(m_type);
@@ -503,10 +488,10 @@ CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
return {};
}
-size_t CompilerType::GetTypeBitAlign() const {
+llvm::Optional<size_t> CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
if (IsValid())
- return m_type_system->GetTypeBitAlign(m_type);
- return 0;
+ return m_type_system->GetTypeBitAlign(m_type, exe_scope);
+ return {};
}
lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
@@ -729,13 +714,6 @@ CompilerType::GetIndexOfChildWithName(const char *name,
return UINT32_MAX;
}
-size_t CompilerType::ConvertStringToFloatValue(const char *s, uint8_t *dst,
- size_t dst_size) const {
- if (IsValid())
- return m_type_system->ConvertStringToFloatValue(m_type, s, dst, dst_size);
- return 0;
-}
-
// Dumping types
#define DEPTH_INCREMENT 2
diff --git a/source/Symbol/CxxModuleHandler.cpp b/source/Symbol/CxxModuleHandler.cpp
index 68a2aab80bd6..19e80e5036bc 100644
--- a/source/Symbol/CxxModuleHandler.cpp
+++ b/source/Symbol/CxxModuleHandler.cpp
@@ -175,6 +175,8 @@ T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) {
}
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)
@@ -196,9 +198,15 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
// Find the local DeclContext that corresponds to the DeclContext of our
// decl we want to import.
- auto to_context = getEqualLocalDeclContext(*m_sema, td->getDeclContext());
- if (!to_context)
+ 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 =
@@ -215,8 +223,6 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
// Import the foreign template arguments.
llvm::SmallVector<TemplateArgument, 4> imported_args;
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
-
// If this logic is changed, also update templateArgsAreSupported.
for (const TemplateArgument &arg : foreign_args.asArray()) {
switch (arg.getKind()) {
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index 0ab9fa4b7bbd..b4e74e9a2898 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -19,6 +19,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include <list>
+#include <cstring>
using namespace lldb;
using namespace lldb_private;
@@ -601,6 +602,9 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
}
offset += aug_data_len;
}
+ unwind_plan.SetUnwindPlanForSignalTrap(
+ strchr(cie->augmentation, 'S') ? eLazyBoolYes : eLazyBoolNo);
+
Address lsda_data;
Address personality_function_ptr;
@@ -769,13 +773,12 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
// useful for compilers that move epilogue code into the body of a
// function.)
if (stack.empty()) {
- if (log)
- log->Printf("DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32
- ", startaddr: %" PRIx64
- " encountered DW_CFA_restore_state but state stack "
- "is empty. Corrupt unwind info?",
- __FUNCTION__, dwarf_offset,
- startaddr.GetFileAddress());
+ LLDB_LOGF(log,
+ "DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32
+ ", startaddr: %" PRIx64
+ " encountered DW_CFA_restore_state but state stack "
+ "is empty. Corrupt unwind info?",
+ __FUNCTION__, dwarf_offset, startaddr.GetFileAddress());
break;
}
lldb::addr_t offset = row->GetOffset();
diff --git a/source/Symbol/DeclVendor.cpp b/source/Symbol/DeclVendor.cpp
index 0a912a2fd214..9ccf422e3bea 100644
--- a/source/Symbol/DeclVendor.cpp
+++ b/source/Symbol/DeclVendor.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/DeclVendor.h"
-
-#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/TypeSystem.h"
#include <vector>
@@ -20,10 +20,11 @@ std::vector<CompilerType> DeclVendor::FindTypes(ConstString name,
// FIXME: This depends on clang, but should be able to support any
// TypeSystem.
std::vector<CompilerType> ret;
- std::vector<clang::NamedDecl *> decls;
+ std::vector<CompilerDecl> decls;
if (FindDecls(name, /*append*/ true, max_matches, decls))
- for (auto *decl : decls)
- if (auto type = ClangASTContext::GetTypeForDecl(decl))
+ for (auto decl : decls)
+ if (auto type =
+ decl.GetTypeSystem()->GetTypeForDecl(decl.GetOpaqueDecl()))
ret.push_back(type);
return ret;
}
diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp
index 09cb9b00aaf3..f609bf7821e1 100644
--- a/source/Symbol/FuncUnwinders.cpp
+++ b/source/Symbol/FuncUnwinders.cpp
@@ -10,6 +10,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
+#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -58,6 +59,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target,
Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (UnwindPlanSP plan_sp = GetObjectFileUnwindPlan(target))
+ return plan_sp;
if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
return plan_sp;
if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target))
@@ -97,6 +100,26 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
return UnwindPlanSP();
}
+lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_unwind_plan_object_file_sp.get() ||
+ m_tried_unwind_plan_object_file)
+ return m_unwind_plan_object_file_sp;
+
+ m_tried_unwind_plan_object_file = true;
+ if (m_range.GetBaseAddress().IsValid()) {
+ CallFrameInfo *object_file_frame = m_unwind_table.GetObjectFileUnwindInfo();
+ if (object_file_frame) {
+ m_unwind_plan_object_file_sp =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (!object_file_frame->GetUnwindPlan(m_range,
+ *m_unwind_plan_object_file_sp))
+ m_unwind_plan_object_file_sp.reset();
+ }
+ }
+ return m_unwind_plan_object_file_sp;
+}
+
UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
@@ -185,6 +208,38 @@ UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
return m_unwind_plan_symbol_file_sp;
}
+UnwindPlanSP
+FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target,
+ Thread &thread) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_unwind_plan_object_file_augmented_sp.get() ||
+ m_tried_unwind_plan_object_file_augmented)
+ return m_unwind_plan_object_file_augmented_sp;
+
+ m_tried_unwind_plan_object_file_augmented = true;
+
+ UnwindPlanSP object_file_unwind_plan = GetObjectFileUnwindPlan(target);
+ if (!object_file_unwind_plan)
+ return m_unwind_plan_object_file_augmented_sp;
+
+ m_unwind_plan_object_file_augmented_sp =
+ std::make_shared<UnwindPlan>(*object_file_unwind_plan);
+
+ // Augment the instructions with epilogue descriptions if necessary
+ // so the UnwindPlan can be used at any instruction in the function.
+
+ UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
+ if (assembly_profiler_sp) {
+ if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
+ m_range, thread, *m_unwind_plan_object_file_augmented_sp)) {
+ m_unwind_plan_object_file_augmented_sp.reset();
+ }
+ } else {
+ m_unwind_plan_object_file_augmented_sp.reset();
+ }
+ return m_unwind_plan_object_file_augmented_sp;
+}
+
UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -328,6 +383,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target);
if (!eh_frame_sp)
eh_frame_sp = GetDebugFrameUnwindPlan(target);
+ if (!eh_frame_sp)
+ eh_frame_sp = GetObjectFileUnwindPlan(target);
UnwindPlanSP arch_default_at_entry_sp =
GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread);
UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread);
@@ -366,6 +423,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
return plan_sp;
if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread))
return plan_sp;
+ if (UnwindPlanSP plan_sp = GetObjectFileAugmentedUnwindPlan(target, thread))
+ return plan_sp;
return assembly_sp;
}
@@ -473,6 +532,9 @@ Address FuncUnwinders::GetLSDAAddress(Target &target) {
if (unwind_plan_sp.get() == nullptr) {
unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
}
+ if (unwind_plan_sp.get() == nullptr) {
+ unwind_plan_sp = GetObjectFileUnwindPlan(target);
+ }
if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) {
lsda_addr = unwind_plan_sp->GetLSDAAddress();
}
@@ -486,6 +548,9 @@ Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) {
if (unwind_plan_sp.get() == nullptr) {
unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
}
+ if (unwind_plan_sp.get() == nullptr) {
+ unwind_plan_sp = GetObjectFileUnwindPlan(target);
+ }
if (unwind_plan_sp.get() &&
unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) {
personality_addr = unwind_plan_sp->GetPersonalityFunctionPtr();
diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp
index 951392c1f1bf..a4c2d3b4b44a 100644
--- a/source/Symbol/Function.cpp
+++ b/source/Symbol/Function.cpp
@@ -16,7 +16,6 @@
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/Log.h"
#include "llvm/Support/Casting.h"
@@ -60,10 +59,11 @@ size_t FunctionInfo::MemorySize() const {
return m_name.MemorySize() + m_declaration.MemorySize();
}
-InlineFunctionInfo::InlineFunctionInfo(const char *name, const char *mangled,
+InlineFunctionInfo::InlineFunctionInfo(const char *name,
+ llvm::StringRef mangled,
const Declaration *decl_ptr,
const Declaration *call_decl_ptr)
- : FunctionInfo(name, decl_ptr), m_mangled(ConstString(mangled), true),
+ : FunctionInfo(name, decl_ptr), m_mangled(mangled),
m_call_decl(call_decl_ptr) {}
InlineFunctionInfo::InlineFunctionInfo(ConstString name,
@@ -128,11 +128,16 @@ size_t InlineFunctionInfo::MemorySize() const {
}
//
-CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc)
- : return_pc(return_pc), resolved(false) {
+CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc,
+ CallSiteParameterArray parameters)
+ : return_pc(return_pc), parameters(std::move(parameters)), resolved(false) {
lazy_callee.symbol_name = symbol_name;
}
+llvm::ArrayRef<CallSiteParameter> CallEdge::GetCallSiteParameters() const {
+ return parameters;
+}
+
void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) {
if (resolved)
return;
@@ -144,8 +149,8 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) {
auto resolve_lazy_callee = [&]() -> Function * {
ConstString callee_name{lazy_callee.symbol_name};
SymbolContextList sc_list;
- size_t num_matches =
- images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list);
+ images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list);
+ size_t num_matches = sc_list.GetSize();
if (num_matches == 0 || !sc_list[0].symbol) {
LLDB_LOG(log, "CallEdge: Found no symbols for {0}, cannot resolve it",
callee_name);
@@ -169,6 +174,7 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) {
Function *CallEdge::GetCallee(ModuleList &images) {
ParseSymbolFileAndResolve(images);
+ assert(resolved && "Did not resolve lazy callee");
return lazy_callee.def;
}
@@ -277,11 +283,25 @@ llvm::MutableArrayRef<CallEdge> Function::GetTailCallingEdges() {
});
}
+CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc,
+ Target &target) {
+ auto edges = GetCallEdges();
+ auto edge_it =
+ std::lower_bound(edges.begin(), edges.end(), return_pc,
+ [&](const CallEdge &edge, addr_t pc) {
+ return edge.GetReturnPCAddress(*this, target) < pc;
+ });
+ if (edge_it == edges.end() ||
+ edge_it->GetReturnPCAddress(*this, target) != return_pc)
+ return nullptr;
+ return &const_cast<CallEdge &>(*edge_it);
+}
+
Block &Function::GetBlock(bool can_create) {
if (!m_block.BlockInfoHasBeenParsed() && can_create) {
ModuleSP module_sp = CalculateSymbolContextModule();
if (module_sp) {
- module_sp->GetSymbolVendor()->ParseBlocksRecursive(*this);
+ module_sp->GetSymbolFile()->ParseBlocksRecursive(*this);
} else {
Host::SystemLog(Host::eSystemLogError,
"error: unable to find module "
@@ -428,14 +448,8 @@ CompilerDeclContext Function::GetDeclContext() {
ModuleSP module_sp = CalculateSymbolContextModule();
if (module_sp) {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
-
- if (sym_vendor) {
- SymbolFile *sym_file = sym_vendor->GetSymbolFile();
-
- if (sym_file)
- return sym_file->GetDeclContextForUID(GetID());
- }
+ if (SymbolFile *sym_file = module_sp->GetSymbolFile())
+ return sym_file->GetDeclContextForUID(GetID());
}
return CompilerDeclContext();
}
@@ -449,12 +463,7 @@ Type *Function::GetType() {
if (!sc.module_sp)
return nullptr;
- SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
-
- if (sym_vendor == nullptr)
- return nullptr;
-
- SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+ SymbolFile *sym_file = sc.module_sp->GetSymbolFile();
if (sym_file == nullptr)
return nullptr;
diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp
index 8d4d72c9a2a2..1433dc156d91 100644
--- a/source/Symbol/LineTable.cpp
+++ b/source/Symbol/LineTable.cpp
@@ -241,33 +241,47 @@ bool LineTable::FindLineEntryByAddress(const Address &so_addr,
bool LineTable::ConvertEntryAtIndexToLineEntry(uint32_t idx,
LineEntry &line_entry) {
- if (idx < m_entries.size()) {
- const Entry &entry = m_entries[idx];
- ModuleSP module_sp(m_comp_unit->GetModule());
- if (module_sp &&
- module_sp->ResolveFileAddress(entry.file_addr,
- line_entry.range.GetBaseAddress())) {
- if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
- line_entry.range.SetByteSize(m_entries[idx + 1].file_addr -
- entry.file_addr);
- else
- line_entry.range.SetByteSize(0);
-
- line_entry.file =
- m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
- line_entry.original_file =
- m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
- line_entry.line = entry.line;
- line_entry.column = entry.column;
- line_entry.is_start_of_statement = entry.is_start_of_statement;
- line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
- line_entry.is_prologue_end = entry.is_prologue_end;
- line_entry.is_epilogue_begin = entry.is_epilogue_begin;
- line_entry.is_terminal_entry = entry.is_terminal_entry;
- return true;
- }
- }
- return false;
+ if (idx >= m_entries.size())
+ return false;
+
+ const Entry &entry = m_entries[idx];
+ ModuleSP module_sp(m_comp_unit->GetModule());
+ if (!module_sp)
+ return false;
+
+ addr_t file_addr = entry.file_addr;
+
+ // A terminal entry can point outside of a module or a section. Decrement the
+ // address to ensure it resolves correctly.
+ if (entry.is_terminal_entry)
+ --file_addr;
+
+ if (!module_sp->ResolveFileAddress(file_addr,
+ line_entry.range.GetBaseAddress()))
+ return false;
+
+ // Now undo the decrement above.
+ if (entry.is_terminal_entry)
+ line_entry.range.GetBaseAddress().Slide(1);
+
+ if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ line_entry.range.SetByteSize(m_entries[idx + 1].file_addr -
+ entry.file_addr);
+ else
+ line_entry.range.SetByteSize(0);
+
+ line_entry.file =
+ m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
+ line_entry.original_file =
+ m_comp_unit->GetSupportFiles().GetFileSpecAtIndex(entry.file_idx);
+ line_entry.line = entry.line;
+ line_entry.column = entry.column;
+ line_entry.is_start_of_statement = entry.is_start_of_statement;
+ line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
+ line_entry.is_prologue_end = entry.is_prologue_end;
+ line_entry.is_epilogue_begin = entry.is_epilogue_begin;
+ line_entry.is_terminal_entry = entry.is_terminal_entry;
+ return true;
}
uint32_t LineTable::FindLineEntryIndexByFileIndex(
diff --git a/source/Symbol/LocateSymbolFile.cpp b/source/Symbol/LocateSymbolFile.cpp
index bfdb6e705f4a..0d0e5300668f 100644
--- a/source/Symbol/LocateSymbolFile.cpp
+++ b/source/Symbol/LocateSymbolFile.cpp
@@ -157,8 +157,8 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec,
dsym_fspec)) {
if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- dsym_fspec.GetPath().c_str());
+ LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
}
return true;
} else {
@@ -189,8 +189,8 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs,
dsym_fspec)) {
if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- dsym_fspec.GetPath().c_str());
+ LLDB_LOGF(log, "dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
}
return true;
}
@@ -261,107 +261,110 @@ Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec,
FileSystem::Instance().Exists(symbol_file_spec))
return symbol_file_spec;
- const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
- if (symbol_filename && symbol_filename[0]) {
- FileSpecList debug_file_search_paths = default_search_paths;
+ FileSpecList debug_file_search_paths = default_search_paths;
- // Add module directory.
- FileSpec module_file_spec = module_spec.GetFileSpec();
- // We keep the unresolved pathname if it fails.
- FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
- module_file_spec);
+ // Add module directory.
+ FileSpec module_file_spec = module_spec.GetFileSpec();
+ // We keep the unresolved pathname if it fails.
+ FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
+ module_file_spec);
- ConstString file_dir = module_file_spec.GetDirectory();
+ ConstString file_dir = module_file_spec.GetDirectory();
+ {
+ FileSpec file_spec(file_dir.AsCString("."));
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+ if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+
+ // Add current working directory.
{
- FileSpec file_spec(file_dir.AsCString("."));
+ FileSpec file_spec(".");
FileSystem::Instance().Resolve(file_spec);
debug_file_search_paths.AppendIfUnique(file_spec);
}
- if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
-
- // Add current working directory.
- {
- FileSpec file_spec(".");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
-
#ifndef _WIN32
#if defined(__NetBSD__)
- // Add /usr/libdata/debug directory.
- {
- FileSpec file_spec("/usr/libdata/debug");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
+ // Add /usr/libdata/debug directory.
+ {
+ FileSpec file_spec("/usr/libdata/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
#else
- // Add /usr/lib/debug directory.
- {
- FileSpec file_spec("/usr/lib/debug");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
+ // Add /usr/lib/debug directory.
+ {
+ FileSpec file_spec("/usr/lib/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
#endif
#endif // _WIN32
- }
+ }
- std::string uuid_str;
- const UUID &module_uuid = module_spec.GetUUID();
- if (module_uuid.IsValid()) {
- // Some debug files are stored in the .build-id directory like this:
- // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
- uuid_str = module_uuid.GetAsString("");
- std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
- ::tolower);
- uuid_str.insert(2, 1, '/');
- uuid_str = uuid_str + ".debug";
- }
+ std::string uuid_str;
+ const UUID &module_uuid = module_spec.GetUUID();
+ if (module_uuid.IsValid()) {
+ // Some debug files are stored in the .build-id directory like this:
+ // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
+ uuid_str = module_uuid.GetAsString("");
+ std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+ ::tolower);
+ uuid_str.insert(2, 1, '/');
+ uuid_str = uuid_str + ".debug";
+ }
- size_t num_directories = debug_file_search_paths.GetSize();
- for (size_t idx = 0; idx < num_directories; ++idx) {
- FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
- FileSystem::Instance().Resolve(dirspec);
- if (!FileSystem::Instance().IsDirectory(dirspec))
- continue;
+ size_t num_directories = debug_file_search_paths.GetSize();
+ for (size_t idx = 0; idx < num_directories; ++idx) {
+ FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
+ continue;
- std::vector<std::string> files;
- std::string dirname = dirspec.GetPath();
+ std::vector<std::string> files;
+ std::string dirname = dirspec.GetPath();
- files.push_back(dirname + "/" + symbol_filename);
- files.push_back(dirname + "/.debug/" + symbol_filename);
+ if (!uuid_str.empty())
files.push_back(dirname + "/.build-id/" + uuid_str);
+ if (symbol_file_spec.GetFilename()) {
+ files.push_back(dirname + "/" +
+ symbol_file_spec.GetFilename().GetCString());
+ files.push_back(dirname + "/.debug/" +
+ symbol_file_spec.GetFilename().GetCString());
// Some debug files may stored in the module directory like this:
// /usr/lib/debug/usr/lib/library.so.debug
if (!file_dir.IsEmpty())
- files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);
-
- const uint32_t num_files = files.size();
- for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
- const std::string &filename = files[idx_file];
- FileSpec file_spec(filename);
- FileSystem::Instance().Resolve(file_spec);
-
- if (llvm::sys::fs::equivalent(file_spec.GetPath(),
- module_file_spec.GetPath()))
- continue;
-
- if (FileSystem::Instance().Exists(file_spec)) {
- lldb_private::ModuleSpecList specs;
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
- assert(num_specs <= 1 &&
- "Symbol Vendor supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec mspec;
- if (specs.GetModuleSpecAtIndex(0, mspec)) {
- // Skip the uuids check if module_uuid is invalid. For example,
- // this happens for *.dwp files since at the moment llvm-dwp
- // doesn't output build ids, nor does binutils dwp.
- if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
- return file_spec;
- }
+ files.push_back(dirname + file_dir.AsCString() + "/" +
+ symbol_file_spec.GetFilename().GetCString());
+ }
+
+ const uint32_t num_files = files.size();
+ for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
+ const std::string &filename = files[idx_file];
+ FileSpec file_spec(filename);
+ FileSystem::Instance().Resolve(file_spec);
+
+ if (llvm::sys::fs::equivalent(file_spec.GetPath(),
+ module_file_spec.GetPath()))
+ continue;
+
+ if (FileSystem::Instance().Exists(file_spec)) {
+ lldb_private::ModuleSpecList specs;
+ const size_t num_specs =
+ ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
+ assert(num_specs <= 1 &&
+ "Symbol Vendor supports only a single architecture");
+ if (num_specs == 1) {
+ ModuleSpec mspec;
+ if (specs.GetModuleSpecAtIndex(0, mspec)) {
+ // Skip the uuids check if module_uuid is invalid. For example,
+ // this happens for *.dwp files since at the moment llvm-dwp
+ // doesn't output build ids, nor does binutils dwp.
+ if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
+ return file_spec;
}
}
}
diff --git a/source/Symbol/LocateSymbolFileMacOSX.cpp b/source/Symbol/LocateSymbolFileMacOSX.cpp
index 4e16382d53e7..74718a8c5e30 100644
--- a/source/Symbol/LocateSymbolFileMacOSX.cpp
+++ b/source/Symbol/LocateSymbolFileMacOSX.cpp
@@ -23,7 +23,6 @@
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -33,6 +32,7 @@
#include "lldb/Utility/UUID.h"
#include "mach/machine.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FileSystem.h"
using namespace lldb;
@@ -45,8 +45,7 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
ModuleSpec &return_module_spec) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
- if (log)
- log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
+ LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled.");
return 0;
}
@@ -102,9 +101,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (::CFURLGetFileSystemRepresentation(
dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
if (log) {
- log->Printf("DebugSymbols framework returned dSYM path of %s for "
- "UUID %s -- looking for the dSYM",
- path, uuid->GetAsString().c_str());
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for the dSYM",
+ path, uuid->GetAsString().c_str());
}
FileSpec dsym_filespec(path);
if (path[0] == '~')
@@ -124,9 +124,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (log) {
if (::CFURLGetFileSystemRepresentation(
dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
- log->Printf("DebugSymbols framework returned dSYM path of %s for "
- "UUID %s -- looking for an exec file",
- path, uuid->GetAsString().c_str());
+ LLDB_LOGF(log,
+ "DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for an exec file",
+ path, uuid->GetAsString().c_str());
}
}
@@ -145,8 +146,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
exec_cf_path, path, sizeof(path))) {
if (log) {
- log->Printf("plist bundle has exec path of %s for UUID %s",
- path, uuid->GetAsString().c_str());
+ LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s",
+ path, uuid->GetAsString().c_str());
}
++items_found;
FileSpec exec_filespec(path);
@@ -168,9 +169,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (dsym_extension_pos) {
*dsym_extension_pos = '\0';
if (log) {
- log->Printf("Looking for executable binary next to dSYM "
- "bundle with name with name %s",
- path);
+ LLDB_LOGF(log,
+ "Looking for executable binary next to dSYM "
+ "bundle with name with name %s",
+ path);
}
FileSpec file_spec(path);
FileSystem::Instance().Resolve(file_spec);
@@ -199,9 +201,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
++items_found;
return_module_spec.GetFileSpec() = bundle_exe_file_spec;
if (log) {
- log->Printf("Executable binary %s next to dSYM is "
- "compatible; using",
- path);
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
}
}
}
@@ -228,9 +231,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
++items_found;
return_module_spec.GetFileSpec() = file_spec;
if (log) {
- log->Printf("Executable binary %s next to dSYM is "
- "compatible; using",
- path);
+ LLDB_LOGF(log,
+ "Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
}
}
break;
@@ -260,7 +264,7 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
return {};
// Make sure we close the directory before exiting this scope.
- CleanUp cleanup_dir(closedir, dirp);
+ auto cleanup_dir = llvm::make_scope_exit([&]() { closedir(dirp); });
FileSpec dsym_fspec;
dsym_fspec.GetDirectory().SetCString(path);
@@ -315,9 +319,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
FileSystem::Instance().Resolve(module_spec.GetFileSpec());
if (log) {
- log->Printf(
- "From dsymForUUID plist: Symbol rich executable is at '%s'",
- str.c_str());
+ LLDB_LOGF(log,
+ "From dsymForUUID plist: Symbol rich executable is at '%s'",
+ str.c_str());
}
}
}
@@ -331,7 +335,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
FileSystem::Instance().Resolve(module_spec.GetFileSpec());
success = true;
if (log) {
- log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
+ LLDB_LOGF(log, "From dsymForUUID plist: dSYM is at '%s'",
+ str.c_str());
}
}
}
@@ -582,11 +587,11 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
std::string command_output;
if (log) {
if (!uuid_str.empty())
- log->Printf("Calling %s with UUID %s to find dSYM",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ LLDB_LOGF(log, "Calling %s with UUID %s to find dSYM",
+ g_dsym_for_uuid_exe_path, uuid_str.c_str());
else if (file_path[0] != '\0')
- log->Printf("Calling %s with file %s to find dSYM",
- g_dsym_for_uuid_exe_path, file_path);
+ LLDB_LOGF(log, "Calling %s with file %s to find dSYM",
+ g_dsym_for_uuid_exe_path, file_path);
}
Status error = Host::RunShellCommand(
command.GetData(),
@@ -643,11 +648,11 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
} else {
if (log) {
if (!uuid_str.empty())
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ LLDB_LOGF(log, "Called %s on %s, no matches",
+ g_dsym_for_uuid_exe_path, uuid_str.c_str());
else if (file_path[0] != '\0')
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, file_path);
+ LLDB_LOGF(log, "Called %s on %s, no matches",
+ g_dsym_for_uuid_exe_path, file_path);
}
}
}
diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp
index 172d2b3f01e3..38bc7722d0d0 100644
--- a/source/Symbol/ObjectFile.cpp
+++ b/source/Symbol/ObjectFile.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Process.h"
@@ -19,13 +20,14 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
+char ObjectFile::ID;
+
ObjectFileSP
ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
lldb::offset_t file_offset, lldb::offset_t file_size,
@@ -81,9 +83,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
if (!data_sp || data_sp->GetByteSize() == 0) {
// Check for archive file with format "/path/to/archive.a(object.o)"
- char path_with_object[PATH_MAX * 2];
- module_sp->GetFileSpec().GetPath(path_with_object,
- sizeof(path_with_object));
+ llvm::SmallString<256> path_with_object;
+ module_sp->GetFileSpec().GetPath(path_with_object);
ConstString archive_object;
const bool must_exist = true;
@@ -271,13 +272,13 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
if (data_sp)
m_data.SetData(data_sp, data_offset, length);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
- "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
- static_cast<void *>(this), static_cast<void *>(module_sp.get()),
- module_sp->GetSpecificationDescription().c_str(),
- m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
- m_length);
+ LLDB_LOGF(log,
+ "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
+ "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
+ static_cast<void *>(this), static_cast<void *>(module_sp.get()),
+ module_sp->GetSpecificationDescription().c_str(),
+ m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
+ m_length);
}
ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
@@ -290,18 +291,17 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
if (header_data_sp)
m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
- "header_addr = 0x%" PRIx64,
- static_cast<void *>(this), static_cast<void *>(module_sp.get()),
- module_sp->GetSpecificationDescription().c_str(),
- static_cast<void *>(process_sp.get()), m_memory_addr);
+ LLDB_LOGF(log,
+ "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
+ "header_addr = 0x%" PRIx64,
+ static_cast<void *>(this), static_cast<void *>(module_sp.get()),
+ module_sp->GetSpecificationDescription().c_str(),
+ static_cast<void *>(process_sp.get()), m_memory_addr);
}
ObjectFile::~ObjectFile() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
}
bool ObjectFile::SetModulesArchitecture(const ArchSpec &new_arch) {
@@ -570,24 +570,22 @@ size_t ObjectFile::ReadSectionData(Section *section,
}
}
-bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,
+bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
FileSpec &archive_file,
ConstString &archive_object,
bool must_exist) {
- RegularExpression g_object_regex(llvm::StringRef("(.*)\\(([^\\)]+)\\)$"));
- RegularExpression::Match regex_match(2);
- if (g_object_regex.Execute(llvm::StringRef::withNullAsEmpty(path_with_object),
- &regex_match)) {
- std::string path;
- std::string obj;
- if (regex_match.GetMatchAtIndex(path_with_object, 1, path) &&
- regex_match.GetMatchAtIndex(path_with_object, 2, obj)) {
- archive_file.SetFile(path, FileSpec::Style::native);
- archive_object.SetCString(obj.c_str());
- return !(must_exist && !FileSystem::Instance().Exists(archive_file));
- }
- }
- return false;
+ size_t len = path_with_object.size();
+ if (len < 2 || path_with_object.back() != ')')
+ return false;
+ llvm::StringRef archive = path_with_object.substr(0, path_with_object.rfind('('));
+ if (archive.empty())
+ return false;
+ llvm::StringRef object = path_with_object.substr(archive.size() + 1).drop_back();
+ archive_file.SetFile(archive, FileSpec::Style::native);
+ if (must_exist && !FileSystem::Instance().Exists(archive_file))
+ return false;
+ archive_object.SetString(object);
+ return true;
}
void ObjectFile::ClearSymtab() {
@@ -595,10 +593,9 @@ void ObjectFile::ClearSymtab() {
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p ObjectFile::ClearSymtab () symtab = %p",
- static_cast<void *>(this),
- static_cast<void *>(m_symtab_up.get()));
+ LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
+ static_cast<void *>(this),
+ static_cast<void *>(m_symtab_up.get()));
m_symtab_up.reset();
}
}
@@ -674,6 +671,10 @@ ObjectFile::GetLoadableData(Target &target) {
return loadables;
}
+std::unique_ptr<CallFrameInfo> ObjectFile::CreateCallFrameInfo() {
+ return {};
+}
+
void ObjectFile::RelocateSection(lldb_private::Section *section)
{
}
diff --git a/source/Symbol/PostfixExpression.cpp b/source/Symbol/PostfixExpression.cpp
index 148653561a4e..8ecd571ed929 100644
--- a/source/Symbol/PostfixExpression.cpp
+++ b/source/Symbol/PostfixExpression.cpp
@@ -41,7 +41,8 @@ GetUnaryOpType(llvm::StringRef token) {
return llvm::None;
}
-Node *postfix::Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc) {
+Node *postfix::ParseOneExpression(llvm::StringRef expr,
+ llvm::BumpPtrAllocator &alloc) {
llvm::SmallVector<Node *, 4> stack;
llvm::StringRef token;
@@ -83,6 +84,26 @@ Node *postfix::Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc) {
return stack.back();
}
+std::vector<std::pair<llvm::StringRef, Node *>>
+postfix::ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc) {
+ llvm::SmallVector<llvm::StringRef, 4> exprs;
+ prog.split(exprs, '=');
+ if (exprs.empty() || !exprs.back().trim().empty())
+ return {};
+ exprs.pop_back();
+
+ std::vector<std::pair<llvm::StringRef, Node *>> result;
+ for (llvm::StringRef expr : exprs) {
+ llvm::StringRef lhs;
+ std::tie(lhs, expr) = getToken(expr);
+ Node *rhs = ParseOneExpression(expr, alloc);
+ if (!rhs)
+ return {};
+ result.emplace_back(lhs, rhs);
+ }
+ return result;
+}
+
namespace {
class SymbolResolver : public Visitor<bool> {
public:
diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp
index 589f69244a48..3f2414335813 100644
--- a/source/Symbol/Symbol.cpp
+++ b/source/Symbol/Symbol.cpp
@@ -31,9 +31,8 @@ Symbol::Symbol()
m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(), m_addr_range(),
m_flags() {}
-Symbol::Symbol(uint32_t symID, const char *name, bool name_is_mangled,
- SymbolType type, bool external, bool is_debug,
- bool is_trampoline, bool is_artificial,
+Symbol::Symbol(uint32_t symID, llvm::StringRef name, SymbolType type, bool external,
+ bool is_debug, bool is_trampoline, bool is_artificial,
const lldb::SectionSP &section_sp, addr_t offset, addr_t size,
bool size_is_valid, bool contains_linker_annotations,
uint32_t flags)
@@ -42,9 +41,9 @@ Symbol::Symbol(uint32_t symID, const char *name, bool name_is_mangled,
m_is_debug(is_debug), m_is_external(external), m_size_is_sibling(false),
m_size_is_synthesized(false), m_size_is_valid(size_is_valid || size > 0),
m_demangled_is_synthesized(false),
- m_contains_linker_annotations(contains_linker_annotations),
+ m_contains_linker_annotations(contains_linker_annotations),
m_is_weak(false), m_type(type),
- m_mangled(ConstString(name), name_is_mangled),
+ m_mangled(name),
m_addr_range(section_sp, offset, size), m_flags(flags) {}
Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type,
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index a0b35cf3d0b9..31e0c89eed94 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -13,7 +13,6 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -22,6 +21,7 @@
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
@@ -494,7 +494,8 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"warning: inlined block 0x%8.8" PRIx64
" doesn't have a range that contains file address 0x%" PRIx64,
curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
@@ -503,12 +504,8 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc,
else {
ObjectFile *objfile = nullptr;
if (module_sp) {
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
- if (symbol_vendor) {
- SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
- if (symbol_file)
- objfile = symbol_file->GetObjectFile();
- }
+ if (SymbolFile *symbol_file = module_sp->GetSymbolFile())
+ objfile = symbol_file->GetObjectFile();
}
if (objfile) {
Host::SystemLog(
@@ -762,9 +759,8 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
}
Block *func_block = GetFunctionBlock();
- if (func_block &&
- func_block->GetRangeIndexContainingAddress(
- end_entry.range.GetBaseAddress()) == UINT32_MAX) {
+ if (func_block && func_block->GetRangeIndexContainingAddress(
+ end_entry.range.GetBaseAddress()) == UINT32_MAX) {
error.SetErrorStringWithFormat(
"end line number %d is not contained within the current function.",
end_line);
@@ -777,8 +773,8 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
return true;
}
-const Symbol *
-SymbolContext::FindBestGlobalDataSymbol(ConstString name, Status &error) {
+const Symbol *SymbolContext::FindBestGlobalDataSymbol(ConstString name,
+ Status &error) {
error.Clear();
if (!target_sp) {
@@ -788,8 +784,9 @@ SymbolContext::FindBestGlobalDataSymbol(ConstString name, Status &error) {
Target &target = *target_sp;
Module *module = module_sp.get();
- auto ProcessMatches = [this, &name, &target, module]
- (SymbolContextList &sc_list, Status &error) -> const Symbol* {
+ auto ProcessMatches = [this, &name, &target,
+ module](SymbolContextList &sc_list,
+ Status &error) -> const Symbol * {
llvm::SmallVector<const Symbol *, 1> external_symbols;
llvm::SmallVector<const Symbol *, 1> internal_symbols;
const uint32_t matches = sc_list.GetSize();
@@ -802,77 +799,77 @@ SymbolContext::FindBestGlobalDataSymbol(ConstString name, Status &error) {
if (sym_address.IsValid()) {
switch (symbol->GetType()) {
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeAbsolute:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- if (symbol->GetDemangledNameIsSynthesized()) {
- // If the demangled name was synthesized, then don't use it for
- // expressions. Only let the symbol match if the mangled named
- // matches for these symbols.
- if (symbol->GetMangled().GetMangledName() != name)
- break;
- }
- if (symbol->IsExternal()) {
- external_symbols.push_back(symbol);
- } else {
- internal_symbols.push_back(symbol);
- }
- break;
- case eSymbolTypeReExported: {
- ConstString reexport_name = symbol->GetReExportedSymbolName();
- if (reexport_name) {
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() =
- symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec()) {
- reexport_module_sp =
- target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp) {
- reexport_module_spec.GetPlatformFileSpec()
- .GetDirectory()
- .Clear();
- reexport_module_sp =
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ if (symbol->GetDemangledNameIsSynthesized()) {
+ // If the demangled name was synthesized, then don't use it for
+ // expressions. Only let the symbol match if the mangled named
+ // matches for these symbols.
+ if (symbol->GetMangled().GetMangledName() != name)
+ break;
+ }
+ if (symbol->IsExternal()) {
+ external_symbols.push_back(symbol);
+ } else {
+ internal_symbols.push_back(symbol);
+ }
+ break;
+ case eSymbolTypeReExported: {
+ ConstString reexport_name = symbol->GetReExportedSymbolName();
+ if (reexport_name) {
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() =
+ symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec()) {
+ reexport_module_sp =
target.GetImages().FindFirstModule(reexport_module_spec);
- }
+ if (!reexport_module_sp) {
+ reexport_module_spec.GetPlatformFileSpec()
+ .GetDirectory()
+ .Clear();
+ reexport_module_sp =
+ target.GetImages().FindFirstModule(reexport_module_spec);
}
- // Don't allow us to try and resolve a re-exported symbol if it
- // is the same as the current symbol
- if (name == symbol->GetReExportedSymbolName() &&
- module == reexport_module_sp.get())
- return nullptr;
-
- return FindBestGlobalDataSymbol(
- symbol->GetReExportedSymbolName(), error);
}
- } break;
-
- case eSymbolTypeCode: // We already lookup functions elsewhere
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeTrampoline:
- case eSymbolTypeInvalid:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeResolver:
- break;
+ // Don't allow us to try and resolve a re-exported symbol if it
+ // is the same as the current symbol
+ if (name == symbol->GetReExportedSymbolName() &&
+ module == reexport_module_sp.get())
+ return nullptr;
+
+ return FindBestGlobalDataSymbol(symbol->GetReExportedSymbolName(),
+ error);
+ }
+ } break;
+
+ case eSymbolTypeCode: // We already lookup functions elsewhere
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeTrampoline:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeResolver:
+ break;
}
}
}
@@ -933,7 +930,6 @@ SymbolContext::FindBestGlobalDataSymbol(ConstString name, Status &error) {
return nullptr; // no error; we just didn't find anything
}
-
//
// SymbolContextSpecifier
//
@@ -1296,6 +1292,8 @@ bool SymbolContextList::RemoveContextAtIndex(size_t idx) {
uint32_t SymbolContextList::GetSize() const { return m_symbol_contexts.size(); }
+bool SymbolContextList::IsEmpty() const { return m_symbol_contexts.empty(); }
+
uint32_t SymbolContextList::NumLineEntriesWithLine(uint32_t line) const {
uint32_t match_count = 0;
const size_t size = m_symbol_contexts.size();
diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp
index 77ab2223ec07..c4f3a9c1a8c8 100644
--- a/source/Symbol/SymbolFile.cpp
+++ b/source/Symbol/SymbolFile.cpp
@@ -10,6 +10,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
@@ -21,6 +22,7 @@
#include <future>
using namespace lldb_private;
+using namespace lldb;
void SymbolFile::PreloadSymbols() {
// No-op for most implementations.
@@ -29,21 +31,24 @@ void SymbolFile::PreloadSymbols() {
std::recursive_mutex &SymbolFile::GetModuleMutex() const {
return GetObjectFile()->GetModule()->GetMutex();
}
+ObjectFile *SymbolFile::GetMainObjectFile() {
+ return m_objfile_sp->GetModule()->GetObjectFile();
+}
-SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
+SymbolFile *SymbolFile::FindPlugin(ObjectFileSP objfile_sp) {
std::unique_ptr<SymbolFile> best_symfile_up;
- if (obj_file != nullptr) {
+ if (objfile_sp != nullptr) {
// We need to test the abilities of this section list. So create what it
- // would be with this new obj_file.
- lldb::ModuleSP module_sp(obj_file->GetModule());
+ // would be with this new objfile_sp.
+ lldb::ModuleSP module_sp(objfile_sp->GetModule());
if (module_sp) {
// Default to the main module section list.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
- if (module_obj_file != obj_file) {
+ if (module_obj_file != objfile_sp.get()) {
// Make sure the main object file's sections are created
module_obj_file->GetSectionList();
- obj_file->CreateSections(*module_sp->GetUnifiedSectionList());
+ objfile_sp->CreateSections(*module_sp->GetUnifiedSectionList());
}
}
@@ -57,7 +62,7 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
(create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex(
idx)) != nullptr;
++idx) {
- std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(obj_file));
+ std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(objfile_sp));
if (curr_symfile_up) {
const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities();
@@ -80,18 +85,14 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
return best_symfile_up.release();
}
-TypeList *SymbolFile::GetTypeList() {
- if (m_obj_file)
- return m_obj_file->GetModule()->GetTypeList();
- return nullptr;
-}
-
-TypeSystem *SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) {
- TypeSystem *type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+llvm::Expected<TypeSystem &>
+SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) {
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec,
@@ -101,36 +102,24 @@ uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec,
return 0;
}
-uint32_t
-SymbolFile::FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches, VariableList &variables) {
- return 0;
-}
+void SymbolFile::FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) {}
-uint32_t SymbolFile::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
- return 0;
-}
+void SymbolFile::FindGlobalVariables(const RegularExpression &regex,
+ uint32_t max_matches,
+ VariableList &variables) {}
-uint32_t SymbolFile::FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
- return 0;
-}
+void SymbolFile::FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ SymbolContextList &sc_list) {}
-uint32_t SymbolFile::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
- return 0;
-}
+void SymbolFile::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {}
void SymbolFile::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
@@ -138,22 +127,14 @@ void SymbolFile::GetMangledNamesForFunction(
return;
}
-uint32_t SymbolFile::FindTypes(
+void SymbolFile::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- if (!append)
- types.Clear();
- return 0;
-}
+ TypeMap &types) {}
-size_t SymbolFile::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
- return 0;
-}
+void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
void SymbolFile::AssertModuleLock() {
// The code below is too expensive to leave enabled in release builds. It's
@@ -169,4 +150,85 @@ void SymbolFile::AssertModuleLock() {
#endif
}
+uint32_t SymbolFile::GetNumCompileUnits() {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (!m_compile_units) {
+ // Create an array of compile unit shared pointers -- which will each
+ // remain NULL until someone asks for the actual compile unit information.
+ m_compile_units.emplace(CalculateNumCompileUnits());
+ }
+ return m_compile_units->size();
+}
+
+CompUnitSP SymbolFile::GetCompileUnitAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ uint32_t num = GetNumCompileUnits();
+ if (idx >= num)
+ return nullptr;
+ lldb::CompUnitSP &cu_sp = (*m_compile_units)[idx];
+ if (!cu_sp)
+ cu_sp = ParseCompileUnitAtIndex(idx);
+ return cu_sp;
+}
+
+void SymbolFile::SetCompileUnitAtIndex(uint32_t idx, const CompUnitSP &cu_sp) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ const size_t num_compile_units = GetNumCompileUnits();
+ assert(idx < num_compile_units);
+ (void)num_compile_units;
+
+ // Fire off an assertion if this compile unit already exists for now. The
+ // partial parsing should take care of only setting the compile unit
+ // once, so if this assertion fails, we need to make sure that we don't
+ // have a race condition, or have a second parse of the same compile
+ // unit.
+ assert((*m_compile_units)[idx] == nullptr);
+ (*m_compile_units)[idx] = cu_sp;
+}
+
+Symtab *SymbolFile::GetSymtab() {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (m_symtab)
+ return m_symtab;
+
+ // Fetch the symtab from the main object file.
+ m_symtab = GetMainObjectFile()->GetSymtab();
+
+ // Then add our symbols to it.
+ if (m_symtab)
+ AddSymbols(*m_symtab);
+
+ return m_symtab;
+}
+
+void SymbolFile::SectionFileAddressesChanged() {
+ ObjectFile *module_objfile = GetMainObjectFile();
+ ObjectFile *symfile_objfile = GetObjectFile();
+ if (symfile_objfile != module_objfile)
+ symfile_objfile->SectionFileAddressesChanged();
+ if (m_symtab)
+ m_symtab->SectionFileAddressesChanged();
+}
+
+void SymbolFile::Dump(Stream &s) {
+ s.Format("SymbolFile {0} ({1})\n", GetPluginName(),
+ GetMainObjectFile()->GetFileSpec());
+ s.PutCString("Types:\n");
+ m_type_list.Dump(&s, /*show_context*/ false);
+ s.PutChar('\n');
+
+ s.PutCString("Compile units:\n");
+ if (m_compile_units) {
+ for (const CompUnitSP &cu_sp : *m_compile_units) {
+ // We currently only dump the compile units that have been parsed
+ if (cu_sp)
+ cu_sp->Dump(&s, /*show_context*/ false);
+ }
+ }
+ s.PutChar('\n');
+
+ if (Symtab *symtab = GetSymtab())
+ symtab->Dump(&s, nullptr, eSortOrderNone);
+}
+
SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default;
diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp
index b9f3a5fe3926..1e1dea71d7f3 100644
--- a/source/Symbol/SymbolVendor.cpp
+++ b/source/Symbol/SymbolVendor.cpp
@@ -58,8 +58,7 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
// SymbolVendor constructor
SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
- : ModuleChild(module_sp), m_type_list(), m_compile_units(), m_sym_file_up(),
- m_symtab() {}
+ : ModuleChild(module_sp), m_sym_file_up() {}
// Destructor
SymbolVendor::~SymbolVendor() {}
@@ -69,414 +68,8 @@ void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
ModuleSP module_sp(GetModule());
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (objfile_sp) {
- m_objfile_sp = objfile_sp;
- m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp.get()));
- }
- }
-}
-
-bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- const size_t num_compile_units = GetNumCompileUnits();
- if (idx < num_compile_units) {
- // Fire off an assertion if this compile unit already exists for now. The
- // partial parsing should take care of only setting the compile unit
- // once, so if this assertion fails, we need to make sure that we don't
- // have a race condition, or have a second parse of the same compile
- // unit.
- assert(m_compile_units[idx].get() == nullptr);
- m_compile_units[idx] = cu_sp;
- return true;
- } else {
- // This should NOT happen, and if it does, we want to crash and know
- // about it
- assert(idx < num_compile_units);
- }
- }
- return false;
-}
-
-size_t SymbolVendor::GetNumCompileUnits() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_compile_units.empty()) {
- if (m_sym_file_up) {
- // Resize our array of compile unit shared pointers -- which will each
- // remain NULL until someone asks for the actual compile unit
- // information. When this happens, the symbol file will be asked to
- // parse this compile unit information.
- m_compile_units.resize(m_sym_file_up->GetNumCompileUnits());
- }
- }
- }
- return m_compile_units.size();
-}
-
-lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseLanguage(comp_unit);
- }
- return eLanguageTypeUnknown;
-}
-
-size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseFunctions(comp_unit);
- }
- return 0;
-}
-
-bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseLineTable(comp_unit);
- }
- return false;
-}
-
-bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseDebugMacros(comp_unit);
- }
- return false;
-}
-bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit,
- FileSpecList &support_files) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseSupportFiles(comp_unit, support_files);
- }
- return false;
-}
-
-bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseIsOptimized(comp_unit);
- }
- return false;
-}
-
-bool SymbolVendor::ParseImportedModules(
- const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseImportedModules(sc, imported_modules);
- }
- return false;
-}
-
-size_t SymbolVendor::ParseBlocksRecursive(Function &func) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseBlocksRecursive(func);
- }
- return 0;
-}
-
-size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseTypes(comp_unit);
- }
- return 0;
-}
-
-size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ParseVariablesForContext(sc);
- }
- return 0;
-}
-
-Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ResolveTypeUID(type_uid);
- }
- return nullptr;
-}
-
-uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
- SymbolContextItem resolve_scope,
- SymbolContext &sc) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc);
- }
- return 0;
-}
-
-uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
- uint32_t line, bool check_inlines,
- SymbolContextItem resolve_scope,
- SymbolContextList &sc_list) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines,
- resolve_scope, sc_list);
- }
- return 0;
-}
-
-size_t
-SymbolVendor::FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches, VariableList &variables) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx,
- max_matches, variables);
- }
- return 0;
-}
-
-size_t SymbolVendor::FindGlobalVariables(const RegularExpression &regex,
- size_t max_matches,
- VariableList &variables) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables);
- }
- return 0;
-}
-
-size_t SymbolVendor::FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, append, sc_list);
- }
- return 0;
-}
-
-size_t SymbolVendor::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindFunctions(regex, include_inlines, append,
- sc_list);
- }
- return 0;
-}
-
-size_t SymbolVendor::FindTypes(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindTypes(name, parent_decl_ctx, append,
- max_matches, searched_symbol_files,
- types);
- }
- if (!append)
- types.Clear();
- return 0;
-}
-
-size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->FindTypes(context, append, types);
- }
- if (!append)
- types.Clear();
- return 0;
-}
-
-size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list);
- }
- return 0;
-}
-
-CompilerDeclContext
-SymbolVendor::FindNamespace(ConstString name,
- const CompilerDeclContext *parent_decl_ctx) {
- CompilerDeclContext namespace_decl_ctx;
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_sym_file_up)
- namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx);
- }
- return namespace_decl_ctx;
-}
-
-void SymbolVendor::Dump(Stream *s) {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- bool show_context = false;
-
- s->Printf("%p: ", static_cast<void *>(this));
- s->Indent();
- s->PutCString("SymbolVendor");
- if (m_sym_file_up) {
- *s << " " << m_sym_file_up->GetPluginName();
- ObjectFile *objfile = m_sym_file_up->GetObjectFile();
- if (objfile) {
- const FileSpec &objfile_file_spec = objfile->GetFileSpec();
- if (objfile_file_spec) {
- s->PutCString(" (");
- objfile_file_spec.Dump(s);
- s->PutChar(')');
- }
- }
- }
- s->EOL();
- if (m_sym_file_up)
- m_sym_file_up->Dump(*s);
- s->IndentMore();
- m_type_list.Dump(s, show_context);
-
- CompileUnitConstIter cu_pos, cu_end;
- cu_end = m_compile_units.end();
- for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) {
- // We currently only dump the compile units that have been parsed
- if (*cu_pos)
- (*cu_pos)->Dump(s, show_context);
- }
-
- if (Symtab *symtab = GetSymtab())
- symtab->Dump(s, nullptr, eSortOrderNone);
-
- s->IndentLess();
- }
-}
-
-CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
- CompUnitSP cu_sp;
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- const size_t num_compile_units = GetNumCompileUnits();
- if (idx < num_compile_units) {
- cu_sp = m_compile_units[idx];
- if (cu_sp.get() == nullptr) {
- m_compile_units[idx] = m_sym_file_up->ParseCompileUnitAtIndex(idx);
- cu_sp = m_compile_units[idx];
- }
- }
- }
- return cu_sp;
-}
-
-FileSpec SymbolVendor::GetMainFileSpec() const {
- if (m_sym_file_up) {
- const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
- if (symfile_objfile)
- return symfile_objfile->GetFileSpec();
- }
-
- return FileSpec();
-}
-
-Symtab *SymbolVendor::GetSymtab() {
- ModuleSP module_sp(GetModule());
- if (!module_sp)
- return nullptr;
-
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- if (m_symtab)
- return m_symtab;
-
- ObjectFile *objfile = module_sp->GetObjectFile();
- if (!objfile)
- return nullptr;
-
- m_symtab = objfile->GetSymtab();
- if (m_symtab && m_sym_file_up)
- m_sym_file_up->AddSymbols(*m_symtab);
-
- return m_symtab;
-}
-
-void SymbolVendor::ClearSymtab() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- ObjectFile *objfile = module_sp->GetObjectFile();
- if (objfile) {
- // Clear symbol table from unified section list.
- objfile->ClearSymtab();
- }
- }
-}
-
-void SymbolVendor::SectionFileAddressesChanged() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- ObjectFile *module_objfile = module_sp->GetObjectFile();
- if (m_sym_file_up) {
- ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
- if (symfile_objfile != module_objfile)
- symfile_objfile->SectionFileAddressesChanged();
- }
- Symtab *symtab = GetSymtab();
- if (symtab) {
- symtab->SectionFileAddressesChanged();
- }
+ if (objfile_sp)
+ m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp));
}
}
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 29c390e83878..c4e6c2ccfb09 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -738,7 +738,7 @@ Symbol *Symtab::FindSymbolWithType(SymbolType symbol_type,
return nullptr;
}
-size_t
+void
Symtab::FindAllSymbolsWithNameAndType(ConstString name,
SymbolType symbol_type,
std::vector<uint32_t> &symbol_indexes) {
@@ -756,10 +756,9 @@ Symtab::FindAllSymbolsWithNameAndType(ConstString name,
// the symbols and match the symbol_type if any was given.
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_indexes);
}
- return symbol_indexes.size();
}
-size_t Symtab::FindAllSymbolsWithNameAndType(
+void Symtab::FindAllSymbolsWithNameAndType(
ConstString name, SymbolType symbol_type, Debug symbol_debug_type,
Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -777,10 +776,9 @@ size_t Symtab::FindAllSymbolsWithNameAndType(
AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
symbol_visibility, symbol_indexes);
}
- return symbol_indexes.size();
}
-size_t Symtab::FindAllSymbolsMatchingRexExAndType(
+void Symtab::FindAllSymbolsMatchingRexExAndType(
const RegularExpression &regex, SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &symbol_indexes) {
@@ -788,7 +786,6 @@ size_t Symtab::FindAllSymbolsMatchingRexExAndType(
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
symbol_visibility, symbol_indexes);
- return symbol_indexes.size();
}
Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
@@ -1024,10 +1021,8 @@ void Symtab::SymbolIndicesToSymbolContextList(
}
}
-size_t Symtab::FindFunctionSymbols(ConstString name,
- uint32_t name_type_mask,
- SymbolContextList &sc_list) {
- size_t count = 0;
+void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
+ SymbolContextList &sc_list) {
std::vector<uint32_t> symbol_indexes;
// eFunctionNameTypeAuto should be pre-resolved by a call to
@@ -1108,11 +1103,8 @@ size_t Symtab::FindFunctionSymbols(ConstString name,
symbol_indexes.erase(
std::unique(symbol_indexes.begin(), symbol_indexes.end()),
symbol_indexes.end());
- count = symbol_indexes.size();
SymbolIndicesToSymbolContextList(symbol_indexes, sc_list);
}
-
- return count;
}
const Symbol *Symtab::GetParent(Symbol *child_symbol) const {
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 4ee8330ce288..5666590c2246 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
@@ -29,15 +30,41 @@
#include "llvm/ADT/StringRef.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-
using namespace lldb;
using namespace lldb_private;
+bool lldb_private::contextMatches(llvm::ArrayRef<CompilerContext> context_chain,
+ llvm::ArrayRef<CompilerContext> pattern) {
+ auto ctx = context_chain.begin();
+ auto ctx_end = context_chain.end();
+ for (const CompilerContext &pat : pattern) {
+ // Early exit if the pattern is too long.
+ if (ctx == ctx_end)
+ return false;
+ if (*ctx != pat) {
+ // Skip any number of module matches.
+ if (pat.kind == CompilerContextKind::AnyModule) {
+ // Greedily match 0..n modules.
+ ctx = std::find_if(ctx, ctx_end, [](const CompilerContext &ctx) {
+ return ctx.kind != CompilerContextKind::Module;
+ });
+ continue;
+ }
+ // See if there is a kind mismatch; they should have 1 bit in common.
+ if (((uint16_t)ctx->kind & (uint16_t)pat.kind) == 0)
+ return false;
+ // The name is ignored for AnyModule, but not for AnyType.
+ if (pat.kind != CompilerContextKind::AnyModule && ctx->name != pat.name)
+ return false;
+ }
+ ++ctx;
+ }
+ return true;
+}
+
void CompilerContext::Dump() const {
- switch (type) {
- case CompilerContextKind::Invalid:
+ switch (kind) {
+ default:
printf("Invalid");
break;
case CompilerContextKind::TranslationUnit:
@@ -52,7 +79,7 @@ void CompilerContext::Dump() const {
case CompilerContextKind::Class:
printf("Class");
break;
- case CompilerContextKind::Structure:
+ case CompilerContextKind::Struct:
printf("Structure");
break;
case CompilerContextKind::Union:
@@ -64,12 +91,18 @@ void CompilerContext::Dump() const {
case CompilerContextKind::Variable:
printf("Variable");
break;
- case CompilerContextKind::Enumeration:
+ case CompilerContextKind::Enum:
printf("Enumeration");
break;
case CompilerContextKind::Typedef:
printf("Typedef");
break;
+ case CompilerContextKind::AnyModule:
+ printf("AnyModule");
+ break;
+ case CompilerContextKind::AnyType:
+ printf("AnyType");
+ break;
}
printf("(\"%s\")\n", name.GetCString());
}
@@ -425,8 +458,6 @@ bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
return false;
}
-TypeList *Type::GetTypeList() { return GetSymbolFile()->GetTypeList(); }
-
const Declaration &Type::GetDeclaration() const { return m_decl; }
bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
@@ -488,47 +519,54 @@ bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) {
}
} else {
// We have no encoding type, return void?
- TypeSystem *type_system =
+ auto type_system_or_err =
m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);
- CompilerType void_compiler_type =
- type_system->GetBasicTypeFromAST(eBasicTypeVoid);
- switch (m_encoding_uid_type) {
- case eEncodingIsUID:
- m_compiler_type = void_compiler_type;
- break;
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to construct void type from ClangASTContext");
+ } else {
+ CompilerType void_compiler_type =
+ type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid);
+ switch (m_encoding_uid_type) {
+ case eEncodingIsUID:
+ m_compiler_type = void_compiler_type;
+ break;
- case eEncodingIsConstUID:
- m_compiler_type = void_compiler_type.AddConstModifier();
- break;
+ case eEncodingIsConstUID:
+ m_compiler_type = void_compiler_type.AddConstModifier();
+ break;
- case eEncodingIsRestrictUID:
- m_compiler_type = void_compiler_type.AddRestrictModifier();
- break;
+ case eEncodingIsRestrictUID:
+ m_compiler_type = void_compiler_type.AddRestrictModifier();
+ break;
- case eEncodingIsVolatileUID:
- m_compiler_type = void_compiler_type.AddVolatileModifier();
- break;
+ case eEncodingIsVolatileUID:
+ m_compiler_type = void_compiler_type.AddVolatileModifier();
+ break;
- case eEncodingIsTypedefUID:
- m_compiler_type = void_compiler_type.CreateTypedef(
- m_name.AsCString("__lldb_invalid_typedef_name"),
- GetSymbolFile()->GetDeclContextContainingUID(GetID()));
- break;
+ case eEncodingIsTypedefUID:
+ m_compiler_type = void_compiler_type.CreateTypedef(
+ m_name.AsCString("__lldb_invalid_typedef_name"),
+ GetSymbolFile()->GetDeclContextContainingUID(GetID()));
+ break;
- case eEncodingIsPointerUID:
- m_compiler_type = void_compiler_type.GetPointerType();
- break;
+ case eEncodingIsPointerUID:
+ m_compiler_type = void_compiler_type.GetPointerType();
+ break;
- case eEncodingIsLValueReferenceUID:
- m_compiler_type = void_compiler_type.GetLValueReferenceType();
- break;
+ case eEncodingIsLValueReferenceUID:
+ m_compiler_type = void_compiler_type.GetLValueReferenceType();
+ break;
- case eEncodingIsRValueReferenceUID:
- m_compiler_type = void_compiler_type.GetRValueReferenceType();
- break;
+ case eEncodingIsRValueReferenceUID:
+ m_compiler_type = void_compiler_type.GetRValueReferenceType();
+ break;
- default:
- llvm_unreachable("Unhandled encoding_data_type.");
+ default:
+ llvm_unreachable("Unhandled encoding_data_type.");
+ }
}
}
diff --git a/source/Symbol/TypeMap.cpp b/source/Symbol/TypeMap.cpp
index bc6e272449f0..4ee1026bed24 100644
--- a/source/Symbol/TypeMap.cpp
+++ b/source/Symbol/TypeMap.cpp
@@ -8,18 +8,6 @@
#include <vector>
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclGroup.h"
-
-#include "clang/Basic/Builtins.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
@@ -30,7 +18,6 @@
using namespace lldb;
using namespace lldb_private;
-using namespace clang;
TypeMap::TypeMap() : m_types() {}
diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp
index fb9c8e71acb3..c63f24aea335 100644
--- a/source/Symbol/TypeSystem.cpp
+++ b/source/Symbol/TypeSystem.cpp
@@ -20,10 +20,29 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Language.h"
using namespace lldb_private;
using namespace lldb;
+/// A 64-bit SmallBitVector is only small up to 64-7 bits, and the
+/// setBitsInMask interface wants to write full bytes.
+static const size_t g_num_small_bitvector_bits = 64 - 8;
+static_assert(eNumLanguageTypes < g_num_small_bitvector_bits,
+ "Languages bit vector is no longer small on 64 bit systems");
+LanguageSet::LanguageSet() : bitvector(eNumLanguageTypes, 0) {}
+
+llvm::Optional<LanguageType> LanguageSet::GetSingularLanguage() {
+ if (bitvector.count() == 1)
+ return (LanguageType)bitvector.find_first();
+ return {};
+}
+
+void LanguageSet::Insert(LanguageType language) { bitvector.set(language); }
+size_t LanguageSet::Size() const { return bitvector.count(); }
+bool LanguageSet::Empty() const { return bitvector.none(); }
+bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }
+
TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {}
TypeSystem::~TypeSystem() {}
@@ -198,65 +217,140 @@ void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
}
}
-TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
- Module *module,
- bool can_create) {
+llvm::Expected<TypeSystem &>
+TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
+ Module *module, bool can_create) {
+ llvm::Error error = llvm::Error::success();
+ assert(!error); // Check the success value when assertions are enabled
std::lock_guard<std::mutex> guard(m_mutex);
- collection::iterator pos = m_map.find(language);
- if (pos != m_map.end())
- return pos->second.get();
-
- for (const auto &pair : m_map) {
- if (pair.second && pair.second->SupportsLanguage(language)) {
- // Add a new mapping for "language" to point to an already existing
- // TypeSystem that supports this language
- AddToMap(language, pair.second);
- return pair.second.get();
+ if (m_clear_in_progress) {
+ error = llvm::make_error<llvm::StringError>(
+ "Unable to get TypeSystem because TypeSystemMap is being cleared",
+ llvm::inconvertibleErrorCode());
+ } else {
+ collection::iterator pos = m_map.find(language);
+ if (pos != m_map.end()) {
+ auto *type_system = pos->second.get();
+ if (type_system) {
+ llvm::consumeError(std::move(error));
+ return *type_system;
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
+ return std::move(error);
}
- }
- if (!can_create)
- return nullptr;
+ for (const auto &pair : m_map) {
+ if (pair.second && pair.second->SupportsLanguage(language)) {
+ // Add a new mapping for "language" to point to an already existing
+ // TypeSystem that supports this language
+ m_map[language] = pair.second;
+ if (pair.second.get()) {
+ llvm::consumeError(std::move(error));
+ return *pair.second.get();
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
+ return std::move(error);
+ }
+ }
+
+ if (!can_create) {
+ error = llvm::make_error<llvm::StringError>(
+ "Unable to find type system for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)),
+ llvm::inconvertibleErrorCode());
+ } else {
+ // Cache even if we get a shared pointer that contains a null type system
+ // back
+ auto type_system_sp = TypeSystem::CreateInstance(language, module);
+ m_map[language] = type_system_sp;
+ if (type_system_sp.get()) {
+ llvm::consumeError(std::move(error));
+ return *type_system_sp.get();
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
+ }
+ }
- // Cache even if we get a shared pointer that contains null type system back
- lldb::TypeSystemSP type_system_sp =
- TypeSystem::CreateInstance(language, module);
- AddToMap(language, type_system_sp);
- return type_system_sp.get();
+ return std::move(error);
}
-TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
- Target *target,
- bool can_create) {
+llvm::Expected<TypeSystem &>
+TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
+ Target *target, bool can_create) {
+ llvm::Error error = llvm::Error::success();
+ assert(!error); // Check the success value when assertions are enabled
std::lock_guard<std::mutex> guard(m_mutex);
- collection::iterator pos = m_map.find(language);
- if (pos != m_map.end())
- return pos->second.get();
+ if (m_clear_in_progress) {
+ error = llvm::make_error<llvm::StringError>(
+ "Unable to get TypeSystem because TypeSystemMap is being cleared",
+ llvm::inconvertibleErrorCode());
+ } else {
+ collection::iterator pos = m_map.find(language);
+ if (pos != m_map.end()) {
+ auto *type_system = pos->second.get();
+ if (type_system) {
+ llvm::consumeError(std::move(error));
+ return *type_system;
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
+ return std::move(error);
+ }
- for (const auto &pair : m_map) {
- if (pair.second && pair.second->SupportsLanguage(language)) {
- // Add a new mapping for "language" to point to an already existing
- // TypeSystem that supports this language
+ for (const auto &pair : m_map) {
+ if (pair.second && pair.second->SupportsLanguage(language)) {
+ // Add a new mapping for "language" to point to an already existing
+ // TypeSystem that supports this language
+ m_map[language] = pair.second;
+ if (pair.second.get()) {
+ llvm::consumeError(std::move(error));
+ return *pair.second.get();
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
+ return std::move(error);
+ }
+ }
- AddToMap(language, pair.second);
- return pair.second.get();
+ if (!can_create) {
+ error = llvm::make_error<llvm::StringError>(
+ "Unable to find type system for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)),
+ llvm::inconvertibleErrorCode());
+ } else {
+ // Cache even if we get a shared pointer that contains a null type system
+ // back
+ auto type_system_sp = TypeSystem::CreateInstance(language, target);
+ m_map[language] = type_system_sp;
+ if (type_system_sp.get()) {
+ llvm::consumeError(std::move(error));
+ return *type_system_sp.get();
+ }
+ error = llvm::make_error<llvm::StringError>(
+ "TypeSystem for language " +
+ llvm::toStringRef(Language::GetNameForLanguageType(language)) +
+ " doesn't exist",
+ llvm::inconvertibleErrorCode());
}
}
- if (!can_create)
- return nullptr;
-
- // Cache even if we get a shared pointer that contains null type system back
- lldb::TypeSystemSP type_system_sp;
- if (!m_clear_in_progress)
- type_system_sp = TypeSystem::CreateInstance(language, target);
-
- AddToMap(language, type_system_sp);
- return type_system_sp.get();
-}
-
-void TypeSystemMap::AddToMap(lldb::LanguageType language,
- lldb::TypeSystemSP const &type_system_sp) {
- if (!m_clear_in_progress)
- m_map[language] = type_system_sp;
+ return std::move(error);
}
diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp
index 774f9cb587ee..15443ce5d8ac 100644
--- a/source/Symbol/UnwindPlan.cpp
+++ b/source/Symbol/UnwindPlan.cpp
@@ -170,7 +170,8 @@ operator==(const UnwindPlan::Row::FAValue &rhs) const {
if (m_type == rhs.m_type) {
switch (m_type) {
case unspecified:
- return true;
+ case isRaSearch:
+ return m_value.ra_search_offset == rhs.m_value.ra_search_offset;
case isRegisterPlusOffset:
return m_value.reg.offset == rhs.m_value.reg.offset;
@@ -205,9 +206,12 @@ void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan,
llvm::makeArrayRef(m_value.expr.opcodes, m_value.expr.length),
thread);
break;
- default:
+ case unspecified:
s.PutCString("unspecified");
break;
+ case isRaSearch:
+ s.Printf("RaSearch@SP%+d", m_value.ra_search_offset);
+ break;
}
}
@@ -402,10 +406,10 @@ const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const {
return m_row_list[idx];
else {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log)
- log->Printf("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index "
- "(number rows is %u)",
- idx, (uint32_t)m_row_list.size());
+ LLDB_LOGF(log,
+ "error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index "
+ "(number rows is %u)",
+ idx, (uint32_t)m_row_list.size());
return UnwindPlan::RowSP();
}
}
@@ -413,8 +417,7 @@ const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const {
const UnwindPlan::RowSP UnwindPlan::GetLastRow() const {
if (m_row_list.empty()) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (log)
- log->Printf("UnwindPlan::GetLastRow() when rows are empty");
+ LLDB_LOGF(log, "UnwindPlan::GetLastRow() when rows are empty");
return UnwindPlan::RowSP();
}
return m_row_list.back();
@@ -434,13 +437,14 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
if (log) {
StreamString s;
if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) {
- log->Printf("UnwindPlan is invalid -- no unwind rows for UnwindPlan "
- "'%s' at address %s",
- m_source_name.GetCString(), s.GetData());
+ LLDB_LOGF(log,
+ "UnwindPlan is invalid -- no unwind rows for UnwindPlan "
+ "'%s' at address %s",
+ m_source_name.GetCString(), s.GetData());
} else {
- log->Printf(
- "UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
- m_source_name.GetCString());
+ LLDB_LOGF(log,
+ "UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
+ m_source_name.GetCString());
}
}
return false;
@@ -456,13 +460,15 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
if (log) {
StreamString s;
if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) {
- log->Printf("UnwindPlan is invalid -- no CFA register defined in row 0 "
- "for UnwindPlan '%s' at address %s",
- m_source_name.GetCString(), s.GetData());
+ LLDB_LOGF(log,
+ "UnwindPlan is invalid -- no CFA register defined in row 0 "
+ "for UnwindPlan '%s' at address %s",
+ m_source_name.GetCString(), s.GetData());
} else {
- log->Printf("UnwindPlan is invalid -- no CFA register defined in row 0 "
- "for UnwindPlan '%s'",
- m_source_name.GetCString());
+ LLDB_LOGF(log,
+ "UnwindPlan is invalid -- no CFA register defined in row 0 "
+ "for UnwindPlan '%s'",
+ m_source_name.GetCString());
}
}
return false;
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index a8f451dc4643..045957a67b3b 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
+#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/FuncUnwinders.h"
@@ -29,7 +30,8 @@ using namespace lldb_private;
UnwindTable::UnwindTable(Module &module)
: m_module(module), m_unwinds(), m_initialized(false), m_mutex(),
- m_eh_frame_up(), m_compact_unwind_up(), m_arm_unwind_up() {}
+ m_object_file_unwind_up(), m_eh_frame_up(), m_compact_unwind_up(),
+ m_arm_unwind_up() {}
// We can't do some of this initialization when the ObjectFile is running its
// ctor; delay doing it until needed for something.
@@ -47,6 +49,8 @@ void UnwindTable::Initialize() {
if (!object_file)
return;
+ m_object_file_unwind_up = object_file->CreateCallFrameInfo();
+
SectionList *sl = m_module.GetSectionList();
if (!sl)
return;
@@ -83,7 +87,12 @@ llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr,
SymbolContext &sc) {
AddressRange range;
- // First check the symbol context
+ // First check the unwind info from the object file plugin
+ if (m_object_file_unwind_up &&
+ m_object_file_unwind_up->GetAddressRange(addr, range))
+ return range;
+
+ // Check the symbol context
if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
false, range) &&
range.GetBaseAddress().IsValid())
@@ -162,6 +171,11 @@ void UnwindTable::Dump(Stream &s) {
s.EOL();
}
+lldb_private::CallFrameInfo *UnwindTable::GetObjectFileUnwindInfo() {
+ Initialize();
+ return m_object_file_unwind_up.get();
+}
+
DWARFCallFrameInfo *UnwindTable::GetEHFrameInfo() {
Initialize();
return m_eh_frame_up.get();
@@ -182,11 +196,7 @@ ArmUnwindInfo *UnwindTable::GetArmUnwindInfo() {
return m_arm_unwind_up.get();
}
-SymbolFile *UnwindTable::GetSymbolFile() {
- if (SymbolVendor *vendor = m_module.GetSymbolVendor())
- return vendor->GetSymbolFile();
- return nullptr;
-}
+SymbolFile *UnwindTable::GetSymbolFile() { return m_module.GetSymbolFile(); }
ArchSpec UnwindTable::GetArchitecture() { return m_module.GetArchitecture(); }
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index 29a7a5191f61..3f3d7c198f15 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -35,14 +35,12 @@
using namespace lldb;
using namespace lldb_private;
-// Variable constructor
-Variable::Variable(
- lldb::user_id_t uid, const char *name,
- const char *mangled, // The mangled or fully qualified name of the variable.
- const lldb::SymbolFileTypeSP &symfile_type_sp, ValueType scope,
- SymbolContextScope *context, const RangeList &scope_range,
- Declaration *decl_ptr, const DWARFExpression &location, bool external,
- bool artificial, bool static_member)
+Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
+ const lldb::SymbolFileTypeSP &symfile_type_sp,
+ ValueType scope, SymbolContextScope *context,
+ const RangeList &scope_range, Declaration *decl_ptr,
+ const DWARFExpression &location, bool external,
+ bool artificial, bool static_member)
: UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
m_symfile_type_sp(symfile_type_sp), m_scope(scope),
m_owner_scope(context), m_scope_range(scope_range),
@@ -50,14 +48,22 @@ Variable::Variable(
m_artificial(artificial), m_loc_is_const_data(false),
m_static_member(static_member) {}
-// Destructor
Variable::~Variable() {}
lldb::LanguageType Variable::GetLanguage() const {
- SymbolContext variable_sc;
- m_owner_scope->CalculateSymbolContext(&variable_sc);
- if (variable_sc.comp_unit)
- return variable_sc.comp_unit->GetLanguage();
+ lldb::LanguageType lang = m_mangled.GuessLanguage();
+ if (lang != lldb::eLanguageTypeUnknown)
+ return lang;
+
+ if (auto *func = m_owner_scope->CalculateSymbolContextFunction()) {
+ if ((lang = func->GetLanguage()) != lldb::eLanguageTypeUnknown)
+ return lang;
+ } else if (auto *comp_unit =
+ m_owner_scope->CalculateSymbolContextCompileUnit()) {
+ if ((lang = comp_unit->GetLanguage()) != lldb::eLanguageTypeUnknown)
+ return lang;
+ }
+
return lldb::eLanguageTypeUnknown;
}
@@ -381,21 +387,15 @@ Status Variable::GetValuesForVariableExpressionPath(
default: {
static RegularExpression g_regex(
llvm::StringRef("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)"));
- RegularExpression::Match regex_match(1);
- std::string variable_name;
+ llvm::SmallVector<llvm::StringRef, 2> matches;
variable_list.Clear();
- if (!g_regex.Execute(variable_expr_path, &regex_match)) {
- error.SetErrorStringWithFormat(
- "unable to extract a variable name from '%s'",
- variable_expr_path.str().c_str());
- return error;
- }
- if (!regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name)) {
+ if (!g_regex.Execute(variable_expr_path, &matches)) {
error.SetErrorStringWithFormat(
"unable to extract a variable name from '%s'",
variable_expr_path.str().c_str());
return error;
}
+ std::string variable_name = matches[1].str();
if (!callback(baton, variable_name.c_str(), variable_list)) {
error.SetErrorString("unknown error");
return error;
@@ -485,24 +485,21 @@ static void PrivateAutoComplete(
StackFrame *frame, llvm::StringRef partial_path,
const llvm::Twine
&prefix_path, // Anything that has been resolved already will be in here
- const CompilerType &compiler_type,
- StringList &matches, bool &word_complete);
+ const CompilerType &compiler_type, CompletionRequest &request);
static void PrivateAutoCompleteMembers(
StackFrame *frame, const std::string &partial_member_name,
llvm::StringRef partial_path,
const llvm::Twine
&prefix_path, // Anything that has been resolved already will be in here
- const CompilerType &compiler_type,
- StringList &matches, bool &word_complete);
+ const CompilerType &compiler_type, CompletionRequest &request);
static void PrivateAutoCompleteMembers(
StackFrame *frame, const std::string &partial_member_name,
llvm::StringRef partial_path,
const llvm::Twine
&prefix_path, // Anything that has been resolved already will be in here
- const CompilerType &compiler_type,
- StringList &matches, bool &word_complete) {
+ const CompilerType &compiler_type, CompletionRequest &request) {
// We are in a type parsing child members
const uint32_t num_bases = compiler_type.GetNumDirectBaseClasses();
@@ -512,9 +509,9 @@ static void PrivateAutoCompleteMembers(
CompilerType base_class_type =
compiler_type.GetDirectBaseClassAtIndex(i, nullptr);
- PrivateAutoCompleteMembers(
- frame, partial_member_name, partial_path, prefix_path,
- base_class_type.GetCanonicalType(), matches, word_complete);
+ PrivateAutoCompleteMembers(frame, partial_member_name, partial_path,
+ prefix_path,
+ base_class_type.GetCanonicalType(), request);
}
}
@@ -525,9 +522,9 @@ static void PrivateAutoCompleteMembers(
CompilerType vbase_class_type =
compiler_type.GetVirtualBaseClassAtIndex(i, nullptr);
- PrivateAutoCompleteMembers(
- frame, partial_member_name, partial_path, prefix_path,
- vbase_class_type.GetCanonicalType(), matches, word_complete);
+ PrivateAutoCompleteMembers(frame, partial_member_name, partial_path,
+ prefix_path,
+ vbase_class_type.GetCanonicalType(), request);
}
}
@@ -548,9 +545,9 @@ static void PrivateAutoCompleteMembers(
frame, partial_path,
prefix_path + member_name, // Anything that has been resolved
// already will be in here
- member_compiler_type.GetCanonicalType(), matches, word_complete);
+ member_compiler_type.GetCanonicalType(), request);
} else {
- matches.AppendString((prefix_path + member_name).str());
+ request.AddCompletion((prefix_path + member_name).str());
}
}
}
@@ -561,8 +558,7 @@ static void PrivateAutoComplete(
StackFrame *frame, llvm::StringRef partial_path,
const llvm::Twine
&prefix_path, // Anything that has been resolved already will be in here
- const CompilerType &compiler_type,
- StringList &matches, bool &word_complete) {
+ const CompilerType &compiler_type, CompletionRequest &request) {
// printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path =
// '%s'\n", prefix_path.c_str(), partial_path.c_str());
std::string remaining_partial_path;
@@ -583,15 +579,14 @@ static void PrivateAutoComplete(
case eTypeClassReference:
case eTypeClassTypedef:
case eTypeClassVector: {
- matches.AppendString(prefix_path.str());
- word_complete = matches.GetSize() == 1;
+ request.AddCompletion(prefix_path.str());
} break;
case eTypeClassClass:
case eTypeClassStruct:
case eTypeClassUnion:
if (prefix_path.str().back() != '.')
- matches.AppendString((prefix_path + ".").str());
+ request.AddCompletion((prefix_path + ".").str());
break;
case eTypeClassObjCObject:
@@ -601,10 +596,9 @@ static void PrivateAutoComplete(
case eTypeClassPointer: {
bool omit_empty_base_classes = true;
if (compiler_type.GetNumChildren(omit_empty_base_classes, nullptr) > 0)
- matches.AppendString((prefix_path + "->").str());
+ request.AddCompletion((prefix_path + "->").str());
else {
- matches.AppendString(prefix_path.str());
- word_complete = true;
+ request.AddCompletion(prefix_path.str());
}
} break;
}
@@ -618,7 +612,7 @@ static void PrivateAutoComplete(
const size_t num_variables = variable_list->GetSize();
for (size_t i = 0; i < num_variables; ++i) {
Variable *variable = variable_list->GetVariableAtIndex(i).get();
- matches.AppendString(variable->GetName().AsCString());
+ request.AddCompletion(variable->GetName().AsCString());
}
}
}
@@ -629,14 +623,14 @@ static void PrivateAutoComplete(
case '*':
if (prefix_path.str().empty()) {
PrivateAutoComplete(frame, partial_path.substr(1), "*", compiler_type,
- matches, word_complete);
+ request);
}
break;
case '&':
if (prefix_path.isTriviallyEmpty()) {
PrivateAutoComplete(frame, partial_path.substr(1), std::string("&"),
- compiler_type, matches, word_complete);
+ compiler_type, request);
}
break;
@@ -648,14 +642,14 @@ static void PrivateAutoComplete(
CompilerType pointee_type(compiler_type.GetPointeeType());
if (partial_path.size() > 2 && partial_path[2]) {
// If there is more after the "->", then search deeper
- PrivateAutoComplete(
- frame, partial_path.substr(2), prefix_path + "->",
- pointee_type.GetCanonicalType(), matches, word_complete);
+ PrivateAutoComplete(frame, partial_path.substr(2),
+ prefix_path + "->",
+ pointee_type.GetCanonicalType(), request);
} else {
// Nothing after the "->", so list all members
PrivateAutoCompleteMembers(
frame, std::string(), std::string(), prefix_path + "->",
- pointee_type.GetCanonicalType(), matches, word_complete);
+ pointee_type.GetCanonicalType(), request);
}
} break;
default:
@@ -673,14 +667,13 @@ static void PrivateAutoComplete(
if (partial_path.size() > 1 && partial_path[1]) {
// If there is more after the ".", then search deeper
PrivateAutoComplete(frame, partial_path.substr(1),
- prefix_path + ".", compiler_type, matches,
- word_complete);
+ prefix_path + ".", compiler_type, request);
} else {
// Nothing after the ".", so list all members
PrivateAutoCompleteMembers(frame, std::string(), partial_path,
prefix_path + ".", compiler_type,
- matches, word_complete);
+ request);
}
break;
default:
@@ -706,8 +699,7 @@ static void PrivateAutoComplete(
if (compiler_type.IsValid()) {
PrivateAutoCompleteMembers(frame, token, remaining_partial_path,
- prefix_path, compiler_type, matches,
- word_complete);
+ prefix_path, compiler_type, request);
} else if (frame) {
// We haven't found our variable yet
const bool get_file_globals = true;
@@ -736,13 +728,12 @@ static void PrivateAutoComplete(
frame, remaining_partial_path,
prefix_path + token, // Anything that has been resolved
// already will be in here
- variable_compiler_type.GetCanonicalType(), matches,
- word_complete);
+ variable_compiler_type.GetCanonicalType(), request);
} else {
- matches.AppendString((prefix_path + variable_name).str());
+ request.AddCompletion((prefix_path + variable_name).str());
}
} else if (remaining_partial_path.empty()) {
- matches.AppendString((prefix_path + variable_name).str());
+ request.AddCompletion((prefix_path + variable_name).str());
}
}
}
@@ -753,16 +744,10 @@ static void PrivateAutoComplete(
}
}
-size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
- CompletionRequest &request) {
+void Variable::AutoComplete(const ExecutionContext &exe_ctx,
+ CompletionRequest &request) {
CompilerType compiler_type;
- bool word_complete = false;
- StringList matches;
PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
- "", compiler_type, matches, word_complete);
- request.SetWordComplete(word_complete);
- request.AddCompletions(matches);
-
- return request.GetNumberOfMatches();
+ "", compiler_type, request);
}
diff --git a/source/Symbol/VerifyDecl.cpp b/source/Symbol/VerifyDecl.cpp
deleted file mode 100644
index 1873d3a5d03c..000000000000
--- a/source/Symbol/VerifyDecl.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-//===-- VerifyDecl.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/VerifyDecl.h"
-#include "clang/AST/DeclBase.h"
-
-void lldb_private::VerifyDecl(clang::Decl *decl) {
- assert(decl && "VerifyDecl called with nullptr?");
- decl->getAccess();
-}
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
index 28cd9aec665c..005261e0ddee 100644
--- a/source/Target/ABI.cpp
+++ b/source/Target/ABI.cpp
@@ -15,6 +15,8 @@
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/Support/TargetRegistry.h"
using namespace lldb;
using namespace lldb_private;
@@ -210,3 +212,20 @@ bool ABI::GetFallbackRegisterLocation(
return false;
}
+
+std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) {
+ std::string triple = arch.GetTriple().getTriple();
+ std::string lookup_error;
+ const llvm::Target *target =
+ llvm::TargetRegistry::lookupTarget(triple, lookup_error);
+ if (!target) {
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS),
+ "Failed to create an llvm target for {0}: {1}", triple,
+ lookup_error);
+ return nullptr;
+ }
+ std::unique_ptr<llvm::MCRegisterInfo> info_up(
+ target->createMCRegInfo(triple));
+ assert(info_up);
+ return info_up;
+}
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
index 77327372f88b..a24a098eb300 100644
--- a/source/Target/ExecutionContext.cpp
+++ b/source/Target/ExecutionContext.cpp
@@ -183,9 +183,9 @@ uint32_t ExecutionContext::GetAddressByteSize() const {
lldb::ByteOrder ExecutionContext::GetByteOrder() const {
if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
- m_target_sp->GetArchitecture().GetByteOrder();
+ return m_target_sp->GetArchitecture().GetByteOrder();
if (m_process_sp)
- m_process_sp->GetByteOrder();
+ return m_process_sp->GetByteOrder();
return endian::InlHostByteOrder();
}
diff --git a/source/Target/Language.cpp b/source/Target/Language.cpp
index 3c3ef2841d44..43d0be0f737c 100644
--- a/source/Target/Language.cpp
+++ b/source/Target/Language.cpp
@@ -357,26 +357,16 @@ std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
return supported_languages;
}
-void Language::GetLanguagesSupportingTypeSystems(
- std::set<lldb::LanguageType> &languages,
- std::set<lldb::LanguageType> &languages_for_expressions) {
- uint32_t idx = 0;
-
- while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::
- GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) {
- (*enumerate)(languages, languages_for_expressions);
- }
+LanguageSet Language::GetLanguagesSupportingTypeSystems() {
+ return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
}
-void Language::GetLanguagesSupportingREPLs(
- std::set<lldb::LanguageType> &languages) {
- uint32_t idx = 0;
+LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() {
+ return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions();
+}
- while (REPLEnumerateSupportedLanguages enumerate =
- PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(
- idx++)) {
- (*enumerate)(languages);
- }
+LanguageSet Language::GetLanguagesSupportingREPLs() {
+ return PluginManager::GetREPLAllTypeSystemSupportedLanguages();
}
std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index dd4415810613..999ac99e93c3 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/source/Target/LanguageRuntime.cpp
@@ -111,12 +111,11 @@ public:
~ExceptionBreakpointResolver() override = default;
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
- SymbolContext &context, Address *addr,
- bool containing) override {
+ SymbolContext &context,
+ Address *addr) override {
if (SetActualResolver())
- return m_actual_resolver_sp->SearchCallback(filter, context, addr,
- containing);
+ return m_actual_resolver_sp->SearchCallback(filter, context, addr);
else
return eCallbackReturnStop;
}
diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp
index 31a378069cec..7c77cc06eb03 100644
--- a/source/Target/Memory.cpp
+++ b/source/Target/Memory.cpp
@@ -348,10 +348,11 @@ AllocatedMemoryCache::AllocatePage(uint32_t byte_size, uint32_t permissions,
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log) {
- log->Printf("Process::DoAllocateMemory (byte_size = 0x%8.8" PRIx32
- ", permissions = %s) => 0x%16.16" PRIx64,
- (uint32_t)page_byte_size, GetPermissionsAsCString(permissions),
- (uint64_t)addr);
+ LLDB_LOGF(log,
+ "Process::DoAllocateMemory (byte_size = 0x%8.8" PRIx32
+ ", permissions = %s) => 0x%16.16" PRIx64,
+ (uint32_t)page_byte_size, GetPermissionsAsCString(permissions),
+ (uint64_t)addr);
}
if (addr != LLDB_INVALID_ADDRESS) {
@@ -385,12 +386,11 @@ lldb::addr_t AllocatedMemoryCache::AllocateMemory(size_t byte_size,
addr = block_sp->ReserveBlock(byte_size);
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8" PRIx32
- ", permissions = %s) => 0x%16.16" PRIx64,
- (uint32_t)byte_size, GetPermissionsAsCString(permissions),
- (uint64_t)addr);
+ LLDB_LOGF(log,
+ "AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8" PRIx32
+ ", permissions = %s) => 0x%16.16" PRIx64,
+ (uint32_t)byte_size, GetPermissionsAsCString(permissions),
+ (uint64_t)addr);
return addr;
}
@@ -406,9 +406,9 @@ bool AllocatedMemoryCache::DeallocateMemory(lldb::addr_t addr) {
}
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16" PRIx64
- ") => %i",
- (uint64_t)addr, success);
+ LLDB_LOGF(log,
+ "AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16" PRIx64
+ ") => %i",
+ (uint64_t)addr, success);
return success;
}
diff --git a/source/Target/ModuleCache.cpp b/source/Target/ModuleCache.cpp
index 444c9806f98b..124cdacfb4d2 100644
--- a/source/Target/ModuleCache.cpp
+++ b/source/Target/ModuleCache.cpp
@@ -48,7 +48,7 @@ std::string GetEscapedHostname(const char *hostname) {
class ModuleLock {
private:
- File m_file;
+ FileUP m_file_up;
std::unique_ptr<lldb_private::LockFile> m_lock;
FileSpec m_file_spec;
@@ -94,9 +94,8 @@ void DeleteExistingModule(const FileSpec &root_dir_spec,
Status error;
ModuleLock lock(root_dir_spec, module_uuid, error);
if (error.Fail()) {
- if (log)
- log->Printf("Failed to lock module %s: %s",
- module_uuid.GetAsString().c_str(), error.AsCString());
+ LLDB_LOGF(log, "Failed to lock module %s: %s",
+ module_uuid.GetAsString().c_str(), error.AsCString());
}
namespace fs = llvm::sys::fs;
@@ -158,16 +157,19 @@ ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid,
return;
m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str());
- FileSystem::Instance().Open(m_file, m_file_spec,
- File::eOpenOptionWrite |
- File::eOpenOptionCanCreate |
- File::eOpenOptionCloseOnExec);
- if (!m_file) {
- error.SetErrorToErrno();
+
+ auto file = FileSystem::Instance().Open(
+ m_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec);
+ if (file)
+ m_file_up = std::move(file.get());
+ else {
+ m_file_up.reset();
+ error = Status(file.takeError());
return;
}
- m_lock.reset(new lldb_private::LockFile(m_file.GetDescriptor()));
+ m_lock.reset(new lldb_private::LockFile(m_file_up->GetDescriptor()));
error = m_lock->WriteLock(0, 1);
if (error.Fail())
error.SetErrorStringWithFormat("Failed to lock file: %s",
@@ -175,10 +177,11 @@ ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid,
}
void ModuleLock::Delete() {
- if (!m_file)
+ if (!m_file_up)
return;
- m_file.Close();
+ m_file_up->Close();
+ m_file_up.reset();
llvm::sys::fs::remove(m_file_spec.GetPath());
}
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 710f82eaefa9..c9849a9e5f09 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -63,13 +63,13 @@ const char *Platform::GetHostPlatformName() { return "host"; }
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"use-module-cache", OptionValue::eTypeBoolean, true, true, nullptr,
- {}, "Use module cache."},
- {"module-cache-directory", OptionValue::eTypeFileSpec, true, 0, nullptr,
- {}, "Root directory for cached modules."}};
+#define LLDB_PROPERTIES_platform
+#include "TargetProperties.inc"
-enum { ePropertyUseModuleCache, ePropertyModuleCacheDirectory };
+enum {
+#define LLDB_PROPERTIES_platform
+#include "TargetPropertiesEnum.inc"
+};
} // namespace
@@ -80,7 +80,7 @@ ConstString PlatformProperties::GetSettingName() {
PlatformProperties::PlatformProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_platform_properties);
auto module_cache_dir = GetModuleCacheDirectory();
if (module_cache_dir)
@@ -99,7 +99,7 @@ PlatformProperties::PlatformProperties() {
bool PlatformProperties::GetUseModuleCache() const {
const auto idx = ePropertyUseModuleCache;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_platform_properties[idx].default_uint_value != 0);
}
bool PlatformProperties::SetUseModuleCache(bool use_module_cache) {
@@ -384,10 +384,9 @@ Platform::Platform(bool is_host)
m_rsync_opts(), m_rsync_prefix(), m_supports_ssh(false), m_ssh_opts(),
m_ignores_remote_hostname(false), m_trap_handlers(),
m_calculated_trap_handlers(false),
- m_module_cache(llvm::make_unique<ModuleCache>()) {
+ m_module_cache(std::make_unique<ModuleCache>()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Platform::Platform()", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this));
}
/// Destructor.
@@ -396,8 +395,7 @@ Platform::Platform(bool is_host)
/// inherited from by the plug-in instance.
Platform::~Platform() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Platform::~Platform()", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p Platform::~Platform()", static_cast<void *>(this));
}
void Platform::GetStatus(Stream &strm) {
@@ -637,9 +635,8 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) {
Status error;
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("Platform::Install (src='%s', dst='%s')", src.GetPath().c_str(),
- dst.GetPath().c_str());
+ LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s')",
+ src.GetPath().c_str(), dst.GetPath().c_str());
FileSpec fixed_dst(dst);
if (!fixed_dst.GetFilename())
@@ -690,10 +687,9 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) {
}
}
- if (log)
- log->Printf("Platform::Install (src='%s', dst='%s') fixed_dst='%s'",
- src.GetPath().c_str(), dst.GetPath().c_str(),
- fixed_dst.GetPath().c_str());
+ LLDB_LOGF(log, "Platform::Install (src='%s', dst='%s') fixed_dst='%s'",
+ src.GetPath().c_str(), dst.GetPath().c_str(),
+ fixed_dst.GetPath().c_str());
if (GetSupportsRSync()) {
error = PutFile(src, dst);
@@ -821,9 +817,8 @@ ConstString Platform::GetFullNameForDylib(ConstString basename) {
bool Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir) {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (log)
- log->Printf("Platform::SetRemoteWorkingDirectory('%s')",
- working_dir.GetCString());
+ LLDB_LOGF(log, "Platform::SetRemoteWorkingDirectory('%s')",
+ working_dir.GetCString());
m_working_dir = working_dir;
return true;
}
@@ -1010,8 +1005,7 @@ uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status error;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Platform::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "Platform::%s()", __FUNCTION__);
// Take care of the host case so that each subclass can just call this
// function to get the host functionality.
@@ -1027,10 +1021,10 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
if (log) {
const FileSpec &shell = launch_info.GetShell();
std::string shell_str = (shell) ? shell.GetPath() : "<null>";
- log->Printf(
- "Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32
- ", shell is '%s'",
- __FUNCTION__, num_resumes, shell_str.c_str());
+ LLDB_LOGF(log,
+ "Platform::%s GetResumeCountForLaunchInfo() returned %" PRIu32
+ ", shell is '%s'",
+ __FUNCTION__, num_resumes, shell_str.c_str());
}
if (!launch_info.ConvertArgumentsForLaunchingInShell(
@@ -1048,9 +1042,8 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
}
}
- if (log)
- log->Printf("Platform::%s final launch_info resume count: %" PRIu32,
- __FUNCTION__, launch_info.GetResumeCount());
+ LLDB_LOGF(log, "Platform::%s final launch_info resume count: %" PRIu32,
+ __FUNCTION__, launch_info.GetResumeCount());
error = Host::LaunchProcess(launch_info);
} else
@@ -1067,8 +1060,7 @@ Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
Status Platform::KillProcess(const lldb::pid_t pid) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
+ LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
// Try to find a process plugin to handle this Kill request. If we can't,
// fall back to the default OS implementation.
@@ -1098,9 +1090,8 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// new target, else use existing one
Status &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Platform::%s entered (target %p)", __FUNCTION__,
- static_cast<void *>(target));
+ LLDB_LOGF(log, "Platform::%s entered (target %p)", __FUNCTION__,
+ static_cast<void *>(target));
ProcessSP process_sp;
// Make sure we stop at the entry point
@@ -1124,10 +1115,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Give this ProcessLaunchInfo filter a chance to adjust the launch info.
error = (*filter_callback)(launch_info, target);
if (!error.Success()) {
- if (log)
- log->Printf("Platform::%s() StructuredDataPlugin launch "
- "filter failed.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Platform::%s() StructuredDataPlugin launch "
+ "filter failed.",
+ __FUNCTION__);
return process_sp;
}
}
@@ -1135,17 +1126,15 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
error = LaunchProcess(launch_info);
if (error.Success()) {
- if (log)
- log->Printf("Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64
- ")",
- __FUNCTION__, launch_info.GetProcessID());
+ LLDB_LOGF(log,
+ "Platform::%s LaunchProcess() call succeeded (pid=%" PRIu64 ")",
+ __FUNCTION__, launch_info.GetProcessID());
if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
ProcessAttachInfo attach_info(launch_info);
process_sp = Attach(attach_info, debugger, target, error);
if (process_sp) {
- if (log)
- log->Printf("Platform::%s Attach() succeeded, Process plugin: %s",
- __FUNCTION__, process_sp->GetPluginName().AsCString());
+ LLDB_LOGF(log, "Platform::%s Attach() succeeded, Process plugin: %s",
+ __FUNCTION__, process_sp->GetPluginName().AsCString());
launch_info.SetHijackListener(attach_info.GetHijackListener());
// Since we attached to the process, it will think it needs to detach
@@ -1163,20 +1152,18 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
process_sp->SetSTDIOFileDescriptor(pty_fd);
}
} else {
- if (log)
- log->Printf("Platform::%s Attach() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "Platform::%s Attach() failed: %s", __FUNCTION__,
+ error.AsCString());
}
} else {
- if (log)
- log->Printf("Platform::%s LaunchProcess() returned launch_info with "
- "invalid process id",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Platform::%s LaunchProcess() returned launch_info with "
+ "invalid process id",
+ __FUNCTION__);
}
} else {
- if (log)
- log->Printf("Platform::%s LaunchProcess() failed: %s", __FUNCTION__,
- error.AsCString());
+ LLDB_LOGF(log, "Platform::%s LaunchProcess() failed: %s", __FUNCTION__,
+ error.AsCString());
}
return process_sp;
@@ -1231,30 +1218,28 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch,
Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
uint32_t uid, uint32_t gid) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("[PutFile] Using block by block transfer....\n");
+ LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n");
- uint32_t source_open_options =
+ auto source_open_options =
File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
namespace fs = llvm::sys::fs;
if (fs::is_symlink_file(source.GetPath()))
source_open_options |= File::eOpenOptionDontFollowSymlinks;
- File source_file;
- Status error = FileSystem::Instance().Open(
- source_file, source, source_open_options, lldb::eFilePermissionsUserRW);
- uint32_t permissions = source_file.GetPermissions(error);
+ auto source_file = FileSystem::Instance().Open(source, source_open_options,
+ lldb::eFilePermissionsUserRW);
+ if (!source_file)
+ return Status(source_file.takeError());
+ Status error;
+ uint32_t permissions = source_file.get()->GetPermissions(error);
if (permissions == 0)
permissions = lldb::eFilePermissionsFileDefault;
- if (!source_file.IsValid())
- return Status("PutFile: unable to open source file");
lldb::user_id_t dest_file = OpenFile(
destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite |
File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec,
permissions, error);
- if (log)
- log->Printf("dest_file = %" PRIu64 "\n", dest_file);
+ LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file);
if (error.Fail())
return error;
@@ -1264,7 +1249,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
uint64_t offset = 0;
for (;;) {
size_t bytes_read = buffer_sp->GetByteSize();
- error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
+ error = source_file.get()->Read(buffer_sp->GetBytes(), bytes_read);
if (error.Fail() || bytes_read == 0)
break;
@@ -1277,7 +1262,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
if (bytes_written != bytes_read) {
// We didn't write the correct number of bytes, so adjust the file
// position in the source file we are reading from...
- source_file.SeekFromStart(offset);
+ source_file.get()->SeekFromStart(offset);
}
}
CloseFile(dest_file, error);
@@ -1630,10 +1615,9 @@ bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec,
if (error.Success())
return true;
- if (log)
- log->Printf("Platform::%s - module %s not found in local cache: %s",
- __FUNCTION__, module_spec.GetUUID().GetAsString().c_str(),
- error.AsCString());
+ LLDB_LOGF(log, "Platform::%s - module %s not found in local cache: %s",
+ __FUNCTION__, module_spec.GetUUID().GetAsString().c_str(),
+ error.AsCString());
return false;
}
@@ -1644,7 +1628,7 @@ Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec,
Status error;
std::error_code EC;
- llvm::raw_fd_ostream dst(dst_file_spec.GetPath(), EC, llvm::sys::fs::F_None);
+ llvm::raw_fd_ostream dst(dst_file_spec.GetPath(), EC, llvm::sys::fs::OF_None);
if (EC) {
error.SetErrorStringWithFormat("unable to open destination file: %s",
dst_file_spec.GetPath().c_str());
@@ -1736,7 +1720,7 @@ uint32_t Platform::LoadImage(lldb_private::Process *process,
return LLDB_INVALID_IMAGE_TOKEN;
}
return DoLoadImage(process, target_file, nullptr, error);
- }
+ }
if (remote_file) {
// Only remote file was specified so we don't have to do any copying
@@ -1769,7 +1753,7 @@ uint32_t Platform::LoadImageUsingPaths(lldb_private::Process *process,
remote_filename.GetPathStyle());
else
file_to_use = remote_filename;
-
+
return DoLoadImage(process, file_to_use, &paths, error, loaded_path);
}
@@ -1812,8 +1796,7 @@ lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url,
if (!process_sp)
return nullptr;
- error =
- process_sp->ConnectRemote(debugger.GetOutputFile().get(), connect_url);
+ error = process_sp->ConnectRemote(&debugger.GetOutputStream(), connect_url);
if (error.Fail())
return nullptr;
@@ -1833,12 +1816,19 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
size_t trap_opcode_size = 0;
switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64_32:
case llvm::Triple::aarch64: {
static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
trap_opcode = g_aarch64_opcode;
trap_opcode_size = sizeof(g_aarch64_opcode);
} break;
+ case llvm::Triple::arc: {
+ static const uint8_t g_hex_opcode[] = { 0xff, 0x7f };
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ } break;
+
// TODO: support big-endian arm and thumb trap codes.
case llvm::Triple::arm: {
// The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 6c634dba00c7..ed0b951fbce1 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -13,7 +13,6 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/Threading.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
@@ -59,6 +58,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanBase.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Log.h"
@@ -112,55 +112,12 @@ public:
}
};
-static constexpr PropertyDefinition g_properties[] = {
- {"disable-memory-cache", OptionValue::eTypeBoolean, false,
- DISABLE_MEM_CACHE_DEFAULT, nullptr, {},
- "Disable reading and caching of memory in fixed-size units."},
- {"extra-startup-command", OptionValue::eTypeArray, false,
- OptionValue::eTypeString, nullptr, {},
- "A list containing extra commands understood by the particular process "
- "plugin used. "
- "For instance, to turn on debugserver logging set this to "
- "\"QSetLogging:bitmask=LOG_DEFAULT;\""},
- {"ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true,
- nullptr, {},
- "If true, breakpoints will be ignored during expression evaluation."},
- {"unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true,
- nullptr, {}, "If true, errors in expression evaluation will unwind "
- "the stack back to the state before the call."},
- {"python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr,
- {}, "A path to a python OS plug-in module file that contains a "
- "OperatingSystemPlugIn class."},
- {"stop-on-sharedlibrary-events", OptionValue::eTypeBoolean, true, false,
- nullptr, {},
- "If true, stop when a shared library is loaded or unloaded."},
- {"detach-keeps-stopped", OptionValue::eTypeBoolean, true, false, nullptr,
- {}, "If true, detach will attempt to keep the process stopped."},
- {"memory-cache-line-size", OptionValue::eTypeUInt64, false, 512, nullptr,
- {}, "The memory cache line size"},
- {"optimization-warnings", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "If true, warn when stopped in code that is optimized where "
- "stepping and variable availability may not behave as expected."},
- {"stop-on-exec", OptionValue::eTypeBoolean, true, true,
- nullptr, {},
- "If true, stop when a shared library is loaded or unloaded."},
- {"utility-expression-timeout", OptionValue::eTypeUInt64, false, 15,
- nullptr, {},
- "The time in seconds to wait for LLDB-internal utility expressions."}
-};
+#define LLDB_PROPERTIES_process
+#include "TargetProperties.inc"
enum {
- ePropertyDisableMemCache,
- ePropertyExtraStartCommand,
- ePropertyIgnoreBreakpointsInExpressions,
- ePropertyUnwindOnErrorInExpressions,
- ePropertyPythonOSPluginPath,
- ePropertyStopOnSharedLibraryEvents,
- ePropertyDetachKeepsStopped,
- ePropertyMemCacheLineSize,
- ePropertyWarningOptimization,
- ePropertyStopOnExec,
- ePropertyUtilityExpressionTimeout,
+#define LLDB_PROPERTIES_process
+#include "TargetPropertiesEnum.inc"
};
ProcessProperties::ProcessProperties(lldb_private::Process *process)
@@ -171,7 +128,7 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process)
// Global process properties, set them up one time
m_collection_sp =
std::make_shared<ProcessOptionValueProperties>(ConstString("process"));
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_process_properties);
m_collection_sp->AppendProperty(
ConstString("thread"), ConstString("Settings specific to threads."),
true, Thread::GetGlobalProperties()->GetValueProperties());
@@ -196,13 +153,13 @@ void ProcessProperties::OptionValueChangedCallback(void *baton,
bool ProcessProperties::GetDisableMemoryCache() const {
const uint32_t idx = ePropertyDisableMemCache;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
uint64_t ProcessProperties::GetMemoryCacheLineSize() const {
const uint32_t idx = ePropertyMemCacheLineSize;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_process_properties[idx].default_uint_value);
}
Args ProcessProperties::GetExtraStartupCommands() const {
@@ -230,7 +187,7 @@ void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) {
bool ProcessProperties::GetIgnoreBreakpointsInExpressions() const {
const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
void ProcessProperties::SetIgnoreBreakpointsInExpressions(bool ignore) {
@@ -241,7 +198,7 @@ void ProcessProperties::SetIgnoreBreakpointsInExpressions(bool ignore) {
bool ProcessProperties::GetUnwindOnErrorInExpressions() const {
const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
void ProcessProperties::SetUnwindOnErrorInExpressions(bool ignore) {
@@ -252,7 +209,7 @@ void ProcessProperties::SetUnwindOnErrorInExpressions(bool ignore) {
bool ProcessProperties::GetStopOnSharedLibraryEvents() const {
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) {
@@ -263,7 +220,7 @@ void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) {
bool ProcessProperties::GetDetachKeepsStopped() const {
const uint32_t idx = ePropertyDetachKeepsStopped;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
void ProcessProperties::SetDetachKeepsStopped(bool stop) {
@@ -274,19 +231,19 @@ void ProcessProperties::SetDetachKeepsStopped(bool stop) {
bool ProcessProperties::GetWarningsOptimization() const {
const uint32_t idx = ePropertyWarningOptimization;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
bool ProcessProperties::GetStopOnExec() const {
const uint32_t idx = ePropertyStopOnExec;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
}
std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const {
const uint32_t idx = ePropertyUtilityExpressionTimeout;
uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_process_properties[idx].default_uint_value);
return std::chrono::seconds(value);
}
@@ -544,8 +501,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
CheckInWithManager();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Process::Process()", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p Process::Process()", static_cast<void *>(this));
if (!m_unix_signals_sp)
m_unix_signals_sp = std::make_shared<UnixSignals>();
@@ -593,8 +549,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
Process::~Process() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Process::~Process()", static_cast<void *>(this));
+ LLDB_LOGF(log, "%p Process::~Process()", static_cast<void *>(this));
StopPrivateStateThread();
// ThreadList::Clear() will try to acquire this process's mutex, so
@@ -781,10 +736,10 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout,
if (!wait_always && StateIsStoppedState(state, true) &&
StateIsStoppedState(GetPrivateState(), true)) {
- if (log)
- log->Printf("Process::%s returning without waiting for events; process "
- "private and public states are already 'stopped'.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Process::%s returning without waiting for events; process "
+ "private and public states are already 'stopped'.",
+ __FUNCTION__);
// We need to toggle the run lock as this won't get done in
// SetPublicState() if the process is hijacked.
if (hijack_listener_sp && use_run_lock)
@@ -1073,19 +1028,17 @@ StateType Process::GetStateChangedEvents(EventSP &event_sp,
Event *Process::PeekAtStateChangedEvents() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s...", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s...", __FUNCTION__);
Event *event_ptr;
event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType(
this, eBroadcastBitStateChanged);
if (log) {
if (event_ptr) {
- log->Printf(
- "Process::%s (event_ptr) => %s", __FUNCTION__,
- StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr)));
+ LLDB_LOGF(log, "Process::%s (event_ptr) => %s", __FUNCTION__,
+ StateAsCString(ProcessEventData::GetStateFromEvent(event_ptr)));
} else {
- log->Printf("Process::%s no events found", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s no events found", __FUNCTION__);
}
}
return event_ptr;
@@ -1149,17 +1102,14 @@ bool Process::SetExitStatus(int status, const char *cstr) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)",
- status, status, cstr ? "\"" : "", cstr ? cstr : "NULL",
- cstr ? "\"" : "");
+ LLDB_LOGF(
+ log, "Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)",
+ status, status, cstr ? "\"" : "", cstr ? cstr : "NULL", cstr ? "\"" : "");
// We were already in the exited state
if (m_private_state.GetValue() == eStateExited) {
- if (log)
- log->Printf("Process::SetExitStatus () ignoring exit status because "
- "state was already set to eStateExited");
+ LLDB_LOGF(log, "Process::SetExitStatus () ignoring exit status because "
+ "state was already set to eStateExited");
return false;
}
@@ -1207,10 +1157,10 @@ bool Process::SetProcessExitStatus(
int exit_status // Exit value of process if signal is zero
) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::SetProcessExitStatus (pid=%" PRIu64
- ", exited=%i, signal=%i, exit_status=%i)\n",
- pid, exited, signo, exit_status);
+ LLDB_LOGF(log,
+ "Process::SetProcessExitStatus (pid=%" PRIu64
+ ", exited=%i, signal=%i, exit_status=%i)\n",
+ pid, exited, signo, exit_status);
if (exited) {
TargetSP target_sp(Debugger::FindTargetWithProcessID(pid));
@@ -1353,9 +1303,8 @@ StateType Process::GetState() {
void Process::SetPublicState(StateType new_state, bool restarted) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::SetPublicState (state = %s, restarted = %i)",
- StateAsCString(new_state), restarted);
+ LLDB_LOGF(log, "Process::SetPublicState (state = %s, restarted = %i)",
+ StateAsCString(new_state), restarted);
const StateType old_state = m_public_state.GetValue();
m_public_state.SetValue(new_state);
@@ -1364,19 +1313,17 @@ void Process::SetPublicState(StateType new_state, bool restarted) {
// program to run.
if (!StateChangedIsExternallyHijacked()) {
if (new_state == eStateDetached) {
- if (log)
- log->Printf(
- "Process::SetPublicState (%s) -- unlocking run lock for detach",
- StateAsCString(new_state));
+ LLDB_LOGF(log,
+ "Process::SetPublicState (%s) -- unlocking run lock for detach",
+ StateAsCString(new_state));
m_public_run_lock.SetStopped();
} else {
const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
if ((old_state_is_stopped != new_state_is_stopped)) {
if (new_state_is_stopped && !restarted) {
- if (log)
- log->Printf("Process::SetPublicState (%s) -- unlocking run lock",
- StateAsCString(new_state));
+ LLDB_LOGF(log, "Process::SetPublicState (%s) -- unlocking run lock",
+ StateAsCString(new_state));
m_public_run_lock.SetStopped();
}
}
@@ -1387,12 +1334,10 @@ void Process::SetPublicState(StateType new_state, bool restarted) {
Status Process::Resume() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::Resume -- locking run lock");
+ LLDB_LOGF(log, "Process::Resume -- locking run lock");
if (!m_public_run_lock.TrySetRunning()) {
Status error("Resume request failed - process still running.");
- if (log)
- log->Printf("Process::Resume: -- TrySetRunning failed, not resuming.");
+ LLDB_LOGF(log, "Process::Resume: -- TrySetRunning failed, not resuming.");
return error;
}
Status error = PrivateResume();
@@ -1408,12 +1353,10 @@ static const char *g_resume_sync_name = "lldb.Process.ResumeSynchronous.hijack";
Status Process::ResumeSynchronous(Stream *stream) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::ResumeSynchronous -- locking run lock");
+ LLDB_LOGF(log, "Process::ResumeSynchronous -- locking run lock");
if (!m_public_run_lock.TrySetRunning()) {
Status error("Resume request failed - process still running.");
- if (log)
- log->Printf("Process::Resume: -- TrySetRunning failed, not resuming.");
+ LLDB_LOGF(log, "Process::Resume: -- TrySetRunning failed, not resuming.");
return error;
}
@@ -1472,8 +1415,7 @@ void Process::SetPrivateState(StateType new_state) {
LIBLLDB_LOG_PROCESS));
bool state_changed = false;
- if (log)
- log->Printf("Process::SetPrivateState (%s)", StateAsCString(new_state));
+ LLDB_LOGF(log, "Process::SetPrivateState (%s)", StateAsCString(new_state));
std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex());
std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex());
@@ -1512,9 +1454,8 @@ void Process::SetPrivateState(StateType new_state) {
if (!m_mod_id.IsLastResumeForUserExpression())
m_mod_id.SetStopEventForLastNaturalStopID(event_sp);
m_memory_cache.Clear();
- if (log)
- log->Printf("Process::SetPrivateState (%s) stop_id = %u",
- StateAsCString(new_state), m_mod_id.GetStopID());
+ LLDB_LOGF(log, "Process::SetPrivateState (%s) stop_id = %u",
+ StateAsCString(new_state), m_mod_id.GetStopID());
}
// Use our target to get a shared pointer to ourselves...
@@ -1523,10 +1464,9 @@ void Process::SetPrivateState(StateType new_state) {
else
m_private_state_broadcaster.BroadcastEvent(event_sp);
} else {
- if (log)
- log->Printf(
- "Process::SetPrivateState (%s) state didn't change. Ignoring...",
- StateAsCString(new_state));
+ LLDB_LOGF(log,
+ "Process::SetPrivateState (%s) state didn't change. Ignoring...",
+ StateAsCString(new_state));
}
}
@@ -1709,7 +1649,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
Address symbol_address = symbol->GetAddress();
load_addr = ResolveIndirectFunction(&symbol_address, error);
if (!error.Success() && show_error) {
- GetTarget().GetDebugger().GetErrorFile()->Printf(
+ GetTarget().GetDebugger().GetErrorStream().Printf(
"warning: failed to resolve indirect function at 0x%" PRIx64
" for breakpoint %i.%i: %s\n",
symbol->GetLoadAddress(&GetTarget()),
@@ -1748,7 +1688,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
} else {
if (show_error || use_hardware) {
// Report error for setting breakpoint...
- GetTarget().GetDebugger().GetErrorFile()->Printf(
+ GetTarget().GetDebugger().GetErrorStream().Printf(
"warning: failed to set breakpoint site at 0x%" PRIx64
" for breakpoint %i.%i: %s\n",
load_addr, owner->GetBreakpoint().GetID(), owner->GetID(),
@@ -1816,16 +1756,15 @@ Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) {
assert(bp_site != nullptr);
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
const addr_t bp_addr = bp_site->GetLoadAddress();
- if (log)
- log->Printf(
- "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64,
- bp_site->GetID(), (uint64_t)bp_addr);
+ LLDB_LOGF(
+ log, "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64,
+ bp_site->GetID(), (uint64_t)bp_addr);
if (bp_site->IsEnabled()) {
- if (log)
- log->Printf(
- "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
- " -- already enabled",
- bp_site->GetID(), (uint64_t)bp_addr);
+ LLDB_LOGF(
+ log,
+ "Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
+ " -- already enabled",
+ bp_site->GetID(), (uint64_t)bp_addr);
return error;
}
@@ -1864,10 +1803,10 @@ Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) {
bp_opcode_size) == 0) {
bp_site->SetEnabled(true);
bp_site->SetType(BreakpointSite::eSoftware);
- if (log)
- log->Printf("Process::EnableSoftwareBreakpoint (site_id = %d) "
- "addr = 0x%" PRIx64 " -- SUCCESS",
- bp_site->GetID(), (uint64_t)bp_addr);
+ LLDB_LOGF(log,
+ "Process::EnableSoftwareBreakpoint (site_id = %d) "
+ "addr = 0x%" PRIx64 " -- SUCCESS",
+ bp_site->GetID(), (uint64_t)bp_addr);
} else
error.SetErrorString(
"failed to verify the breakpoint trap in memory.");
@@ -1880,7 +1819,8 @@ Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) {
error.SetErrorString("Unable to read memory at breakpoint address.");
}
if (log && error.Fail())
- log->Printf(
+ LLDB_LOGF(
+ log,
"Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
" -- FAILED: %s",
bp_site->GetID(), (uint64_t)bp_addr, error.AsCString());
@@ -1893,10 +1833,10 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
addr_t bp_addr = bp_site->GetLoadAddress();
lldb::user_id_t breakID = bp_site->GetID();
- if (log)
- log->Printf("Process::DisableSoftwareBreakpoint (breakID = %" PRIu64
- ") addr = 0x%" PRIx64,
- breakID, (uint64_t)bp_addr);
+ LLDB_LOGF(log,
+ "Process::DisableSoftwareBreakpoint (breakID = %" PRIu64
+ ") addr = 0x%" PRIx64,
+ breakID, (uint64_t)bp_addr);
if (bp_site->IsHardware()) {
error.SetErrorString("Breakpoint site is a hardware breakpoint.");
@@ -1943,10 +1883,10 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
break_op_size) == 0) {
// SUCCESS
bp_site->SetEnabled(false);
- if (log)
- log->Printf("Process::DisableSoftwareBreakpoint (site_id = %d) "
- "addr = 0x%" PRIx64 " -- SUCCESS",
- bp_site->GetID(), (uint64_t)bp_addr);
+ LLDB_LOGF(log,
+ "Process::DisableSoftwareBreakpoint (site_id = %d) "
+ "addr = 0x%" PRIx64 " -- SUCCESS",
+ bp_site->GetID(), (uint64_t)bp_addr);
return error;
} else {
if (break_op_found)
@@ -1961,19 +1901,19 @@ Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) {
"Unable to read memory that should contain the breakpoint trap.");
}
} else {
- if (log)
- log->Printf(
- "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
- " -- already disabled",
- bp_site->GetID(), (uint64_t)bp_addr);
+ LLDB_LOGF(
+ log,
+ "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
+ " -- already disabled",
+ bp_site->GetID(), (uint64_t)bp_addr);
return error;
}
- if (log)
- log->Printf(
- "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
- " -- FAILED: %s",
- bp_site->GetID(), (uint64_t)bp_addr, error.AsCString());
+ LLDB_LOGF(
+ log,
+ "Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64
+ " -- FAILED: %s",
+ bp_site->GetID(), (uint64_t)bp_addr, error.AsCString());
return error;
}
@@ -2371,13 +2311,13 @@ addr_t Process::AllocateMemory(size_t size, uint32_t permissions,
#else
addr_t allocated_addr = DoAllocateMemory(size, permissions, error);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::AllocateMemory(size=%" PRIu64
- ", permissions=%s) => 0x%16.16" PRIx64
- " (m_stop_id = %u m_memory_id = %u)",
- (uint64_t)size, GetPermissionsAsCString(permissions),
- (uint64_t)allocated_addr, m_mod_id.GetStopID(),
- m_mod_id.GetMemoryID());
+ LLDB_LOGF(log,
+ "Process::AllocateMemory(size=%" PRIu64
+ ", permissions=%s) => 0x%16.16" PRIx64
+ " (m_stop_id = %u m_memory_id = %u)",
+ (uint64_t)size, GetPermissionsAsCString(permissions),
+ (uint64_t)allocated_addr, m_mod_id.GetStopID(),
+ m_mod_id.GetMemoryID());
return allocated_addr;
#endif
}
@@ -2403,16 +2343,16 @@ bool Process::CanJIT() {
if (err.Success()) {
m_can_jit = eCanJITYes;
- if (log)
- log->Printf("Process::%s pid %" PRIu64
- " allocation test passed, CanJIT () is true",
- __FUNCTION__, GetID());
+ LLDB_LOGF(log,
+ "Process::%s pid %" PRIu64
+ " allocation test passed, CanJIT () is true",
+ __FUNCTION__, GetID());
} else {
m_can_jit = eCanJITNo;
- if (log)
- log->Printf("Process::%s pid %" PRIu64
- " allocation test failed, CanJIT () is false: %s",
- __FUNCTION__, GetID(), err.AsCString());
+ LLDB_LOGF(log,
+ "Process::%s pid %" PRIu64
+ " allocation test failed, CanJIT () is false: %s",
+ __FUNCTION__, GetID(), err.AsCString());
}
DeallocateMemory(allocated_memory);
@@ -2441,11 +2381,11 @@ Status Process::DeallocateMemory(addr_t ptr) {
error = DoDeallocateMemory(ptr);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::DeallocateMemory(addr=0x%16.16" PRIx64
- ") => err = %s (m_stop_id = %u, m_memory_id = %u)",
- ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(),
- m_mod_id.GetMemoryID());
+ LLDB_LOGF(log,
+ "Process::DeallocateMemory(addr=0x%16.16" PRIx64
+ ") => err = %s (m_stop_id = %u, m_memory_id = %u)",
+ ptr, error.AsCString("SUCCESS"), m_mod_id.GetStopID(),
+ m_mod_id.GetMemoryID());
#endif
return error;
}
@@ -2455,8 +2395,9 @@ ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec,
size_t size_to_read) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log) {
- log->Printf("Process::ReadModuleFromMemory reading %s binary from memory",
- file_spec.GetPath().c_str());
+ LLDB_LOGF(log,
+ "Process::ReadModuleFromMemory reading %s binary from memory",
+ file_spec.GetPath().c_str());
}
ModuleSP module_sp(new Module(file_spec, ArchSpec()));
if (module_sp) {
@@ -2691,9 +2632,8 @@ Status Process::LoadCore() {
if (!StateIsStoppedState(state, false)) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::Halt() failed to stop, state is: %s",
- StateAsCString(state));
+ LLDB_LOGF(log, "Process::Halt() failed to stop, state is: %s",
+ StateAsCString(state));
error.SetErrorString(
"Did not get stopped event after loading the core file.");
}
@@ -2728,10 +2668,10 @@ Process::AttachCompletionHandler::AttachCompletionHandler(Process *process,
uint32_t exec_count)
: NextEventAction(process), m_exec_count(exec_count) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Process::AttachCompletionHandler::%s process=%p, exec_count=%" PRIu32,
- __FUNCTION__, static_cast<void *>(process), exec_count);
+ LLDB_LOGF(
+ log,
+ "Process::AttachCompletionHandler::%s process=%p, exec_count=%" PRIu32,
+ __FUNCTION__, static_cast<void *>(process), exec_count);
}
Process::NextEventAction::EventActionResult
@@ -2739,10 +2679,9 @@ Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
- if (log)
- log->Printf(
- "Process::AttachCompletionHandler::%s called with state %s (%d)",
- __FUNCTION__, StateAsCString(state), static_cast<int>(state));
+ LLDB_LOGF(log,
+ "Process::AttachCompletionHandler::%s called with state %s (%d)",
+ __FUNCTION__, StateAsCString(state), static_cast<int>(state));
switch (state) {
case eStateAttaching:
@@ -2764,18 +2703,18 @@ Process::AttachCompletionHandler::PerformAction(lldb::EventSP &event_sp) {
if (m_exec_count > 0) {
--m_exec_count;
- if (log)
- log->Printf("Process::AttachCompletionHandler::%s state %s: reduced "
- "remaining exec count to %" PRIu32 ", requesting resume",
- __FUNCTION__, StateAsCString(state), m_exec_count);
+ LLDB_LOGF(log,
+ "Process::AttachCompletionHandler::%s state %s: reduced "
+ "remaining exec count to %" PRIu32 ", requesting resume",
+ __FUNCTION__, StateAsCString(state), m_exec_count);
RequestResume();
return eEventActionRetry;
} else {
- if (log)
- log->Printf("Process::AttachCompletionHandler::%s state %s: no more "
- "execs expected to start, continuing with attach",
- __FUNCTION__, StateAsCString(state));
+ LLDB_LOGF(log,
+ "Process::AttachCompletionHandler::%s state %s: no more "
+ "execs expected to start, continuing with attach",
+ __FUNCTION__, StateAsCString(state));
m_process->CompleteAttach();
return eEventActionSuccess;
@@ -2932,8 +2871,7 @@ Status Process::Attach(ProcessAttachInfo &attach_info) {
void Process::CompleteAttach() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS |
LIBLLDB_LOG_TARGET));
- if (log)
- log->Printf("Process::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s()", __FUNCTION__);
// Let the process subclass figure out at much as it can about the process
// before we go looking for a dynamic loader plug-in.
@@ -2944,9 +2882,10 @@ void Process::CompleteAttach() {
GetTarget().SetArchitecture(process_arch);
if (log) {
const char *triple_str = process_arch.GetTriple().getTriple().c_str();
- log->Printf("Process::%s replacing process architecture with DidAttach() "
- "architecture: %s",
- __FUNCTION__, triple_str ? triple_str : "<null>");
+ LLDB_LOGF(log,
+ "Process::%s replacing process architecture with DidAttach() "
+ "architecture: %s",
+ __FUNCTION__, triple_str ? triple_str : "<null>");
}
}
@@ -2965,11 +2904,11 @@ void Process::CompleteAttach() {
if (platform_sp) {
GetTarget().SetPlatform(platform_sp);
GetTarget().SetArchitecture(platform_arch);
- if (log)
- log->Printf("Process::%s switching platform to %s and architecture "
- "to %s based on info from attach",
- __FUNCTION__, platform_sp->GetName().AsCString(""),
- platform_arch.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log,
+ "Process::%s switching platform to %s and architecture "
+ "to %s based on info from attach",
+ __FUNCTION__, platform_sp->GetName().AsCString(""),
+ platform_arch.GetTriple().getTriple().c_str());
}
} else if (!process_arch.IsValid()) {
ProcessInstanceInfo process_info;
@@ -2978,11 +2917,11 @@ void Process::CompleteAttach() {
if (process_arch.IsValid() &&
!GetTarget().GetArchitecture().IsExactMatch(process_arch)) {
GetTarget().SetArchitecture(process_arch);
- if (log)
- log->Printf("Process::%s switching architecture to %s based on info "
- "the platform retrieved for pid %" PRIu64,
- __FUNCTION__,
- process_arch.GetTriple().getTriple().c_str(), GetID());
+ LLDB_LOGF(log,
+ "Process::%s switching architecture to %s based on info "
+ "the platform retrieved for pid %" PRIu64,
+ __FUNCTION__, process_arch.GetTriple().getTriple().c_str(),
+ GetID());
}
}
}
@@ -2994,12 +2933,13 @@ void Process::CompleteAttach() {
dyld->DidAttach();
if (log) {
ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- log->Printf("Process::%s after DynamicLoader::DidAttach(), target "
- "executable is %s (using %s plugin)",
- __FUNCTION__,
- exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
- : "<none>",
- dyld->GetPluginName().AsCString("<unnamed>"));
+ LLDB_LOGF(log,
+ "Process::%s after DynamicLoader::DidAttach(), target "
+ "executable is %s (using %s plugin)",
+ __FUNCTION__,
+ exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
+ : "<none>",
+ dyld->GetPluginName().AsCString("<unnamed>"));
}
}
@@ -3010,12 +2950,13 @@ void Process::CompleteAttach() {
system_runtime->DidAttach();
if (log) {
ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- log->Printf("Process::%s after SystemRuntime::DidAttach(), target "
- "executable is %s (using %s plugin)",
- __FUNCTION__,
- exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
- : "<none>",
- system_runtime->GetPluginName().AsCString("<unnamed>"));
+ LLDB_LOGF(log,
+ "Process::%s after SystemRuntime::DidAttach(), target "
+ "executable is %s (using %s plugin)",
+ __FUNCTION__,
+ exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
+ : "<none>",
+ system_runtime->GetPluginName().AsCString("<unnamed>"));
}
}
@@ -3048,7 +2989,8 @@ void Process::CompleteAttach() {
eLoadDependentsNo);
if (log) {
ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- log->Printf(
+ LLDB_LOGF(
+ log,
"Process::%s after looping through modules, target executable is %s",
__FUNCTION__,
exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
@@ -3092,11 +3034,11 @@ Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) {
Status Process::PrivateResume() {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS |
LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s "
- "private state: %s",
- m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),
- StateAsCString(m_private_state.GetValue()));
+ LLDB_LOGF(log,
+ "Process::PrivateResume() m_stop_id = %u, public state: %s "
+ "private state: %s",
+ m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),
+ StateAsCString(m_private_state.GetValue()));
// If signals handing status changed we might want to update our signal
// filters before resuming.
@@ -3123,12 +3065,9 @@ Status Process::PrivateResume() {
if (error.Success()) {
DidResume();
m_thread_list.DidResume();
- if (log)
- log->Printf("Process thinks the process has resumed.");
+ LLDB_LOGF(log, "Process thinks the process has resumed.");
} else {
- if (log)
- log->Printf(
- "Process::PrivateResume() DoResume failed.");
+ LLDB_LOGF(log, "Process::PrivateResume() DoResume failed.");
return error;
}
}
@@ -3137,16 +3076,15 @@ Status Process::PrivateResume() {
// from one frame of a set of inlined frames that share the same PC to
// another.) So generate a continue & a stopped event, and let the world
// handle them.
- if (log)
- log->Printf(
- "Process::PrivateResume() asked to simulate a start & stop.");
+ LLDB_LOGF(log,
+ "Process::PrivateResume() asked to simulate a start & stop.");
SetPrivateState(eStateRunning);
SetPrivateState(eStateStopped);
}
- } else if (log)
- log->Printf("Process::PrivateResume() got an error \"%s\".",
- error.AsCString("<unknown error>"));
+ } else
+ LLDB_LOGF(log, "Process::PrivateResume() got an error \"%s\".",
+ error.AsCString("<unknown error>"));
return error;
}
@@ -3199,8 +3137,7 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
if (m_public_state.GetValue() == eStateRunning ||
m_private_state.GetValue() == eStateRunning) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s() About to stop.", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s() About to stop.", __FUNCTION__);
ListenerSP listener_sp(
Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
@@ -3220,17 +3157,15 @@ Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) {
// anymore...
if (state == eStateExited || m_private_state.GetValue() == eStateExited) {
- if (log)
- log->Printf("Process::%s() Process exited while waiting to stop.",
- __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s() Process exited while waiting to stop.",
+ __FUNCTION__);
return error;
} else
exit_event_sp.reset(); // It is ok to consume any non-exit stop events
if (state != eStateStopped) {
- if (log)
- log->Printf("Process::%s() failed to stop, state is: %s", __FUNCTION__,
- StateAsCString(state));
+ LLDB_LOGF(log, "Process::%s() failed to stop, state is: %s", __FUNCTION__,
+ StateAsCString(state));
// If we really couldn't stop the process then we should just error out
// here, but if the lower levels just bobbled sending the event and we
// really are stopped, then continue on.
@@ -3475,10 +3410,10 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
m_stdio_communication.SynchronizeWithReadThread();
RefreshStateAfterStop();
if (ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
- if (log)
- log->Printf("Process::ShouldBroadcastEvent (%p) stopped due to an "
- "interrupt, state: %s",
- static_cast<void *>(event_ptr), StateAsCString(state));
+ LLDB_LOGF(log,
+ "Process::ShouldBroadcastEvent (%p) stopped due to an "
+ "interrupt, state: %s",
+ static_cast<void *>(event_ptr), StateAsCString(state));
// Even though we know we are going to stop, we should let the threads
// have a look at the stop, so they can properly set their state.
m_thread_list.ShouldStop(event_ptr);
@@ -3496,11 +3431,11 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
if (was_restarted || should_resume || m_resume_requested) {
Vote stop_vote = m_thread_list.ShouldReportStop(event_ptr);
- if (log)
- log->Printf("Process::ShouldBroadcastEvent: should_resume: %i state: "
- "%s was_restarted: %i stop_vote: %d.",
- should_resume, StateAsCString(state), was_restarted,
- stop_vote);
+ LLDB_LOGF(log,
+ "Process::ShouldBroadcastEvent: should_resume: %i state: "
+ "%s was_restarted: %i stop_vote: %d.",
+ should_resume, StateAsCString(state), was_restarted,
+ stop_vote);
switch (stop_vote) {
case eVoteYes:
@@ -3513,10 +3448,10 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
}
if (!was_restarted) {
- if (log)
- log->Printf("Process::ShouldBroadcastEvent (%p) Restarting process "
- "from state: %s",
- static_cast<void *>(event_ptr), StateAsCString(state));
+ LLDB_LOGF(log,
+ "Process::ShouldBroadcastEvent (%p) Restarting process "
+ "from state: %s",
+ static_cast<void *>(event_ptr), StateAsCString(state));
ProcessEventData::SetRestartedInEvent(event_ptr, true);
PrivateResume();
}
@@ -3543,12 +3478,12 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
if (return_value)
m_last_broadcast_state = state;
- if (log)
- log->Printf("Process::ShouldBroadcastEvent (%p) => new state: %s, last "
- "broadcast state: %s - %s",
- static_cast<void *>(event_ptr), StateAsCString(state),
- StateAsCString(m_last_broadcast_state),
- return_value ? "YES" : "NO");
+ LLDB_LOGF(log,
+ "Process::ShouldBroadcastEvent (%p) => new state: %s, last "
+ "broadcast state: %s - %s",
+ static_cast<void *>(event_ptr), StateAsCString(state),
+ StateAsCString(m_last_broadcast_state),
+ return_value ? "YES" : "NO");
return return_value;
}
@@ -3556,10 +3491,9 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
bool already_running = PrivateStateThreadIsValid();
- if (log)
- log->Printf("Process::%s()%s ", __FUNCTION__,
- already_running ? " already running"
- : " starting private state thread");
+ LLDB_LOGF(log, "Process::%s()%s ", __FUNCTION__,
+ already_running ? " already running"
+ : " starting private state thread");
if (!is_secondary_thread && already_running)
return true;
@@ -3617,9 +3551,9 @@ void Process::StopPrivateStateThread() {
ControlPrivateStateThread(eBroadcastInternalStateControlStop);
else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Went to stop the private state thread, but it was already invalid.");
+ LLDB_LOGF(
+ log,
+ "Went to stop the private state thread, but it was already invalid.");
}
}
@@ -3630,8 +3564,7 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
signal == eBroadcastInternalStateControlPause ||
signal == eBroadcastInternalStateControlResume);
- if (log)
- log->Printf("Process::%s (signal = %d)", __FUNCTION__, signal);
+ LLDB_LOGF(log, "Process::%s (signal = %d)", __FUNCTION__, signal);
// Signal the private state thread
if (m_private_state_thread.IsJoinable()) {
@@ -3640,8 +3573,7 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
// possible that the thread state is invalid but that the thread is waiting
// on a control event instead of simply being on its way out (this should
// not happen, but it apparently can).
- if (log)
- log->Printf("Sending control event of type: %d.", signal);
+ LLDB_LOGF(log, "Sending control event of type: %d.", signal);
std::shared_ptr<EventDataReceipt> event_receipt_sp(new EventDataReceipt());
m_private_state_control_broadcaster.BroadcastEvent(signal,
event_receipt_sp);
@@ -3669,9 +3601,9 @@ void Process::ControlPrivateStateThread(uint32_t signal) {
m_private_state_thread.Reset();
}
} else {
- if (log)
- log->Printf(
- "Private state thread already dead, no need to signal it to stop.");
+ LLDB_LOGF(
+ log,
+ "Private state thread already dead, no need to signal it to stop.");
}
}
@@ -3694,8 +3626,7 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
if (m_next_event_action_up) {
NextEventAction::EventActionResult action_result =
m_next_event_action_up->PerformAction(event_sp);
- if (log)
- log->Printf("Ran next event action, result was %d.", action_result);
+ LLDB_LOGF(log, "Ran next event action, result was %d.", action_result);
switch (action_result) {
case NextEventAction::eEventActionSuccess:
@@ -3726,11 +3657,12 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
if (should_broadcast) {
const bool is_hijacked = IsHijackedForEvent(eBroadcastBitStateChanged);
if (log) {
- log->Printf("Process::%s (pid = %" PRIu64
- ") broadcasting new state %s (old state %s) to %s",
- __FUNCTION__, GetID(), StateAsCString(new_state),
- StateAsCString(GetState()),
- is_hijacked ? "hijacked" : "public");
+ LLDB_LOGF(log,
+ "Process::%s (pid = %" PRIu64
+ ") broadcasting new state %s (old state %s) to %s",
+ __FUNCTION__, GetID(), StateAsCString(new_state),
+ StateAsCString(GetState()),
+ is_hijacked ? "hijacked" : "public");
}
Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
if (StateIsRunningState(new_state)) {
@@ -3742,9 +3674,8 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
PushProcessIOHandler();
m_iohandler_sync.SetValue(m_iohandler_sync.GetValue() + 1,
eBroadcastAlways);
- if (log)
- log->Printf("Process::%s updated m_iohandler_sync to %d",
- __FUNCTION__, m_iohandler_sync.GetValue());
+ LLDB_LOGF(log, "Process::%s updated m_iohandler_sync to %d",
+ __FUNCTION__, m_iohandler_sync.GetValue());
}
} else if (StateIsStoppedState(new_state, false)) {
if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get())) {
@@ -3785,7 +3716,8 @@ void Process::HandlePrivateEvent(EventSP &event_sp) {
BroadcastEvent(event_sp);
} else {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"Process::%s (pid = %" PRIu64
") suppressing state %s (old state %s): should_broadcast == false",
__FUNCTION__, GetID(), StateAsCString(new_state),
@@ -3820,9 +3752,8 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
bool control_only = true;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...",
- __FUNCTION__, static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...",
+ __FUNCTION__, static_cast<void *>(this), GetID());
bool exit_now = false;
bool interrupt_requested = false;
@@ -3830,11 +3761,11 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
EventSP event_sp;
GetEventsPrivate(event_sp, llvm::None, control_only);
if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster)) {
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64
- ") got a control event: %d",
- __FUNCTION__, static_cast<void *>(this), GetID(),
- event_sp->GetType());
+ LLDB_LOGF(log,
+ "Process::%s (arg = %p, pid = %" PRIu64
+ ") got a control event: %d",
+ __FUNCTION__, static_cast<void *>(this), GetID(),
+ event_sp->GetType());
switch (event_sp->GetType()) {
case eBroadcastInternalStateControlStop:
@@ -3853,23 +3784,24 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
continue;
} else if (event_sp->GetType() == eBroadcastBitInterrupt) {
if (m_public_state.GetValue() == eStateAttaching) {
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64
- ") woke up with an interrupt while attaching - "
- "forwarding interrupt.",
- __FUNCTION__, static_cast<void *>(this), GetID());
+ LLDB_LOGF(log,
+ "Process::%s (arg = %p, pid = %" PRIu64
+ ") woke up with an interrupt while attaching - "
+ "forwarding interrupt.",
+ __FUNCTION__, static_cast<void *>(this), GetID());
BroadcastEvent(eBroadcastBitInterrupt, nullptr);
} else if (StateIsRunningState(m_last_broadcast_state)) {
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64
- ") woke up with an interrupt - Halting.",
- __FUNCTION__, static_cast<void *>(this), GetID());
+ LLDB_LOGF(log,
+ "Process::%s (arg = %p, pid = %" PRIu64
+ ") woke up with an interrupt - Halting.",
+ __FUNCTION__, static_cast<void *>(this), GetID());
Status error = HaltPrivate();
if (error.Fail() && log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64
- ") failed to halt the process: %s",
- __FUNCTION__, static_cast<void *>(this), GetID(),
- error.AsCString());
+ LLDB_LOGF(log,
+ "Process::%s (arg = %p, pid = %" PRIu64
+ ") failed to halt the process: %s",
+ __FUNCTION__, static_cast<void *>(this), GetID(),
+ error.AsCString());
// Halt should generate a stopped event. Make a note of the fact that
// we were doing the interrupt, so we can set the interrupted flag
// after we receive the event. We deliberately set this to true even if
@@ -3883,10 +3815,9 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
// request. We use m_last_broadcast_state, because the Stopped event
// may not have been popped of the event queue yet, which is when the
// public state gets updated.
- if (log)
- log->Printf(
- "Process::%s ignoring interrupt as we have already stopped.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Process::%s ignoring interrupt as we have already stopped.",
+ __FUNCTION__);
}
continue;
}
@@ -3908,9 +3839,10 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
ProcessEventData::SetInterruptedInEvent(event_sp.get(), true);
interrupt_requested = false;
} else if (log) {
- log->Printf("Process::%s interrupt_requested, but a non-stopped "
- "state '%s' received.",
- __FUNCTION__, StateAsCString(internal_state));
+ LLDB_LOGF(log,
+ "Process::%s interrupt_requested, but a non-stopped "
+ "state '%s' received.",
+ __FUNCTION__, StateAsCString(internal_state));
}
}
@@ -3919,20 +3851,19 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) {
if (internal_state == eStateInvalid || internal_state == eStateExited ||
internal_state == eStateDetached) {
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64
- ") about to exit with internal state %s...",
- __FUNCTION__, static_cast<void *>(this), GetID(),
- StateAsCString(internal_state));
+ LLDB_LOGF(log,
+ "Process::%s (arg = %p, pid = %" PRIu64
+ ") about to exit with internal state %s...",
+ __FUNCTION__, static_cast<void *>(this), GetID(),
+ StateAsCString(internal_state));
break;
}
}
// Verify log is still enabled before attempting to write to it...
- if (log)
- log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",
- __FUNCTION__, static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",
+ __FUNCTION__, static_cast<void *>(this), GetID());
// If we are a secondary thread, then the primary thread we are working for
// will have already acquired the public_run_lock, and isn't done with what
@@ -4042,10 +3973,10 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
if (curr_thread_list.GetSize() != num_threads) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Number of threads changed from %u to %u while processing event.",
- num_threads, curr_thread_list.GetSize());
+ LLDB_LOGF(
+ log,
+ "Number of threads changed from %u to %u while processing event.",
+ num_threads, curr_thread_list.GetSize());
break;
}
@@ -4054,10 +3985,10 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
if (thread_sp->GetIndexID() != thread_index_array[idx]) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("The thread at position %u changed from %u to %u while "
- "processing event.",
- idx, thread_index_array[idx], thread_sp->GetIndexID());
+ LLDB_LOGF(log,
+ "The thread at position %u changed from %u to %u while "
+ "processing event.",
+ idx, thread_index_array[idx], thread_sp->GetIndexID());
break;
}
@@ -4303,9 +4234,8 @@ size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) {
size_t bytes_available = one_profile_data.size();
if (bytes_available > 0) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::GetProfileData (buf = %p, size = %" PRIu64 ")",
- static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
+ LLDB_LOGF(log, "Process::GetProfileData (buf = %p, size = %" PRIu64 ")",
+ static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
if (bytes_available > buf_size) {
memcpy(buf, one_profile_data.c_str(), buf_size);
one_profile_data.erase(0, buf_size);
@@ -4325,9 +4255,8 @@ size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
size_t bytes_available = m_stdout_data.size();
if (bytes_available > 0) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")",
- static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
+ LLDB_LOGF(log, "Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")",
+ static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
if (bytes_available > buf_size) {
memcpy(buf, m_stdout_data.c_str(), buf_size);
m_stdout_data.erase(0, buf_size);
@@ -4345,9 +4274,8 @@ size_t Process::GetSTDERR(char *buf, size_t buf_size, Status &error) {
size_t bytes_available = m_stderr_data.size();
if (bytes_available > 0) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::GetSTDERR (buf = %p, size = %" PRIu64 ")",
- static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
+ LLDB_LOGF(log, "Process::GetSTDERR (buf = %p, size = %" PRIu64 ")",
+ static_cast<void *>(buf), static_cast<uint64_t>(buf_size));
if (bytes_available > buf_size) {
memcpy(buf, m_stderr_data.c_str(), buf_size);
m_stderr_data.erase(0, buf_size);
@@ -4371,9 +4299,10 @@ public:
IOHandlerProcessSTDIO(Process *process, int write_fd)
: IOHandler(process->GetTarget().GetDebugger(),
IOHandler::Type::ProcessIO),
- m_process(process), m_write_file(write_fd, false) {
+ m_process(process),
+ m_read_file(GetInputFD(), File::eOpenOptionRead, false),
+ m_write_file(write_fd, File::eOpenOptionWrite, false) {
m_pipe.CreateNew(false);
- m_read_file.SetDescriptor(GetInputFD(), false);
}
~IOHandlerProcessSTDIO() override = default;
@@ -4493,9 +4422,9 @@ public:
protected:
Process *m_process;
- File m_read_file; // Read from this file (usually actual STDIN for LLDB
- File m_write_file; // Write to this file (usually the master pty for getting
- // io to debuggee)
+ NativeFile m_read_file; // Read from this file (usually actual STDIN for LLDB
+ NativeFile m_write_file; // Write to this file (usually the master pty for
+ // getting io to debuggee)
Pipe m_pipe;
std::atomic<bool> m_is_running{false};
};
@@ -4532,8 +4461,7 @@ bool Process::PushProcessIOHandler() {
IOHandlerSP io_handler_sp(m_process_input_reader);
if (io_handler_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s pushing IO handler", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s pushing IO handler", __FUNCTION__);
io_handler_sp->SetIsDone(false);
// If we evaluate an utility function, then we don't cancel the current
@@ -4797,9 +4725,8 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
// public events. The simplest thing to do is to spin up a temporary thread
// to handle private state thread events while we are fielding public
// events here.
- if (log)
- log->Printf("Running thread plan on private state thread, spinning up "
- "another state thread to handle the events.");
+ LLDB_LOGF(log, "Running thread plan on private state thread, spinning up "
+ "another state thread to handle the events.");
backup_private_state_thread = m_private_state_thread;
@@ -4854,9 +4781,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (log) {
StreamString s;
thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64
- " to run thread plan \"%s\".",
- thread->GetIndexID(), thread->GetID(), s.GetData());
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64
+ " to run thread plan \"%s\".",
+ thread->GetIndexID(), thread->GetID(), s.GetData());
}
bool got_event;
@@ -4877,10 +4805,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (!options.GetStopOthers() || !options.GetTryAllThreads())
before_first_timeout = false;
- if (log)
- log->Printf("Stop others: %u, try all: %u, before_first: %u.\n",
- options.GetStopOthers(), options.GetTryAllThreads(),
- before_first_timeout);
+ LLDB_LOGF(log, "Stop others: %u, try all: %u, before_first: %u.\n",
+ options.GetStopOthers(), options.GetTryAllThreads(),
+ before_first_timeout);
// This isn't going to work if there are unfetched events on the queue. Are
// there cases where we might want to run the remaining events here, and
@@ -4919,10 +4846,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
// loop. The only exception is if we get two running events with no
// intervening stop, which can happen, we will just wait for then next
// stop event.
- if (log)
- log->Printf("Top of while loop: do_resume: %i handle_running_event: %i "
- "before_first_timeout: %i.",
- do_resume, handle_running_event, before_first_timeout);
+ LLDB_LOGF(log,
+ "Top of while loop: do_resume: %i handle_running_event: %i "
+ "before_first_timeout: %i.",
+ do_resume, handle_running_event, before_first_timeout);
if (do_resume || handle_running_event) {
// Do the initial resume and wait for the running event before going
@@ -4944,10 +4871,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
got_event =
listener_sp->GetEvent(event_sp, GetUtilityExpressionTimeout());
if (!got_event) {
- if (log)
- log->Printf("Process::RunThreadPlan(): didn't get any event after "
- "resume %" PRIu32 ", exiting.",
- num_resumes);
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): didn't get any event after "
+ "resume %" PRIu32 ", exiting.",
+ num_resumes);
diagnostic_manager.Printf(eDiagnosticSeverityError,
"didn't get any event after resume %" PRIu32
@@ -4966,13 +4893,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (stop_state == eStateStopped) {
restarted = Process::ProcessEventData::GetRestartedFromEvent(
event_sp.get());
- if (log)
- log->Printf(
- "Process::RunThreadPlan(): didn't get running event after "
- "resume %d, got %s instead (restarted: %i, do_resume: %i, "
- "handle_running_event: %i).",
- num_resumes, StateAsCString(stop_state), restarted, do_resume,
- handle_running_event);
+ LLDB_LOGF(
+ log,
+ "Process::RunThreadPlan(): didn't get running event after "
+ "resume %d, got %s instead (restarted: %i, do_resume: %i, "
+ "handle_running_event: %i).",
+ num_resumes, StateAsCString(stop_state), restarted, do_resume,
+ handle_running_event);
}
if (restarted) {
@@ -5015,19 +4942,20 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (log) {
if (timeout) {
auto now = system_clock::now();
- log->Printf("Process::RunThreadPlan(): about to wait - now is %s - "
- "endpoint is %s",
- llvm::to_string(now).c_str(),
- llvm::to_string(now + *timeout).c_str());
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): about to wait - now is %s - "
+ "endpoint is %s",
+ llvm::to_string(now).c_str(),
+ llvm::to_string(now + *timeout).c_str());
} else {
- log->Printf("Process::RunThreadPlan(): about to wait forever.");
+ LLDB_LOGF(log, "Process::RunThreadPlan(): about to wait forever.");
}
}
#ifdef LLDB_RUN_THREAD_HALT_WITH_EVENT
// See comment above...
if (miss_first_event) {
- usleep(1000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
miss_first_event = false;
got_event = false;
} else
@@ -5044,17 +4972,15 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
return_value = eExpressionInterrupted;
diagnostic_manager.PutString(eDiagnosticSeverityRemark,
"execution halted by user interrupt.");
- if (log)
- log->Printf("Process::RunThreadPlan(): Got interrupted by "
- "eBroadcastBitInterrupted, exiting.");
+ LLDB_LOGF(log, "Process::RunThreadPlan(): Got interrupted by "
+ "eBroadcastBitInterrupted, exiting.");
break;
} else {
stop_state =
Process::ProcessEventData::GetStateFromEvent(event_sp.get());
- if (log)
- log->Printf(
- "Process::RunThreadPlan(): in while loop, got event: %s.",
- StateAsCString(stop_state));
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): in while loop, got event: %s.",
+ StateAsCString(stop_state));
switch (stop_state) {
case lldb::eStateStopped: {
@@ -5064,18 +4990,18 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
if (!thread_sp) {
// Ooh, our thread has vanished. Unlikely that this was
// successful execution...
- if (log)
- log->Printf("Process::RunThreadPlan(): execution completed "
- "but our thread (index-id=%u) has vanished.",
- thread_idx_id);
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): execution completed "
+ "but our thread (index-id=%u) has vanished.",
+ thread_idx_id);
return_value = eExpressionInterrupted;
} else if (Process::ProcessEventData::GetRestartedFromEvent(
event_sp.get())) {
// If we were restarted, we just need to go back up to fetch
// another event.
if (log) {
- log->Printf("Process::RunThreadPlan(): Got a stop and "
- "restart, so we'll continue waiting.");
+ LLDB_LOGF(log, "Process::RunThreadPlan(): Got a stop and "
+ "restart, so we'll continue waiting.");
}
keep_going = true;
do_resume = false;
@@ -5098,10 +5024,10 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
break;
default:
- if (log)
- log->Printf("Process::RunThreadPlan(): execution stopped with "
- "unexpected state: %s.",
- StateAsCString(stop_state));
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): execution stopped with "
+ "unexpected state: %s.",
+ StateAsCString(stop_state));
if (stop_state == eStateExited)
event_to_broadcast_sp = event_sp;
@@ -5162,8 +5088,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
while (try_halt_again < num_retries) {
Status halt_error;
if (do_halt) {
- if (log)
- log->Printf("Process::RunThreadPlan(): Running Halt.");
+ LLDB_LOGF(log, "Process::RunThreadPlan(): Running Halt.");
const bool clear_thread_plans = false;
const bool use_run_lock = false;
Halt(clear_thread_plans, use_run_lock);
@@ -5179,8 +5104,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
stop_state =
Process::ProcessEventData::GetStateFromEvent(event_sp.get());
if (log) {
- log->Printf("Process::RunThreadPlan(): Stopped with event: %s",
- StateAsCString(stop_state));
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): Stopped with event: %s",
+ StateAsCString(stop_state));
if (stop_state == lldb::eStateStopped &&
Process::ProcessEventData::GetInterruptedFromEvent(
event_sp.get()))
@@ -5379,24 +5305,25 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
} while (false);
if (event_explanation)
- log->Printf("Process::RunThreadPlan(): execution interrupted: %s %s",
- s.GetData(), event_explanation);
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan(): execution interrupted: %s %s",
+ s.GetData(), event_explanation);
else
- log->Printf("Process::RunThreadPlan(): execution interrupted: %s",
- s.GetData());
+ LLDB_LOGF(log, "Process::RunThreadPlan(): execution interrupted: %s",
+ s.GetData());
}
if (should_unwind) {
- if (log)
- log->Printf("Process::RunThreadPlan: ExecutionInterrupted - "
- "discarding thread plans up to %p.",
- static_cast<void *>(thread_plan_sp.get()));
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan: ExecutionInterrupted - "
+ "discarding thread plans up to %p.",
+ static_cast<void *>(thread_plan_sp.get()));
thread->DiscardThreadPlansUpToPlan(thread_plan_sp);
} else {
- if (log)
- log->Printf("Process::RunThreadPlan: ExecutionInterrupted - for "
- "plan: %p not discarding.",
- static_cast<void *>(thread_plan_sp.get()));
+ LLDB_LOGF(log,
+ "Process::RunThreadPlan: ExecutionInterrupted - for "
+ "plan: %p not discarding.",
+ static_cast<void *>(thread_plan_sp.get()));
}
} else if (return_value == eExpressionSetupError) {
if (log)
@@ -5559,9 +5486,8 @@ size_t Process::GetThreadStatus(Stream &strm,
++num_thread_infos_dumped;
} else {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::GetThreadStatus - thread 0x" PRIu64
- " vanished while running Thread::GetStatus.");
+ LLDB_LOGF(log, "Process::GetThreadStatus - thread 0x" PRIu64
+ " vanished while running Thread::GetStatus.");
}
}
return num_thread_infos_dumped;
@@ -5612,6 +5538,12 @@ ProcessRunLock &Process::GetRunLock() {
return m_public_run_lock;
}
+bool Process::CurrentThreadIsPrivateStateThread()
+{
+ return m_private_state_thread.EqualsThread(Host::GetCurrentThread());
+}
+
+
void Process::Flush() {
m_thread_list.Flush();
m_extended_thread_list.Flush();
@@ -5622,8 +5554,7 @@ void Process::Flush() {
void Process::DidExec() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("Process::%s()", __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s()", __FUNCTION__);
Target &target = GetTarget();
target.CleanupProcess();
@@ -5669,7 +5600,7 @@ addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) {
if (iter != m_resolved_indirect_addresses.end()) {
function_addr = (*iter).second;
} else {
- if (!InferiorCall(this, address, function_addr)) {
+ if (!CallVoidArgVoidPtrReturn(address, function_addr)) {
Symbol *symbol = address->CalculateSymbolContextSymbol();
error.SetErrorStringWithFormat(
"Unable to call resolver for indirect function %s",
@@ -5929,19 +5860,18 @@ void Process::MapSupportedStructuredDataPlugins(
// Bail out early if there are no type names to map.
if (supported_type_names.GetSize() == 0) {
- if (log)
- log->Printf("Process::%s(): no structured data types supported",
- __FUNCTION__);
+ LLDB_LOGF(log, "Process::%s(): no structured data types supported",
+ __FUNCTION__);
return;
}
// Convert StructuredData type names to ConstString instances.
std::set<ConstString> const_type_names;
- if (log)
- log->Printf("Process::%s(): the process supports the following async "
- "structured data types:",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Process::%s(): the process supports the following async "
+ "structured data types:",
+ __FUNCTION__);
supported_type_names.ForEach(
[&const_type_names, &log](StructuredData::Object *object) {
@@ -5988,11 +5918,11 @@ void Process::MapSupportedStructuredDataPlugins(
m_structured_data_plugin_map.insert(
std::make_pair(type_name, plugin_sp));
names_to_remove.push_back(type_name);
- if (log)
- log->Printf("Process::%s(): using plugin %s for type name "
- "%s",
- __FUNCTION__, plugin_sp->GetPluginName().GetCString(),
- type_name.GetCString());
+ LLDB_LOGF(log,
+ "Process::%s(): using plugin %s for type name "
+ "%s",
+ __FUNCTION__, plugin_sp->GetPluginName().GetCString(),
+ type_name.GetCString());
}
}
@@ -6042,7 +5972,62 @@ UtilityFunction *Process::GetLoadImageUtilityFunction(
llvm::function_ref<std::unique_ptr<UtilityFunction>()> factory) {
if (platform != GetTarget().GetPlatform().get())
return nullptr;
- std::call_once(m_dlopen_utility_func_flag_once,
- [&] { m_dlopen_utility_func_up = factory(); });
+ llvm::call_once(m_dlopen_utility_func_flag_once,
+ [&] { m_dlopen_utility_func_up = factory(); });
return m_dlopen_utility_func_up.get();
}
+
+bool Process::CallVoidArgVoidPtrReturn(const Address *address,
+ addr_t &returned_func,
+ bool trap_exceptions) {
+ Thread *thread = GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == nullptr || address == nullptr)
+ return false;
+
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(GetUtilityExpressionTimeout());
+ options.SetTrapExceptions(trap_exceptions);
+
+ auto type_system_or_err =
+ GetTarget().GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (!type_system_or_err) {
+ llvm::consumeError(type_system_or_err.takeError());
+ return false;
+ }
+ CompilerType void_ptr_type =
+ type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+ lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
+ *thread, *address, void_ptr_type, llvm::ArrayRef<addr_t>(), options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result =
+ RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+ returned_func =
+ call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+ LLDB_INVALID_ADDRESS);
+
+ if (GetAddressByteSize() == 4) {
+ if (returned_func == UINT32_MAX)
+ return false;
+ } else if (GetAddressByteSize() == 8) {
+ if (returned_func == UINT64_MAX)
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp
index c960260f30c8..f29cf435d028 100644
--- a/source/Target/RegisterContext.cpp
+++ b/source/Target/RegisterContext.cpp
@@ -82,14 +82,12 @@ RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
arch.GetByteOrder(), addr_size);
ModuleSP opcode_ctx;
- DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr, 0,
- dwarf_opcode_len);
+ DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr);
Value result;
Status error;
- const lldb::offset_t offset = 0;
if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
- offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr,
- nullptr, result, &error)) {
+ eRegisterKindDWARF, nullptr, nullptr, result,
+ &error)) {
expr_result = result.GetScalar().SInt(-1);
switch (expr_result) {
case 0:
diff --git a/source/Target/RemoteAwarePlatform.cpp b/source/Target/RemoteAwarePlatform.cpp
index 1704e1533e9c..faa217ac83ef 100644
--- a/source/Target/RemoteAwarePlatform.cpp
+++ b/source/Target/RemoteAwarePlatform.cpp
@@ -61,8 +61,8 @@ Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec,
}
lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec,
- uint32_t flags, uint32_t mode,
- Status &error) {
+ File::OpenOptions flags,
+ uint32_t mode, Status &error) {
if (IsHost())
return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
if (m_remote_platform_sp)
diff --git a/source/Target/SectionLoadList.cpp b/source/Target/SectionLoadList.cpp
index 598f49ca13de..f2546a893194 100644
--- a/source/Target/SectionLoadList.cpp
+++ b/source/Target/SectionLoadList.cpp
@@ -121,7 +121,8 @@ bool SectionLoadList::SetSectionLoadAddress(const lldb::SectionSP &section,
} else {
if (log) {
- log->Printf(
+ LLDB_LOGF(
+ log,
"SectionLoadList::%s (section = %p (%s), load_addr = 0x%16.16" PRIx64
") error: module has been deleted",
__FUNCTION__, static_cast<void *>(section.get()),
@@ -145,9 +146,9 @@ size_t SectionLoadList::SetSectionUnloaded(const lldb::SectionSP &section_sp) {
section_sp->GetModule()->GetFileSpec());
module_name = module_file_spec.GetPath();
}
- log->Printf("SectionLoadList::%s (section = %p (%s.%s))", __FUNCTION__,
- static_cast<void *>(section_sp.get()), module_name.c_str(),
- section_sp->GetName().AsCString());
+ LLDB_LOGF(log, "SectionLoadList::%s (section = %p (%s.%s))", __FUNCTION__,
+ static_cast<void *>(section_sp.get()), module_name.c_str(),
+ section_sp->GetName().AsCString());
}
std::lock_guard<std::recursive_mutex> guard(m_mutex);
@@ -179,7 +180,8 @@ bool SectionLoadList::SetSectionUnloaded(const lldb::SectionSP &section_sp,
const FileSpec &module_file_spec(section_sp->GetModule()->GetFileSpec());
module_name = module_file_spec.GetPath();
}
- log->Printf(
+ LLDB_LOGF(
+ log,
"SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64
")",
__FUNCTION__, static_cast<void *>(section_sp.get()),
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index f8b22d96e16f..5e5a596e471d 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -29,6 +29,7 @@
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/lldb-enumerations.h"
@@ -50,14 +51,16 @@ using namespace lldb_private;
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index, addr_t cfa,
bool cfa_is_valid, addr_t pc, StackFrame::Kind kind,
+ bool behaves_like_zeroth_frame,
const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(),
m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
- m_stack_frame_kind(kind), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(kind),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
// If we don't have a CFA value, use the frame index for our StackID so that
// recursive functions properly aren't confused with one another on a history
// stack.
@@ -74,15 +77,17 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index,
const RegisterContextSP &reg_context_sp, addr_t cfa,
- addr_t pc, const SymbolContext *sc_ptr)
+ addr_t pc, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index),
m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr),
m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(),
m_frame_base_error(), m_cfa_is_valid(true),
- m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(StackFrame::Kind::Regular),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
if (sc_ptr != nullptr) {
m_sc = *sc_ptr;
m_flags.Set(m_sc.GetResolvedMask());
@@ -98,7 +103,8 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
user_id_t unwind_frame_index,
const RegisterContextSP &reg_context_sp, addr_t cfa,
- const Address &pc_addr, const SymbolContext *sc_ptr)
+ const Address &pc_addr, bool behaves_like_zeroth_frame,
+ const SymbolContext *sc_ptr)
: m_thread_wp(thread_sp), m_frame_index(frame_idx),
m_concrete_frame_index(unwind_frame_index),
m_reg_context_sp(reg_context_sp),
@@ -106,9 +112,10 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
nullptr),
m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
m_frame_base_error(), m_cfa_is_valid(true),
- m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(),
- m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(),
- m_mutex() {
+ m_stack_frame_kind(StackFrame::Kind::Regular),
+ m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
+ m_variable_list_sp(), m_variable_list_value_objects(),
+ m_recognized_frame_sp(), m_disassembly(), m_mutex() {
if (sc_ptr != nullptr) {
m_sc = *sc_ptr;
m_flags.Set(m_sc.GetResolvedMask());
@@ -288,7 +295,7 @@ StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
// following the function call instruction...
Address lookup_addr(GetFrameCodeAddress());
- if (m_frame_index > 0 && lookup_addr.IsValid()) {
+ if (!m_behaves_like_zeroth_frame && lookup_addr.IsValid()) {
addr_t offset = lookup_addr.GetOffset();
if (offset > 0) {
lookup_addr.SetOffset(offset - 1);
@@ -1357,13 +1364,16 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
base_and_offset.second,
addr)) {
- TypeSystem *c_type_system =
- target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
- if (!c_type_system) {
+ auto c_type_system_or_err =
+ target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (auto err = c_type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD),
+ std::move(err), "Unable to guess value for given address");
return ValueObjectSP();
} else {
CompilerType void_ptr_type =
- c_type_system
+ c_type_system_or_err
->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
.GetPointerType();
return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index 5492dda46402..6d0c46259c20 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -67,7 +67,8 @@ uint32_t StackFrameList::GetCurrentInlinedDepth() {
m_current_inlined_depth = UINT32_MAX;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf(
+ LLDB_LOGF(
+ log,
"GetCurrentInlinedDepth: invalidating current inlined depth.\n");
}
return m_current_inlined_depth;
@@ -90,7 +91,8 @@ void StackFrameList::ResetCurrentInlinedDepth() {
m_current_inlined_pc = LLDB_INVALID_ADDRESS;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf(
+ LLDB_LOGF(
+ log,
"ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
return;
}
@@ -184,9 +186,10 @@ void StackFrameList::ResetCurrentInlinedDepth() {
m_current_inlined_depth = num_inlined_functions + 1;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("ResetCurrentInlinedDepth: setting inlined "
- "depth: %d 0x%" PRIx64 ".\n",
- m_current_inlined_depth, curr_pc);
+ LLDB_LOGF(log,
+ "ResetCurrentInlinedDepth: setting inlined "
+ "depth: %d 0x%" PRIx64 ".\n",
+ m_current_inlined_depth, curr_pc);
break;
}
@@ -247,26 +250,19 @@ static void FindInterveningFrames(Function &begin, Function &end,
begin.GetDisplayName(), end.GetDisplayName(), return_pc);
// Find a non-tail calling edge with the correct return PC.
- auto first_level_edges = begin.GetCallEdges();
if (log)
- for (const CallEdge &edge : first_level_edges)
+ for (const CallEdge &edge : begin.GetCallEdges())
LLDB_LOG(log, "FindInterveningFrames: found call with retn-PC = {0:x}",
edge.GetReturnPCAddress(begin, target));
- auto first_edge_it = std::lower_bound(
- first_level_edges.begin(), first_level_edges.end(), return_pc,
- [&](const CallEdge &edge, addr_t target_pc) {
- return edge.GetReturnPCAddress(begin, target) < target_pc;
- });
- if (first_edge_it == first_level_edges.end() ||
- first_edge_it->GetReturnPCAddress(begin, target) != return_pc) {
+ CallEdge *first_edge = begin.GetCallEdgeForReturnAddress(return_pc, target);
+ if (!first_edge) {
LLDB_LOG(log, "No call edge outgoing from {0} with retn-PC == {1:x}",
begin.GetDisplayName(), return_pc);
return;
}
- CallEdge &first_edge = const_cast<CallEdge &>(*first_edge_it);
// The first callee may not be resolved, or there may be nothing to fill in.
- Function *first_callee = first_edge.GetCallee(images);
+ Function *first_callee = first_edge->GetCallee(images);
if (!first_callee) {
LLDB_LOG(log, "Could not resolve callee");
return;
@@ -290,15 +286,15 @@ static void FindInterveningFrames(Function &begin, Function &end,
DFS(Function *end, ModuleList &images) : end(end), images(images) {}
- void search(Function *first_callee, std::vector<Function *> &path) {
+ void search(Function &first_callee, std::vector<Function *> &path) {
dfs(first_callee);
if (!ambiguous)
path = std::move(solution_path);
}
- void dfs(Function *callee) {
+ void dfs(Function &callee) {
// Found a path to the target function.
- if (callee == end) {
+ if (&callee == end) {
if (solution_path.empty())
solution_path = active_path;
else
@@ -310,19 +306,19 @@ static void FindInterveningFrames(Function &begin, Function &end,
// there's more than one way to reach a target. This errs on the side of
// caution: it conservatively stops searching when some solutions are
// still possible to save time in the average case.
- if (!visited_nodes.insert(callee).second) {
+ if (!visited_nodes.insert(&callee).second) {
ambiguous = true;
return;
}
// Search the calls made from this callee.
- active_path.push_back(callee);
- for (CallEdge &edge : callee->GetTailCallingEdges()) {
+ active_path.push_back(&callee);
+ for (CallEdge &edge : callee.GetTailCallingEdges()) {
Function *next_callee = edge.GetCallee(images);
if (!next_callee)
continue;
- dfs(next_callee);
+ dfs(*next_callee);
if (ambiguous)
return;
}
@@ -330,7 +326,7 @@ static void FindInterveningFrames(Function &begin, Function &end,
}
};
- DFS(&end, images).search(first_callee, path);
+ DFS(&end, images).search(*first_callee, path);
}
/// Given that \p next_frame will be appended to the frame list, synthesize
@@ -394,11 +390,13 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) {
bool cfa_is_valid = false;
addr_t pc =
callee->GetAddressRange().GetBaseAddress().GetLoadAddress(&target);
+ constexpr bool behaves_like_zeroth_frame = false;
SymbolContext sc;
callee->CalculateSymbolContext(&sc);
auto synth_frame = std::make_shared<StackFrame>(
m_thread.shared_from_this(), frame_idx, concrete_frame_idx, cfa,
- cfa_is_valid, pc, StackFrame::Kind::Artificial, &sc);
+ cfa_is_valid, pc, StackFrame::Kind::Artificial,
+ behaves_like_zeroth_frame, &sc);
m_frames.push_back(synth_frame);
LLDB_LOG(log, "Pushed frame {0}", callee->GetDisplayName());
}
@@ -448,6 +446,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
uint32_t idx = m_concrete_frames_fetched++;
lldb::addr_t pc = LLDB_INVALID_ADDRESS;
lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
+ bool behaves_like_zeroth_frame = (idx == 0);
if (idx == 0) {
// We might have already created frame zero, only create it if we need
// to.
@@ -455,8 +454,9 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext());
if (reg_ctx_sp) {
- const bool success =
- unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ const bool success = unwinder &&
+ unwinder->GetFrameInfoAtIndex(
+ idx, cfa, pc, behaves_like_zeroth_frame);
// There shouldn't be any way not to get the frame info for frame
// 0. But if the unwinder can't make one, lets make one by hand
// with the SP as the CFA and see if that gets any further.
@@ -467,7 +467,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
unwind_frame_sp = std::make_shared<StackFrame>(
m_thread.shared_from_this(), m_frames.size(), idx, reg_ctx_sp,
- cfa, pc, nullptr);
+ cfa, pc, behaves_like_zeroth_frame, nullptr);
m_frames.push_back(unwind_frame_sp);
}
} else {
@@ -475,8 +475,9 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
}
} else {
- const bool success =
- unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
+ const bool success = unwinder &&
+ unwinder->GetFrameInfoAtIndex(
+ idx, cfa, pc, behaves_like_zeroth_frame);
if (!success) {
// We've gotten to the end of the stack.
SetAllFramesFetched();
@@ -485,7 +486,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
const bool cfa_is_valid = true;
unwind_frame_sp = std::make_shared<StackFrame>(
m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid,
- pc, StackFrame::Kind::Regular, nullptr);
+ pc, StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr);
// Create synthetic tail call frames between the previous frame and the
// newly-found frame. The new frame's index may change after this call,
@@ -527,10 +528,11 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) {
while (unwind_sc.GetParentOfInlinedScope(
curr_frame_address, next_frame_sc, next_frame_address)) {
next_frame_sc.line_entry.ApplyFileMappings(target_sp);
- StackFrameSP frame_sp(
- new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx,
- unwind_frame_sp->GetRegisterContextSP(), cfa,
- next_frame_address, &next_frame_sc));
+ behaves_like_zeroth_frame = false;
+ StackFrameSP frame_sp(new StackFrame(
+ m_thread.shared_from_this(), m_frames.size(), idx,
+ unwind_frame_sp->GetRegisterContextSP(), cfa, next_frame_address,
+ behaves_like_zeroth_frame, &next_frame_sc));
m_frames.push_back(frame_sp);
unwind_sc = next_frame_sc;
@@ -661,11 +663,13 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) {
Unwind *unwinder = m_thread.GetUnwinder();
if (unwinder) {
addr_t pc, cfa;
- if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) {
+ bool behaves_like_zeroth_frame = (idx == 0);
+ if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc,
+ behaves_like_zeroth_frame)) {
const bool cfa_is_valid = true;
frame_sp = std::make_shared<StackFrame>(
m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc,
- StackFrame::Kind::Regular, nullptr);
+ StackFrame::Kind::Regular, behaves_like_zeroth_frame, nullptr);
Function *function =
frame_sp->GetSymbolContext(eSymbolContextFunction).function;
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 6db0c2b037e9..28179b7e1ce0 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -147,10 +147,10 @@ public:
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Process::%s could not find breakpoint site id: %" PRId64 "...",
- __FUNCTION__, m_value);
+ LLDB_LOGF(log,
+ "Process::%s could not find breakpoint site id: %" PRId64
+ "...",
+ __FUNCTION__, m_value);
m_should_stop = true;
}
@@ -270,7 +270,7 @@ protected:
if (!thread_sp->IsValid()) {
// This shouldn't ever happen, but just in case, don't do more harm.
if (log) {
- log->Printf("PerformAction got called with an invalid thread.");
+ LLDB_LOGF(log, "PerformAction got called with an invalid thread.");
}
m_should_stop = true;
m_should_stop_is_valid = true;
@@ -339,10 +339,9 @@ protected:
return;
}
- if (log)
- log->Printf("StopInfoBreakpoint::PerformAction - Hit a "
- "breakpoint while running an expression,"
- " not running commands to avoid recursion.");
+ LLDB_LOGF(log, "StopInfoBreakpoint::PerformAction - Hit a "
+ "breakpoint while running an expression,"
+ " not running commands to avoid recursion.");
bool ignoring_breakpoints =
process->GetIgnoreBreakpointsInExpressions();
if (ignoring_breakpoints) {
@@ -359,10 +358,10 @@ protected:
} else {
m_should_stop = true;
}
- if (log)
- log->Printf("StopInfoBreakpoint::PerformAction - in expression, "
- "continuing: %s.",
- m_should_stop ? "true" : "false");
+ LLDB_LOGF(log,
+ "StopInfoBreakpoint::PerformAction - in expression, "
+ "continuing: %s.",
+ m_should_stop ? "true" : "false");
process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf(
"Warning: hit breakpoint while running function, skipping "
"commands and conditions to prevent recursion.\n");
@@ -402,10 +401,11 @@ protected:
// aren't:
if (!bp_loc_sp->ValidForThisThread(thread_sp.get())) {
if (log) {
- log->Printf("Breakpoint %s hit on thread 0x%llx but it was not "
- "for this thread, continuing.",
- loc_desc.GetData(), static_cast<unsigned long long>(
- thread_sp->GetID()));
+ LLDB_LOGF(log,
+ "Breakpoint %s hit on thread 0x%llx but it was not "
+ "for this thread, continuing.",
+ loc_desc.GetData(),
+ static_cast<unsigned long long>(thread_sp->GetID()));
}
continue;
}
@@ -445,21 +445,18 @@ protected:
error_sp->EOL();
const char *err_str =
condition_error.AsCString("<Unknown Error>");
- if (log)
- log->Printf("Error evaluating condition: \"%s\"\n", err_str);
+ LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
error_sp->PutCString(err_str);
error_sp->EOL();
error_sp->Flush();
} else {
- if (log) {
- log->Printf("Condition evaluated for breakpoint %s on thread "
- "0x%llx conditon_says_stop: %i.",
- loc_desc.GetData(),
- static_cast<unsigned long long>(
- thread_sp->GetID()),
- condition_says_stop);
- }
+ LLDB_LOGF(log,
+ "Condition evaluated for breakpoint %s on thread "
+ "0x%llx conditon_says_stop: %i.",
+ loc_desc.GetData(),
+ static_cast<unsigned long long>(thread_sp->GetID()),
+ condition_says_stop);
if (!condition_says_stop) {
// We don't want to increment the hit count of breakpoints if
// the condition fails. We've already bumped it by the time
@@ -479,9 +476,9 @@ protected:
bool auto_continue_says_stop = true;
if (bp_loc_sp->IsAutoContinue())
{
- if (log)
- log->Printf("Continuing breakpoint %s as AutoContinue was set.",
- loc_desc.GetData());
+ LLDB_LOGF(log,
+ "Continuing breakpoint %s as AutoContinue was set.",
+ loc_desc.GetData());
// We want this stop reported, so you will know we auto-continued
// but only for external breakpoints:
if (!internal_breakpoint)
@@ -533,10 +530,10 @@ protected:
Log *log_process(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log_process)
- log_process->Printf(
- "Process::%s could not find breakpoint site id: %" PRId64 "...",
- __FUNCTION__, m_value);
+ LLDB_LOGF(log_process,
+ "Process::%s could not find breakpoint site id: %" PRId64
+ "...",
+ __FUNCTION__, m_value);
}
if ((!m_should_stop || internal_breakpoint) &&
@@ -546,15 +543,15 @@ protected:
// additionally to the breakpoint
m_should_stop = true;
- // Here we clean the preset stop info so the next GetStopInfo call will
- // find the appropriate stop info, which should be the stop info
- // related to the completed plan
- thread_sp->ResetStopInfo();
+ // We know we're stopping for a completed plan and we don't want to
+ // show the breakpoint stop, so compute the public stop info immediately
+ // here.
+ thread_sp->CalculatePublicStopInfo();
}
- if (log)
- log->Printf("Process::%s returning from action with m_should_stop: %d.",
- __FUNCTION__, m_should_stop);
+ LLDB_LOGF(log,
+ "Process::%s returning from action with m_should_stop: %d.",
+ __FUNCTION__, m_should_stop);
}
}
@@ -664,11 +661,10 @@ protected:
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf(
- "Process::%s could not find watchpoint location id: %" PRId64
- "...",
- __FUNCTION__, GetValue());
+ LLDB_LOGF(log,
+ "Process::%s could not find watchpoint location id: %" PRId64
+ "...",
+ __FUNCTION__, GetValue());
m_should_stop = true;
}
@@ -817,15 +813,14 @@ protected:
m_should_stop = false;
} else
m_should_stop = true;
- if (log)
- log->Printf(
- "Condition successfully evaluated, result is %s.\n",
- m_should_stop ? "true" : "false");
+ LLDB_LOGF(log,
+ "Condition successfully evaluated, result is %s.\n",
+ m_should_stop ? "true" : "false");
} else {
m_should_stop = true;
- if (log)
- log->Printf(
- "Failed to get an integer result from the expression.");
+ LLDB_LOGF(
+ log,
+ "Failed to get an integer result from the expression.");
}
}
} else {
@@ -836,8 +831,7 @@ protected:
error_sp->Printf(": \"%s\"", wp_sp->GetConditionText());
error_sp->EOL();
const char *err_str = error.AsCString("<Unknown Error>");
- if (log)
- log->Printf("Error evaluating condition: \"%s\"\n", err_str);
+ LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
error_sp->PutCString(err_str);
error_sp->EOL();
@@ -889,14 +883,13 @@ protected:
Log *log_process(
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log_process)
- log_process->Printf(
- "Process::%s could not find watchpoint id: %" PRId64 "...",
- __FUNCTION__, m_value);
+ LLDB_LOGF(log_process,
+ "Process::%s could not find watchpoint id: %" PRId64 "...",
+ __FUNCTION__, m_value);
}
- if (log)
- log->Printf("Process::%s returning from action with m_should_stop: %d.",
- __FUNCTION__, m_should_stop);
+ LLDB_LOGF(log,
+ "Process::%s returning from action with m_should_stop: %d.",
+ __FUNCTION__, m_should_stop);
m_should_stop_is_valid = true;
}
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 4941cb585c55..4b9a1b77ad16 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -71,7 +71,7 @@ Target::Arch::Arch(const ArchSpec &spec)
: m_spec(spec),
m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}
-const Target::Arch& Target::Arch::operator=(const ArchSpec &spec) {
+const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) {
m_spec = spec;
m_plugin_up = PluginManager::CreateArchitectureInstance(spec);
return *this;
@@ -106,21 +106,19 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
CheckInWithManager();
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Target::Target()", static_cast<void *>(this));
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT),
+ "{0} Target::Target()", static_cast<void *>(this));
if (target_arch.IsValid()) {
- LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET,
- "Target::Target created with architecture %s (%s)",
- target_arch.GetArchitectureName(),
- target_arch.GetTriple().getTriple().c_str());
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET),
+ "Target::Target created with architecture {0} ({1})",
+ target_arch.GetArchitectureName(),
+ target_arch.GetTriple().getTriple().c_str());
}
}
Target::~Target() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Target::~Target()", static_cast<void *>(this));
+ LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this));
DeleteCurrentProcess();
}
@@ -137,10 +135,9 @@ void Target::PrimeFromDummyTarget(Target *target) {
BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
AddBreakpoint(new_bp, false);
}
-
- for (auto bp_name_entry : target->m_breakpoint_names)
- {
-
+
+ for (auto bp_name_entry : target->m_breakpoint_names) {
+
BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
AddBreakpointName(new_bp_name);
}
@@ -209,13 +206,11 @@ const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }
lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,
const char *repl_options, bool can_create) {
if (language == eLanguageTypeUnknown) {
- std::set<LanguageType> repl_languages;
+ LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
- Language::GetLanguagesSupportingREPLs(repl_languages);
-
- if (repl_languages.size() == 1) {
- language = *repl_languages.begin();
- } else if (repl_languages.size() == 0) {
+ if (auto single_lang = repl_languages.GetSingularLanguage()) {
+ language = *single_lang;
+ } else if (repl_languages.Empty()) {
err.SetErrorStringWithFormat(
"LLDB isn't configured with REPL support for any languages.");
return REPLSP();
@@ -310,14 +305,14 @@ BreakpointSP Target::CreateSourceRegexBreakpoint(
const FileSpecList *containingModules,
const FileSpecList *source_file_spec_list,
const std::unordered_set<std::string> &function_names,
- RegularExpression &source_regex, bool internal, bool hardware,
+ RegularExpression source_regex, bool internal, bool hardware,
LazyBool move_to_nearest_code) {
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
containingModules, source_file_spec_list));
if (move_to_nearest_code == eLazyBoolCalculate)
move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(
- nullptr, source_regex, function_names,
+ nullptr, std::move(source_regex), function_names,
!static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
@@ -552,7 +547,7 @@ SearchFilterSP Target::GetSearchFilterForModuleAndCUList(
BreakpointSP Target::CreateFuncRegexBreakpoint(
const FileSpecList *containingModules,
- const FileSpecList *containingSourceFiles, RegularExpression &func_regex,
+ const FileSpecList *containingSourceFiles, RegularExpression func_regex,
lldb::LanguageType requested_language, LazyBool skip_prologue,
bool internal, bool hardware) {
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
@@ -561,7 +556,7 @@ BreakpointSP Target::CreateFuncRegexBreakpoint(
? GetSkipPrologue()
: static_cast<bool>(skip_prologue);
BreakpointResolverSP resolver_sp(new BreakpointResolverName(
- nullptr, func_regex, requested_language, 0, skip));
+ nullptr, std::move(func_regex), requested_language, 0, skip));
return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
}
@@ -584,46 +579,40 @@ Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
return exc_bkpt_sp;
}
-lldb::BreakpointSP
-Target::CreateScriptedBreakpoint(const llvm::StringRef class_name,
- const FileSpecList *containingModules,
- const FileSpecList *containingSourceFiles,
- bool internal,
- bool request_hardware,
- StructuredData::ObjectSP extra_args_sp,
- Status *creation_error)
-{
+lldb::BreakpointSP Target::CreateScriptedBreakpoint(
+ const llvm::StringRef class_name, const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles, bool internal,
+ bool request_hardware, StructuredData::ObjectSP extra_args_sp,
+ Status *creation_error) {
SearchFilterSP filter_sp;
-
+
lldb::SearchDepth depth = lldb::eSearchDepthTarget;
- bool has_files = containingSourceFiles && containingSourceFiles->GetSize() > 0;
+ bool has_files =
+ containingSourceFiles && containingSourceFiles->GetSize() > 0;
bool has_modules = containingModules && containingModules->GetSize() > 0;
-
+
if (has_files && has_modules) {
- filter_sp = GetSearchFilterForModuleAndCUList(
- containingModules, containingSourceFiles);
+ filter_sp = GetSearchFilterForModuleAndCUList(containingModules,
+ containingSourceFiles);
} else if (has_files) {
- filter_sp = GetSearchFilterForModuleAndCUList(
- nullptr, containingSourceFiles);
+ filter_sp =
+ GetSearchFilterForModuleAndCUList(nullptr, containingSourceFiles);
} else if (has_modules) {
filter_sp = GetSearchFilterForModuleList(containingModules);
} else {
filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>(
shared_from_this());
}
-
+
StructuredDataImpl *extra_args_impl = new StructuredDataImpl();
if (extra_args_sp)
extra_args_impl->SetObjectSP(extra_args_sp);
BreakpointResolverSP resolver_sp(new BreakpointResolverScripted(
- nullptr, class_name, depth, extra_args_impl,
- *GetDebugger().GetScriptInterpreter()));
+ nullptr, class_name, depth, extra_args_impl));
return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);
-
}
-
BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,
BreakpointResolverSP &resolver_sp,
bool internal, bool request_hardware,
@@ -651,8 +640,8 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
if (log) {
StreamString s;
bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__,
- bp_sp->IsInternal() ? "yes" : "no", s.GetData());
+ LLDB_LOGF(log, "Target::%s (internal = %s) => break_id = %s\n",
+ __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData());
}
bp_sp->ResolveBreakpoint();
@@ -662,71 +651,61 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
}
}
-void Target::AddNameToBreakpoint(BreakpointID &id,
- const char *name,
- Status &error)
- {
- BreakpointSP bp_sp
- = m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
- if (!bp_sp)
- {
- StreamString s;
- id.GetDescription(&s, eDescriptionLevelBrief);
- error.SetErrorStringWithFormat("Could not find breakpoint %s",
- s.GetData());
- return;
- }
- AddNameToBreakpoint(bp_sp, name, error);
- }
-
-void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
- const char *name,
- Status &error)
- {
- if (!bp_sp)
- return;
-
- BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
- if (!bp_name)
- return;
-
- bp_name->ConfigureBreakpoint(bp_sp);
- bp_sp->AddName(name);
- }
+void Target::AddNameToBreakpoint(BreakpointID &id, const char *name,
+ Status &error) {
+ BreakpointSP bp_sp =
+ m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
+ if (!bp_sp) {
+ StreamString s;
+ id.GetDescription(&s, eDescriptionLevelBrief);
+ error.SetErrorStringWithFormat("Could not find breakpoint %s", s.GetData());
+ return;
+ }
+ AddNameToBreakpoint(bp_sp, name, error);
+}
+
+void Target::AddNameToBreakpoint(BreakpointSP &bp_sp, const char *name,
+ Status &error) {
+ if (!bp_sp)
+ return;
+
+ BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
+ if (!bp_name)
+ return;
+
+ bp_name->ConfigureBreakpoint(bp_sp);
+ bp_sp->AddName(name);
+}
void Target::AddBreakpointName(BreakpointName *bp_name) {
m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
}
-BreakpointName *Target::FindBreakpointName(ConstString name,
- bool can_create,
- Status &error)
-{
+BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create,
+ Status &error) {
BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
if (!error.Success())
return nullptr;
BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
if (iter == m_breakpoint_names.end()) {
- if (!can_create)
- {
+ if (!can_create) {
error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
- "can_create is false.", name.AsCString());
+ "can_create is false.",
+ name.AsCString());
return nullptr;
}
- iter = m_breakpoint_names.insert(std::make_pair(name,
- new BreakpointName(name)))
- .first;
+ iter = m_breakpoint_names
+ .insert(std::make_pair(name, new BreakpointName(name)))
+ .first;
}
return (iter->second);
}
-void
-Target::DeleteBreakpointName(ConstString name)
-{
+void Target::DeleteBreakpointName(ConstString name) {
BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
-
+
if (iter != m_breakpoint_names.end()) {
const char *name_cstr = name.AsCString();
m_breakpoint_names.erase(iter);
@@ -736,15 +715,13 @@ Target::DeleteBreakpointName(ConstString name)
}
void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
- ConstString name)
-{
+ ConstString name) {
bp_sp->RemoveName(name.AsCString());
}
-void Target::ConfigureBreakpointName(BreakpointName &bp_name,
- const BreakpointOptions &new_options,
- const BreakpointName::Permissions &new_permissions)
-{
+void Target::ConfigureBreakpointName(
+ BreakpointName &bp_name, const BreakpointOptions &new_options,
+ const BreakpointName::Permissions &new_permissions) {
bp_name.GetOptions().CopyOverSetOptions(new_options);
bp_name.GetPermissions().MergeInto(new_permissions);
ApplyNameToBreakpoints(bp_name);
@@ -752,15 +729,14 @@ void Target::ConfigureBreakpointName(BreakpointName &bp_name,
void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
BreakpointList bkpts_with_name(false);
- m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
+ m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
bkpts_with_name);
for (auto bp_sp : bkpts_with_name.Breakpoints())
bp_name.ConfigureBreakpoint(bp_sp);
}
-void Target::GetBreakpointNames(std::vector<std::string> &names)
-{
+void Target::GetBreakpointNames(std::vector<std::string> &names) {
names.clear();
for (auto bp_name : m_breakpoint_names) {
names.push_back(bp_name.first.AsCString());
@@ -797,10 +773,10 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
const CompilerType *type, uint32_t kind,
Status &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
- " type = %u)\n",
- __FUNCTION__, addr, (uint64_t)size, kind);
+ LLDB_LOGF(log,
+ "Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
+ " type = %u)\n",
+ __FUNCTION__, addr, (uint64_t)size, kind);
WatchpointSP wp_sp;
if (!ProcessIsValid()) {
@@ -855,10 +831,9 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
}
error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
- if (log)
- log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
- __FUNCTION__, error.Success() ? "succeeded" : "failed",
- wp_sp->GetID());
+ LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n",
+ __FUNCTION__, error.Success() ? "succeeded" : "failed",
+ wp_sp->GetID());
if (error.Fail()) {
// Enabling the watchpoint on the device side failed. Remove the said
@@ -875,22 +850,19 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
return wp_sp;
}
-void Target::RemoveAllowedBreakpoints ()
-{
+void Target::RemoveAllowedBreakpoints() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s \n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s \n", __FUNCTION__);
m_breakpoint_list.RemoveAllowed(true);
-
+
m_last_created_breakpoint.reset();
}
void Target::RemoveAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
- internal_also ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
+ internal_also ? "yes" : "no");
m_breakpoint_list.RemoveAll(true);
if (internal_also)
@@ -901,9 +873,8 @@ void Target::RemoveAllBreakpoints(bool internal_also) {
void Target::DisableAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
- internal_also ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
+ internal_also ? "yes" : "no");
m_breakpoint_list.SetEnabledAll(false);
if (internal_also)
@@ -912,17 +883,15 @@ void Target::DisableAllBreakpoints(bool internal_also) {
void Target::DisableAllowedBreakpoints() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s", __FUNCTION__);
m_breakpoint_list.SetEnabledAllowed(false);
}
void Target::EnableAllBreakpoints(bool internal_also) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
- internal_also ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
+ internal_also ? "yes" : "no");
m_breakpoint_list.SetEnabledAll(true);
if (internal_also)
@@ -931,17 +900,15 @@ void Target::EnableAllBreakpoints(bool internal_also) {
void Target::EnableAllowedBreakpoints() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s", __FUNCTION__);
m_breakpoint_list.SetEnabledAllowed(true);
}
bool Target::RemoveBreakpointByID(break_id_t break_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
- break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+ break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
if (DisableBreakpointByID(break_id)) {
if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
@@ -960,9 +927,8 @@ bool Target::RemoveBreakpointByID(break_id_t break_id) {
bool Target::DisableBreakpointByID(break_id_t break_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
- break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+ break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
BreakpointSP bp_sp;
@@ -979,9 +945,8 @@ bool Target::DisableBreakpointByID(break_id_t break_id) {
bool Target::EnableBreakpointByID(break_id_t break_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
- break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
+ LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
+ break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
BreakpointSP bp_sp;
@@ -1031,10 +996,9 @@ Status Target::SerializeBreakpointsToFile(const FileSpec &file,
}
StreamFile out_file(path.c_str(),
- File::OpenOptions::eOpenOptionTruncate |
- File::OpenOptions::eOpenOptionWrite |
- File::OpenOptions::eOpenOptionCanCreate |
- File::OpenOptions::eOpenOptionCloseOnExec,
+ File::eOpenOptionTruncate | File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec,
lldb::eFilePermissionsFileDefault);
if (!out_file.GetFile().IsValid()) {
error.SetErrorStringWithFormat("Unable to open output file: %s.",
@@ -1159,8 +1123,7 @@ Status Target::CreateBreakpointsFromFile(const FileSpec &file,
// to end operations.
bool Target::RemoveAllWatchpoints(bool end_to_end) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
m_watchpoint_list.RemoveAll(true);
@@ -1191,8 +1154,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) {
// to end operations.
bool Target::DisableAllWatchpoints(bool end_to_end) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
m_watchpoint_list.SetEnabledAll(false);
@@ -1221,8 +1183,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) {
// to end operations.
bool Target::EnableAllWatchpoints(bool end_to_end) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!end_to_end) {
m_watchpoint_list.SetEnabledAll(true);
@@ -1250,8 +1211,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::ClearAllWatchpointHitCounts() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
size_t num_watchpoints = m_watchpoint_list.GetSize();
for (size_t i = 0; i < num_watchpoints; ++i) {
@@ -1267,8 +1227,7 @@ bool Target::ClearAllWatchpointHitCounts() {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::ClearAllWatchpointHistoricValues() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
size_t num_watchpoints = m_watchpoint_list.GetSize();
for (size_t i = 0; i < num_watchpoints; ++i) {
@@ -1285,8 +1244,7 @@ bool Target::ClearAllWatchpointHistoricValues() {
// these operations.
bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s\n", __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
if (!ProcessIsValid())
return false;
@@ -1305,8 +1263,7 @@ bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+ LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
return false;
@@ -1325,8 +1282,7 @@ bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+ LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
return false;
@@ -1345,8 +1301,7 @@ bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+ LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);
if (watch_to_remove_sp == m_last_created_watchpoint)
@@ -1363,8 +1318,7 @@ bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,
uint32_t ignore_count) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
+ LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
if (!ProcessIsValid())
return false;
@@ -1399,19 +1353,18 @@ static void LoadScriptingResourceForModule(const ModuleSP &module_sp,
Target *target) {
Status error;
StreamString feedback_stream;
- if (module_sp &&
- !module_sp->LoadScriptingResourceInTarget(target, error,
- &feedback_stream)) {
+ if (module_sp && !module_sp->LoadScriptingResourceInTarget(
+ target, error, &feedback_stream)) {
if (error.AsCString())
- target->GetDebugger().GetErrorFile()->Printf(
+ target->GetDebugger().GetErrorStream().Printf(
"unable to load scripting data for module %s - error reported was "
"%s\n",
module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
error.AsCString());
}
if (feedback_stream.GetSize())
- target->GetDebugger().GetErrorFile()->Printf("%s\n",
- feedback_stream.GetData());
+ target->GetDebugger().GetErrorStream().Printf("%s\n",
+ feedback_stream.GetData());
}
void Target::ClearModules(bool delete_locations) {
@@ -1440,7 +1393,8 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
executable_sp->GetFileSpec().GetPath().c_str());
const bool notify = true;
- m_images.Append(executable_sp, notify); // The first image is our executable file
+ m_images.Append(executable_sp,
+ notify); // The first image is our executable file
// If we haven't set an architecture yet, reset our architecture based on
// what we found in the executable module.
@@ -1481,10 +1435,10 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
platform_dependent_file_spec = dependent_file_spec;
ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());
- ModuleSP image_module_sp(GetOrCreateModule(module_spec,
- false /* notify */));
+ ModuleSP image_module_sp(
+ GetOrCreateModule(module_spec, false /* notify */));
if (image_module_sp) {
- added_modules.AppendIfNeeded (image_module_sp, false);
+ added_modules.AppendIfNeeded(image_module_sp, false);
ObjectFile *objfile = image_module_sp->GetObjectFile();
if (objfile)
objfile->GetDependentModules(dependent_files);
@@ -1531,8 +1485,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
bool arch_changed, vendor_changed, os_changed, os_ver_changed,
env_changed;
- m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed, vendor_changed,
- os_changed, os_ver_changed, env_changed);
+ m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed,
+ vendor_changed, os_changed,
+ os_ver_changed, env_changed);
if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
replace_local_arch = false;
@@ -1554,10 +1509,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
// If we have an executable file, try to reset the executable to the desired
// architecture
- if (log)
- log->Printf("Target::SetArchitecture changing architecture to %s (%s)",
- arch_spec.GetArchitectureName(),
- arch_spec.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log, "Target::SetArchitecture changing architecture to %s (%s)",
+ arch_spec.GetArchitectureName(),
+ arch_spec.GetTriple().getTriple().c_str());
m_arch = other;
ModuleSP executable_sp = GetExecutableModule();
@@ -1565,16 +1519,15 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
// Need to do something about unsetting breakpoints.
if (executable_sp) {
- if (log)
- log->Printf("Target::SetArchitecture Trying to select executable file "
- "architecture %s (%s)",
- arch_spec.GetArchitectureName(),
- arch_spec.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log,
+ "Target::SetArchitecture Trying to select executable file "
+ "architecture %s (%s)",
+ arch_spec.GetArchitectureName(),
+ arch_spec.GetTriple().getTriple().c_str());
ModuleSpec module_spec(executable_sp->GetFileSpec(), other);
FileSpecList search_paths = GetExecutableSearchPaths();
Status error = ModuleList::GetSharedModule(module_spec, executable_sp,
- &search_paths,
- nullptr, nullptr);
+ &search_paths, nullptr, nullptr);
if (!error.Fail() && executable_sp) {
SetExecutableModule(executable_sp, eLoadDependentsYes);
@@ -1591,11 +1544,11 @@ bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
// The current target arch is compatible with "arch_spec", see if we can
// improve our current architecture using bits from "arch_spec"
- if (log)
- log->Printf("Target::MergeArchitecture target has arch %s, merging with "
- "arch %s",
- m_arch.GetSpec().GetTriple().getTriple().c_str(),
- arch_spec.GetTriple().getTriple().c_str());
+ LLDB_LOGF(log,
+ "Target::MergeArchitecture target has arch %s, merging with "
+ "arch %s",
+ m_arch.GetSpec().GetTriple().getTriple().c_str(),
+ arch_spec.GetTriple().getTriple().c_str());
// Merge bits from arch_spec into "merged_arch" and set our architecture
ArchSpec merged_arch(m_arch.GetSpec());
@@ -1612,7 +1565,7 @@ bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
void Target::NotifyWillClearList(const ModuleList &module_list) {}
void Target::NotifyModuleAdded(const ModuleList &module_list,
- const ModuleSP &module_sp) {
+ const ModuleSP &module_sp) {
// A module is being added to this target for the first time
if (m_valid) {
ModuleList my_module_list;
@@ -1622,7 +1575,7 @@ void Target::NotifyModuleAdded(const ModuleList &module_list,
}
void Target::NotifyModuleRemoved(const ModuleList &module_list,
- const ModuleSP &module_sp) {
+ const ModuleSP &module_sp) {
// A module is being removed from this target.
if (m_valid) {
ModuleList my_module_list;
@@ -1632,8 +1585,8 @@ void Target::NotifyModuleRemoved(const ModuleList &module_list,
}
void Target::NotifyModuleUpdated(const ModuleList &module_list,
- const ModuleSP &old_module_sp,
- const ModuleSP &new_module_sp) {
+ const ModuleSP &old_module_sp,
+ const ModuleSP &new_module_sp) {
// A module is replacing an already added module
if (m_valid) {
m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,
@@ -1644,10 +1597,9 @@ void Target::NotifyModuleUpdated(const ModuleList &module_list,
}
void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {
- ModulesDidUnload (module_list, false);
+ ModulesDidUnload(module_list, false);
}
-
void Target::ModulesDidLoad(ModuleList &module_list) {
const size_t num_images = module_list.GetSize();
if (m_valid && num_images) {
@@ -1696,11 +1648,11 @@ bool Target::ModuleIsExcludedForUnconstrainedSearches(
if (GetBreakpointsConsultPlatformAvoidList()) {
ModuleList matchingModules;
ModuleSpec module_spec(module_file_spec);
- size_t num_modules = GetImages().FindModules(module_spec, matchingModules);
+ GetImages().FindModules(module_spec, matchingModules);
+ size_t num_modules = matchingModules.GetSize();
- // If there is more than one module for this file spec, only return true if
- // ALL the modules are on the
- // black list.
+ // If there is more than one module for this file spec, only
+ // return true if ALL the modules are on the black list.
if (num_modules > 0) {
for (size_t i = 0; i < num_modules; i++) {
if (!ModuleIsExcludedForUnconstrainedSearches(
@@ -1967,8 +1919,8 @@ bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
Status &error, Address &pointer_addr) {
Scalar scalar;
if (ReadScalarIntegerFromMemory(addr, prefer_file_cache,
- m_arch.GetSpec().GetAddressByteSize(), false, scalar,
- error)) {
+ m_arch.GetSpec().GetAddressByteSize(), false,
+ scalar, error)) {
addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
SectionLoadList &section_load_list = GetSectionLoadList();
@@ -2021,8 +1973,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
transformed_spec.GetFileSpec().GetFilename() =
module_spec.GetFileSpec().GetFilename();
error = ModuleList::GetSharedModule(transformed_spec, module_sp,
- &search_paths,
- &old_module_sp, &did_create_module);
+ &search_paths, &old_module_sp,
+ &did_create_module);
}
}
@@ -2037,9 +1989,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
// cache.
if (module_spec.GetUUID().IsValid()) {
// We have a UUID, it is OK to check the global module list...
- error = ModuleList::GetSharedModule(module_spec, module_sp,
- &search_paths,
- &old_module_sp, &did_create_module);
+ error =
+ ModuleList::GetSharedModule(module_spec, module_sp, &search_paths,
+ &old_module_sp, &did_create_module);
}
if (!module_sp) {
@@ -2047,8 +1999,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
// module in the shared module cache.
if (m_platform_sp) {
error = m_platform_sp->GetSharedModule(
- module_spec, m_process_sp.get(), module_sp,
- &search_paths, &old_module_sp, &did_create_module);
+ module_spec, m_process_sp.get(), module_sp, &search_paths,
+ &old_module_sp, &did_create_module);
} else {
error.SetErrorString("no platform is currently set");
}
@@ -2107,11 +2059,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
module_spec_copy.GetUUID().Clear();
ModuleList found_modules;
- size_t num_found =
- m_images.FindModules(module_spec_copy, found_modules);
- if (num_found == 1) {
+ m_images.FindModules(module_spec_copy, found_modules);
+ if (found_modules.GetSize() == 1)
old_module_sp = found_modules.GetModuleAtIndex(0);
- }
}
}
@@ -2120,9 +2070,8 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
if (GetPreloadSymbols())
module_sp->PreloadSymbols();
- if (old_module_sp &&
- m_images.GetIndexForModule(old_module_sp.get()) !=
- LLDB_INVALID_INDEX32) {
+ if (old_module_sp && m_images.GetIndexForModule(old_module_sp.get()) !=
+ LLDB_INVALID_INDEX32) {
m_images.ReplaceModule(old_module_sp, module_sp);
Module *old_module_ptr = old_module_sp.get();
old_module_sp.reset();
@@ -2164,34 +2113,28 @@ void Target::ImageSearchPathsChanged(const PathMappingList &path_list,
target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
}
-TypeSystem *Target::GetScratchTypeSystemForLanguage(Status *error,
- lldb::LanguageType language,
- bool create_on_demand) {
+llvm::Expected<TypeSystem &>
+Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
+ bool create_on_demand) {
if (!m_valid)
- return nullptr;
-
- if (error) {
- error->Clear();
- }
+ return llvm::make_error<llvm::StringError>("Invalid Target",
+ llvm::inconvertibleErrorCode());
if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all
// assembly code
|| language == eLanguageTypeUnknown) {
- std::set<lldb::LanguageType> languages_for_types;
- std::set<lldb::LanguageType> languages_for_expressions;
+ LanguageSet languages_for_expressions =
+ Language::GetLanguagesSupportingTypeSystemsForExpressions();
- Language::GetLanguagesSupportingTypeSystems(languages_for_types,
- languages_for_expressions);
-
- if (languages_for_expressions.count(eLanguageTypeC)) {
+ if (languages_for_expressions[eLanguageTypeC]) {
language = eLanguageTypeC; // LLDB's default. Override by setting the
// target language.
} else {
- if (languages_for_expressions.empty()) {
- return nullptr;
- } else {
- language = *languages_for_expressions.begin();
- }
+ if (languages_for_expressions.Empty())
+ return llvm::make_error<llvm::StringError>(
+ "No expression support for any languages",
+ llvm::inconvertibleErrorCode());
+ language = (LanguageType)languages_for_expressions.bitvector.find_first();
}
}
@@ -2199,39 +2142,63 @@ TypeSystem *Target::GetScratchTypeSystemForLanguage(Status *error,
create_on_demand);
}
+std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) {
+ if (!m_valid)
+ return {};
+
+ std::vector<TypeSystem *> scratch_type_systems;
+
+ LanguageSet languages_for_expressions =
+ Language::GetLanguagesSupportingTypeSystemsForExpressions();
+
+ for (auto bit : languages_for_expressions.bitvector.set_bits()) {
+ auto language = (LanguageType)bit;
+ auto type_system_or_err =
+ GetScratchTypeSystemForLanguage(language, create_on_demand);
+ if (!type_system_or_err)
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
+ type_system_or_err.takeError(),
+ "Language '{}' has expression support but no scratch type "
+ "system available",
+ Language::GetNameForLanguageType(language));
+ else
+ scratch_type_systems.emplace_back(&type_system_or_err.get());
+ }
+
+ return scratch_type_systems;
+}
+
PersistentExpressionState *
Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
- TypeSystem *type_system =
- GetScratchTypeSystemForLanguage(nullptr, language, true);
+ auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true);
- if (type_system) {
- return type_system->GetPersistentExpressionState();
- } else {
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
+ std::move(err),
+ "Unable to get persistent expression state for language {}",
+ Language::GetNameForLanguageType(language));
return nullptr;
}
+
+ return type_system_or_err->GetPersistentExpressionState();
}
UserExpression *Target::GetUserExpressionForLanguage(
llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
Expression::ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ValueObject *ctx_obj, Status &error) {
- Status type_system_error;
-
- TypeSystem *type_system =
- GetScratchTypeSystemForLanguage(&type_system_error, language);
- UserExpression *user_expr = nullptr;
-
- if (!type_system) {
+ const EvaluateExpressionOptions &options, ValueObject *ctx_obj,
+ Status &error) {
+ auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
+ if (auto err = type_system_or_err.takeError()) {
error.SetErrorStringWithFormat(
"Could not find type system for language %s: %s",
Language::GetNameForLanguageType(language),
- type_system_error.AsCString());
+ llvm::toString(std::move(err)).c_str());
return nullptr;
}
- user_expr = type_system->GetUserExpression(expr, prefix, language,
- desired_type, options, ctx_obj);
+ auto *user_expr = type_system_or_err->GetUserExpression(
+ expr, prefix, language, desired_type, options, ctx_obj);
if (!user_expr)
error.SetErrorStringWithFormat(
"Could not create an expression for language %s",
@@ -2244,21 +2211,17 @@ FunctionCaller *Target::GetFunctionCallerForLanguage(
lldb::LanguageType language, const CompilerType &return_type,
const Address &function_address, const ValueList &arg_value_list,
const char *name, Status &error) {
- Status type_system_error;
- TypeSystem *type_system =
- GetScratchTypeSystemForLanguage(&type_system_error, language);
- FunctionCaller *persistent_fn = nullptr;
-
- if (!type_system) {
+ auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
+ if (auto err = type_system_or_err.takeError()) {
error.SetErrorStringWithFormat(
"Could not find type system for language %s: %s",
Language::GetNameForLanguageType(language),
- type_system_error.AsCString());
- return persistent_fn;
+ llvm::toString(std::move(err)).c_str());
+ return nullptr;
}
- persistent_fn = type_system->GetFunctionCaller(return_type, function_address,
- arg_value_list, name);
+ auto *persistent_fn = type_system_or_err->GetFunctionCaller(
+ return_type, function_address, arg_value_list, name);
if (!persistent_fn)
error.SetErrorStringWithFormat(
"Could not create an expression for language %s",
@@ -2271,20 +2234,17 @@ UtilityFunction *
Target::GetUtilityFunctionForLanguage(const char *text,
lldb::LanguageType language,
const char *name, Status &error) {
- Status type_system_error;
- TypeSystem *type_system =
- GetScratchTypeSystemForLanguage(&type_system_error, language);
- UtilityFunction *utility_fn = nullptr;
+ auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
- if (!type_system) {
+ if (auto err = type_system_or_err.takeError()) {
error.SetErrorStringWithFormat(
"Could not find type system for language %s: %s",
Language::GetNameForLanguageType(language),
- type_system_error.AsCString());
- return utility_fn;
+ llvm::toString(std::move(err)).c_str());
+ return nullptr;
}
- utility_fn = type_system->GetUtilityFunction(text, name);
+ auto *utility_fn = type_system_or_err->GetUtilityFunction(text, name);
if (!utility_fn)
error.SetErrorStringWithFormat(
"Could not create an expression for language %s",
@@ -2294,12 +2254,17 @@ Target::GetUtilityFunctionForLanguage(const char *text,
}
ClangASTContext *Target::GetScratchClangASTContext(bool create_on_demand) {
- if (m_valid) {
- if (TypeSystem *type_system = GetScratchTypeSystemForLanguage(
- nullptr, eLanguageTypeC, create_on_demand))
- return llvm::dyn_cast<ClangASTContext>(type_system);
+ if (!m_valid)
+ return nullptr;
+
+ auto type_system_or_err =
+ GetScratchTypeSystemForLanguage(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 ClangASTContext");
+ return nullptr;
}
- return nullptr;
+ return llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get());
}
ClangASTImporterSP Target::GetClangASTImporter() {
@@ -2340,10 +2305,10 @@ ArchSpec Target::GetDefaultArchitecture() {
void Target::SetDefaultArchitecture(const ArchSpec &arch) {
TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
if (properties_sp) {
- LogIfAnyCategoriesSet(
- LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's "
- "default architecture to %s (%s)",
- arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
+ LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET),
+ "Target::SetDefaultArchitecture setting target's "
+ "default architecture to {0} ({1})",
+ arch.GetArchitectureName(), arch.GetTriple().getTriple());
return properties_sp->SetDefaultArchitecture(arch);
}
}
@@ -2378,7 +2343,8 @@ ExpressionResults Target::EvaluateExpression(
bool old_suppress_value = m_suppress_stop_hooks;
m_suppress_stop_hooks = true;
auto on_exit = llvm::make_scope_exit([this, old_suppress_value]() {
- m_suppress_stop_hooks = old_suppress_value; });
+ m_suppress_stop_hooks = old_suppress_value;
+ });
ExecutionContext exe_ctx;
@@ -2392,13 +2358,19 @@ ExpressionResults Target::EvaluateExpression(
// Make sure we aren't just trying to see the value of a persistent variable
// (something like "$0")
- lldb::ExpressionVariableSP persistent_var_sp;
// Only check for persistent variables the expression starts with a '$'
- if (expr[0] == '$')
- persistent_var_sp = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC)
- ->GetPersistentExpressionState()
- ->GetVariable(expr);
-
+ lldb::ExpressionVariableSP persistent_var_sp;
+ if (expr[0] == '$') {
+ auto type_system_or_err =
+ GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
+ std::move(err), "Unable to get scratch type system");
+ } else {
+ persistent_var_sp =
+ type_system_or_err->GetPersistentExpressionState()->GetVariable(expr);
+ }
+ }
if (persistent_var_sp) {
result_valobj_sp = persistent_var_sp->GetValueObject();
execution_results = eExpressionCompleted;
@@ -2415,8 +2387,7 @@ ExpressionResults Target::EvaluateExpression(
return execution_results;
}
-lldb::ExpressionVariableSP
-Target::GetPersistentVariable(ConstString name) {
+lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) {
lldb::ExpressionVariableSP variable_sp;
m_scratch_type_system_map.ForEach(
[name, &variable_sp](TypeSystem *type_system) -> bool {
@@ -2448,24 +2419,61 @@ lldb::addr_t Target::GetPersistentSymbol(ConstString name) {
return address;
}
+llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {
+ Module *exe_module = GetExecutableModulePointer();
+ llvm::Error error = llvm::Error::success();
+ assert(!error); // Check the success value when assertions are enabled.
+
+ if (!exe_module || !exe_module->GetObjectFile()) {
+ error = llvm::make_error<llvm::StringError>("No primary executable found",
+ llvm::inconvertibleErrorCode());
+ } else {
+ Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress();
+ if (entry_addr.IsValid())
+ return entry_addr;
+
+ error = llvm::make_error<llvm::StringError>(
+ "Could not find entry point address for executable module \"" +
+ exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"",
+ llvm::inconvertibleErrorCode());
+ }
+
+ const ModuleList &modules = GetImages();
+ const size_t num_images = modules.GetSize();
+ for (size_t idx = 0; idx < num_images; ++idx) {
+ ModuleSP module_sp(modules.GetModuleAtIndex(idx));
+ if (!module_sp || !module_sp->GetObjectFile())
+ continue;
+
+ Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
+ if (entry_addr.IsValid()) {
+ // Discard the error.
+ llvm::consumeError(std::move(error));
+ return entry_addr;
+ }
+ }
+
+ return std::move(error);
+}
+
lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
AddressClass addr_class) const {
auto arch_plugin = GetArchitecturePlugin();
- return arch_plugin ?
- arch_plugin->GetCallableLoadAddress(load_addr, addr_class) : load_addr;
+ return arch_plugin
+ ? arch_plugin->GetCallableLoadAddress(load_addr, addr_class)
+ : load_addr;
}
lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
AddressClass addr_class) const {
auto arch_plugin = GetArchitecturePlugin();
- return arch_plugin ?
- arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class) : load_addr;
+ return arch_plugin ? arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class)
+ : load_addr;
}
lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
auto arch_plugin = GetArchitecturePlugin();
- return arch_plugin ?
- arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;
+ return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;
}
SourceManager &Target::GetSourceManager() {
@@ -2539,7 +2547,7 @@ void Target::RunStopHooks() {
if (!m_process_sp)
return;
-
+
// Somebody might have restarted the process:
if (m_process_sp->GetState() != eStateStopped)
return;
@@ -2658,11 +2666,12 @@ void Target::RunStopHooks() {
// But only complain if there were more stop hooks to do:
StopHookCollection::iterator tmp = pos;
if (++tmp != end)
- result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64
- " set the program running.\n"
- " Consider using '-G true' to make "
- "stop hooks auto-continue.\n",
- cur_hook_sp->GetID());
+ result.AppendMessageWithFormat(
+ "\nAborting stop hooks, hook %" PRIu64
+ " set the program running.\n"
+ " Consider using '-G true' to make "
+ "stop hooks auto-continue.\n",
+ cur_hook_sp->GetID());
keep_going = false;
did_restart = true;
}
@@ -2820,9 +2829,8 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
Status error;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
- if (log)
- log->Printf("Target::%s() called for %s", __FUNCTION__,
- launch_info.GetExecutableFile().GetPath().c_str());
+ LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__,
+ launch_info.GetExecutableFile().GetPath().c_str());
StateType state = eStateInvalid;
@@ -2834,14 +2842,12 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
if (process_sp) {
state = process_sp->GetState();
- if (log)
- log->Printf(
- "Target::%s the process exists, and its current state is %s",
- __FUNCTION__, StateAsCString(state));
+ LLDB_LOGF(log,
+ "Target::%s the process exists, and its current state is %s",
+ __FUNCTION__, StateAsCString(state));
} else {
- if (log)
- log->Printf("Target::%s the process instance doesn't currently exist.",
- __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s the process instance doesn't currently exist.",
+ __FUNCTION__);
}
}
@@ -2873,24 +2879,23 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
// that can launch a process for debugging, go ahead and do that here.
if (state != eStateConnected && platform_sp &&
platform_sp->CanDebugProcess()) {
- if (log)
- log->Printf("Target::%s asking the platform to debug the process",
- __FUNCTION__);
+ LLDB_LOGF(log, "Target::%s asking the platform to debug the process",
+ __FUNCTION__);
// If there was a previous process, delete it before we make the new one.
// One subtle point, we delete the process before we release the reference
// to m_process_sp. That way even if we are the last owner, the process
// will get Finalized before it gets destroyed.
DeleteCurrentProcess();
-
+
m_process_sp =
GetPlatform()->DebugProcess(launch_info, debugger, this, error);
} else {
- if (log)
- log->Printf("Target::%s the platform doesn't know how to debug a "
- "process, getting a process plugin to do this for us.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "Target::%s the platform doesn't know how to debug a "
+ "process, getting a process plugin to do this for us.",
+ __FUNCTION__);
if (state == eStateConnected) {
assert(m_process_sp);
@@ -2928,9 +2933,9 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
if (state == eStateStopped) {
if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
if (synchronous_execution) {
- // Now we have handled the stop-from-attach, and we are just switching
- // to a synchronous resume. So we should switch to the SyncResume
- // hijacker.
+ // Now we have handled the stop-from-attach, and we are just
+ // switching to a synchronous resume. So we should switch to the
+ // SyncResume hijacker.
m_process_sp->RestoreProcessEvents();
m_process_sp->ResumeSynchronous(stream);
} else {
@@ -3213,33 +3218,51 @@ void Target::StopHook::GetDescription(Stream *s,
s->SetIndentLevel(indent_level);
}
-// class TargetProperties
-
-// clang-format off
static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
- {eNoDynamicValues, "no-dynamic-values",
- "Don't calculate the dynamic type of values"},
- {eDynamicCanRunTarget, "run-target", "Calculate the dynamic type of values "
- "even if you have to run the target."},
- {eDynamicDontRunTarget, "no-run-target",
- "Calculate the dynamic type of values, but don't run the target."} };
+ {
+ eNoDynamicValues,
+ "no-dynamic-values",
+ "Don't calculate the dynamic type of values",
+ },
+ {
+ eDynamicCanRunTarget,
+ "run-target",
+ "Calculate the dynamic type of values "
+ "even if you have to run the target.",
+ },
+ {
+ eDynamicDontRunTarget,
+ "no-run-target",
+ "Calculate the dynamic type of values, but don't run the target.",
+ },
+};
OptionEnumValues lldb_private::GetDynamicValueTypes() {
return OptionEnumValues(g_dynamic_value_types);
}
static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = {
- {eInlineBreakpointsNever, "never", "Never look for inline breakpoint "
- "locations (fastest). This setting "
- "should only be used if you know that "
- "no inlining occurs in your programs."},
- {eInlineBreakpointsHeaders, "headers",
- "Only check for inline breakpoint locations when setting breakpoints in "
- "header files, but not when setting breakpoint in implementation source "
- "files (default)."},
- {eInlineBreakpointsAlways, "always",
- "Always look for inline breakpoint locations when setting file and line "
- "breakpoints (slower but most accurate)."} };
+ {
+ eInlineBreakpointsNever,
+ "never",
+ "Never look for inline breakpoint locations (fastest). This setting "
+ "should only be used if you know that no inlining occurs in your"
+ "programs.",
+ },
+ {
+ eInlineBreakpointsHeaders,
+ "headers",
+ "Only check for inline breakpoint locations when setting breakpoints "
+ "in header files, but not when setting breakpoint in implementation "
+ "source files (default).",
+ },
+ {
+ eInlineBreakpointsAlways,
+ "always",
+ "Always look for inline breakpoint locations when setting file and "
+ "line breakpoints (slower but most accurate).",
+ },
+};
enum x86DisassemblyFlavor {
eX86DisFlavorDefault,
@@ -3248,258 +3271,99 @@ enum x86DisassemblyFlavor {
};
static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {
- {eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
- {eX86DisFlavorIntel, "intel", "Intel disassembler flavor."},
- {eX86DisFlavorATT, "att", "AT&T disassembler flavor."} };
+ {
+ eX86DisFlavorDefault,
+ "default",
+ "Disassembler default (currently att).",
+ },
+ {
+ eX86DisFlavorIntel,
+ "intel",
+ "Intel disassembler flavor.",
+ },
+ {
+ eX86DisFlavorATT,
+ "att",
+ "AT&T disassembler flavor.",
+ },
+};
static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {
- {Disassembler::eHexStyleC, "c", "C-style (0xffff)."},
- {Disassembler::eHexStyleAsm, "asm", "Asm-style (0ffffh)."} };
+ {
+ Disassembler::eHexStyleC,
+ "c",
+ "C-style (0xffff).",
+ },
+ {
+ Disassembler::eHexStyleAsm,
+ "asm",
+ "Asm-style (0ffffh).",
+ },
+};
static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = {
- {eLoadScriptFromSymFileTrue, "true",
- "Load debug scripts inside symbol files"},
- {eLoadScriptFromSymFileFalse, "false",
- "Do not load debug scripts inside symbol files."},
- {eLoadScriptFromSymFileWarn, "warn",
- "Warn about debug scripts inside symbol files but do not load them."} };
-
-static constexpr
-OptionEnumValueElement g_load_current_working_dir_lldbinit_values[] = {
- {eLoadCWDlldbinitTrue, "true",
- "Load .lldbinit files from current directory"},
- {eLoadCWDlldbinitFalse, "false",
- "Do not load .lldbinit files from current directory"},
- {eLoadCWDlldbinitWarn, "warn",
- "Warn about loading .lldbinit files from current directory"} };
+ {
+ eLoadScriptFromSymFileTrue,
+ "true",
+ "Load debug scripts inside symbol files",
+ },
+ {
+ eLoadScriptFromSymFileFalse,
+ "false",
+ "Do not load debug scripts inside symbol files.",
+ },
+ {
+ eLoadScriptFromSymFileWarn,
+ "warn",
+ "Warn about debug scripts inside symbol files but do not load them.",
+ },
+};
+
+static constexpr OptionEnumValueElement g_load_cwd_lldbinit_values[] = {
+ {
+ eLoadCWDlldbinitTrue,
+ "true",
+ "Load .lldbinit files from current directory",
+ },
+ {
+ eLoadCWDlldbinitFalse,
+ "false",
+ "Do not load .lldbinit files from current directory",
+ },
+ {
+ eLoadCWDlldbinitWarn,
+ "warn",
+ "Warn about loading .lldbinit files from current directory",
+ },
+};
static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {
- {eMemoryModuleLoadLevelMinimal, "minimal",
- "Load minimal information when loading modules from memory. Currently "
- "this setting loads sections only."},
- {eMemoryModuleLoadLevelPartial, "partial",
- "Load partial information when loading modules from memory. Currently "
- "this setting loads sections and function bounds."},
- {eMemoryModuleLoadLevelComplete, "complete",
- "Load complete information when loading modules from memory. Currently "
- "this setting loads sections and all symbols."} };
-
-static constexpr PropertyDefinition g_properties[] = {
- {"default-arch", OptionValue::eTypeArch, true, 0, nullptr, {},
- "Default architecture to choose, when there's a choice."},
- {"move-to-nearest-code", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Move breakpoints to nearest code."},
- {"language", OptionValue::eTypeLanguage, false, eLanguageTypeUnknown,
- nullptr, {},
- "The language to use when interpreting expressions entered in commands."},
- {"expr-prefix", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
- "Path to a file containing expressions to be prepended to all "
- "expressions."},
- {"prefer-dynamic-value", OptionValue::eTypeEnum, false,
- eDynamicDontRunTarget, nullptr, OptionEnumValues(g_dynamic_value_types),
- "Should printed values be shown as their dynamic value."},
- {"enable-synthetic-value", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Should synthetic values be used by default whenever available."},
- {"skip-prologue", OptionValue::eTypeBoolean, false, true, nullptr, {},
- "Skip function prologues when setting breakpoints by name."},
- {"source-map", OptionValue::eTypePathMap, false, 0, nullptr, {},
- "Source path remappings are used to track the change of location between "
- "a source file when built, and "
- "where it exists on the current system. It consists of an array of "
- "duples, the first element of each duple is "
- "some part (starting at the root) of the path to the file when it was "
- "built, "
- "and the second is where the remainder of the original build hierarchy is "
- "rooted on the local system. "
- "Each element of the array is checked in order and the first one that "
- "results in a match wins."},
- {"exec-search-paths", OptionValue::eTypeFileSpecList, false, 0, nullptr,
- {}, "Executable search paths to use when locating executable files "
- "whose paths don't match the local file system."},
- {"debug-file-search-paths", OptionValue::eTypeFileSpecList, false, 0,
- nullptr, {},
- "List of directories to be searched when locating debug symbol files. "
- "See also symbols.enable-external-lookup."},
- {"clang-module-search-paths", OptionValue::eTypeFileSpecList, false, 0,
- nullptr, {},
- "List of directories to be searched when locating modules for Clang."},
- {"auto-import-clang-modules", OptionValue::eTypeBoolean, false, true,
- nullptr, {},
- "Automatically load Clang modules referred to by the program."},
- {"import-std-module", OptionValue::eTypeBoolean, false, false,
- nullptr, {},
- "Import the C++ std module to improve debugging STL containers."},
- {"auto-apply-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Automatically apply fix-it hints to expressions."},
- {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Print the fixed expression text."},
- {"save-jit-objects", OptionValue::eTypeBoolean, false, false, nullptr,
- {}, "Save intermediate object files generated by the LLVM JIT"},
- {"max-children-count", OptionValue::eTypeSInt64, false, 256, nullptr,
- {}, "Maximum number of children to expand in any level of depth."},
- {"max-string-summary-length", OptionValue::eTypeSInt64, false, 1024,
- nullptr, {},
- "Maximum number of characters to show when using %s in summary strings."},
- {"max-memory-read-size", OptionValue::eTypeSInt64, false, 1024, nullptr,
- {}, "Maximum number of bytes that 'memory read' will fetch before "
- "--force must be specified."},
- {"breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean, false,
- true, nullptr, {}, "Consult the platform module avoid list when "
- "setting non-module specific breakpoints."},
- {"arg0", OptionValue::eTypeString, false, 0, nullptr, {},
- "The first argument passed to the program in the argument array which can "
- "be different from the executable itself."},
- {"run-args", OptionValue::eTypeArgs, false, 0, nullptr, {},
- "A list containing all the arguments to be passed to the executable when "
- "it is run. Note that this does NOT include the argv[0] which is in "
- "target.arg0."},
- {"env-vars", OptionValue::eTypeDictionary, false, OptionValue::eTypeString,
- nullptr, {}, "A list of all the environment variables to be passed "
- "to the executable's environment, and their values."},
- {"inherit-env", OptionValue::eTypeBoolean, false, true, nullptr, {},
- "Inherit the environment from the process that is running LLDB."},
- {"input-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
- "The file/path to be used by the executable program for reading its "
- "standard input."},
- {"output-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
- "The file/path to be used by the executable program for writing its "
- "standard output."},
- {"error-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
- "The file/path to be used by the executable program for writing its "
- "standard error."},
- {"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "debugserver will detach (rather than killing) a process if it "
- "loses connection with lldb."},
- {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, {},
- "Enable loading of symbol tables before they are needed."},
- {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, {},
- "Disable Address Space Layout Randomization (ASLR)"},
- {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, {},
- "Disable stdin/stdout for process (e.g. for a GUI application)"},
- {"inline-breakpoint-strategy", OptionValue::eTypeEnum, false,
- eInlineBreakpointsAlways, nullptr,
- OptionEnumValues(g_inline_breakpoint_enums),
- "The strategy to use when settings breakpoints by file and line. "
- "Breakpoint locations can end up being inlined by the compiler, so that a "
- "compile unit 'a.c' might contain an inlined function from another source "
- "file. "
- "Usually this is limited to breakpoint locations from inlined functions "
- "from header or other include files, or more accurately "
- "non-implementation source files. "
- "Sometimes code might #include implementation files and cause inlined "
- "breakpoint locations in inlined implementation files. "
- "Always checking for inlined breakpoint locations can be expensive "
- "(memory and time), so if you have a project with many headers "
- "and find that setting breakpoints is slow, then you can change this "
- "setting to headers. "
- "This setting allows you to control exactly which strategy is used when "
- "setting "
- "file and line breakpoints."},
- // FIXME: This is the wrong way to do per-architecture settings, but we
- // don't have a general per architecture settings system in place yet.
- {"x86-disassembly-flavor", OptionValue::eTypeEnum, false,
- eX86DisFlavorDefault, nullptr,
- OptionEnumValues(g_x86_dis_flavor_value_types),
- "The default disassembly flavor to use for x86 or x86-64 targets."},
- {"use-hex-immediates", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Show immediates in disassembly as hexadecimal."},
- {"hex-immediate-style", OptionValue::eTypeEnum, false,
- Disassembler::eHexStyleC, nullptr,
- OptionEnumValues(g_hex_immediate_style_values),
- "Which style to use for printing hexadecimal disassembly values."},
- {"use-fast-stepping", OptionValue::eTypeBoolean, false, true, nullptr,
- {}, "Use a fast stepping algorithm based on running from branch to "
- "branch rather than instruction single-stepping."},
- {"load-script-from-symbol-file", OptionValue::eTypeEnum, false,
- eLoadScriptFromSymFileWarn, nullptr,
- OptionEnumValues(g_load_script_from_sym_file_values),
- "Allow LLDB to load scripting resources embedded in symbol files when "
- "available."},
- {"load-cwd-lldbinit", OptionValue::eTypeEnum, false, eLoadCWDlldbinitWarn,
- nullptr, OptionEnumValues(g_load_current_working_dir_lldbinit_values),
- "Allow LLDB to .lldbinit files from the current directory automatically."},
- {"memory-module-load-level", OptionValue::eTypeEnum, false,
- eMemoryModuleLoadLevelComplete, nullptr,
- OptionEnumValues(g_memory_module_load_level_values),
- "Loading modules from memory can be slow as reading the symbol tables and "
- "other data can take a long time depending on your connection to the "
- "debug target. "
- "This setting helps users control how much information gets loaded when "
- "loading modules from memory."
- "'complete' is the default value for this setting which will load all "
- "sections and symbols by reading them from memory (slowest, most "
- "accurate). "
- "'partial' will load sections and attempt to find function bounds without "
- "downloading the symbol table (faster, still accurate, missing symbol "
- "names). "
- "'minimal' is the fastest setting and will load section data with no "
- "symbols, but should rarely be used as stack frames in these memory "
- "regions will be inaccurate and not provide any context (fastest). "},
- {"display-expression-in-crashlogs", OptionValue::eTypeBoolean, false, false,
- nullptr, {}, "Expressions that crash will show up in crash logs if "
- "the host system supports executable specific crash log "
- "strings and this setting is set to true."},
- {"trap-handler-names", OptionValue::eTypeArray, true,
- OptionValue::eTypeString, nullptr, {},
- "A list of trap handler function names, e.g. a common Unix user process "
- "one is _sigtramp."},
- {"display-runtime-support-values", OptionValue::eTypeBoolean, false, false,
- nullptr, {}, "If true, LLDB will show variables that are meant to "
- "support the operation of a language's runtime support."},
- {"display-recognized-arguments", OptionValue::eTypeBoolean, false, false,
- nullptr, {}, "Show recognized arguments in variable listings by default."},
- {"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, {},
- "Disable lock-step debugging, instead control threads independently."},
- {"require-hardware-breakpoint", OptionValue::eTypeBoolean, false, 0,
- nullptr, {}, "Require all breakpoints to be hardware breakpoints."}};
-// clang-format on
+ {
+ eMemoryModuleLoadLevelMinimal,
+ "minimal",
+ "Load minimal information when loading modules from memory. Currently "
+ "this setting loads sections only.",
+ },
+ {
+ eMemoryModuleLoadLevelPartial,
+ "partial",
+ "Load partial information when loading modules from memory. Currently "
+ "this setting loads sections and function bounds.",
+ },
+ {
+ eMemoryModuleLoadLevelComplete,
+ "complete",
+ "Load complete information when loading modules from memory. Currently "
+ "this setting loads sections and all symbols.",
+ },
+};
+
+#define LLDB_PROPERTIES_target
+#include "TargetProperties.inc"
enum {
- ePropertyDefaultArch,
- ePropertyMoveToNearestCode,
- ePropertyLanguage,
- ePropertyExprPrefix,
- ePropertyPreferDynamic,
- ePropertyEnableSynthetic,
- ePropertySkipPrologue,
- ePropertySourceMap,
- ePropertyExecutableSearchPaths,
- ePropertyDebugFileSearchPaths,
- ePropertyClangModuleSearchPaths,
- ePropertyAutoImportClangModules,
- ePropertyImportStdModule,
- ePropertyAutoApplyFixIts,
- ePropertyNotifyAboutFixIts,
- ePropertySaveObjects,
- ePropertyMaxChildrenCount,
- ePropertyMaxSummaryLength,
- ePropertyMaxMemReadSize,
- ePropertyBreakpointUseAvoidList,
- ePropertyArg0,
- ePropertyRunArgs,
- ePropertyEnvVars,
- ePropertyInheritEnv,
- ePropertyInputPath,
- ePropertyOutputPath,
- ePropertyErrorPath,
- ePropertyDetachOnError,
- ePropertyPreloadSymbols,
- ePropertyDisableASLR,
- ePropertyDisableSTDIO,
- ePropertyInlineStrategy,
- ePropertyDisassemblyFlavor,
- ePropertyUseHexImmediates,
- ePropertyHexImmediateStyle,
- ePropertyUseFastStepping,
- ePropertyLoadScriptFromSymbolFile,
- ePropertyLoadCWDlldbinitFile,
- ePropertyMemoryModuleLoadLevel,
- ePropertyDisplayExpressionsInCrashlogs,
- ePropertyTrapHandlerNames,
- ePropertyDisplayRuntimeSupportValues,
- ePropertyDisplayRecognizedArguments,
- ePropertyNonStopModeEnabled,
- ePropertyRequireHardwareBreakpoints,
+#define LLDB_PROPERTIES_target
+#include "TargetPropertiesEnum.inc"
ePropertyExperimental,
};
@@ -3547,7 +3411,7 @@ protected:
m_got_host_env = true;
const uint32_t idx = ePropertyInheritEnv;
if (GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0)) {
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0)) {
PlatformSP platform_sp(m_target->GetPlatform());
if (platform_sp) {
Environment env = platform_sp->GetEnvironment();
@@ -3575,17 +3439,13 @@ protected:
};
// TargetProperties
-static constexpr PropertyDefinition g_experimental_properties[]{
- {"inject-local-vars", OptionValue::eTypeBoolean, true, true, nullptr,
- {},
- "If true, inject local variables explicitly into the expression text. "
- "This will fix symbol resolution when there are name collisions between "
- "ivars and local variables. "
- "But it can make expressions run much more slowly."},
- {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr,
- {}, "If true, use Clang's modern type lookup infrastructure."}};
-
-enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup };
+#define LLDB_PROPERTIES_experimental
+#include "TargetProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_experimental
+#include "TargetPropertiesEnum.inc"
+};
class TargetExperimentalOptionValueProperties : public OptionValueProperties {
public:
@@ -3655,7 +3515,7 @@ TargetProperties::TargetProperties(Target *target)
} else {
m_collection_sp =
std::make_shared<TargetOptionValueProperties>(ConstString("target"));
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_target_properties);
m_experimental_properties_up.reset(new TargetExperimentalProperties());
m_collection_sp->AppendProperty(
ConstString(Properties::GetExperimentalSettingsName()),
@@ -3724,14 +3584,14 @@ void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {
bool TargetProperties::GetMoveToNearestCode() const {
const uint32_t idx = ePropertyMoveToNearestCode;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {
const uint32_t idx = ePropertyPreferDynamic;
return (lldb::DynamicValueType)
m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
@@ -3742,7 +3602,7 @@ bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
bool TargetProperties::GetPreloadSymbols() const {
const uint32_t idx = ePropertyPreloadSymbols;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
void TargetProperties::SetPreloadSymbols(bool b) {
@@ -3753,7 +3613,7 @@ void TargetProperties::SetPreloadSymbols(bool b) {
bool TargetProperties::GetDisableASLR() const {
const uint32_t idx = ePropertyDisableASLR;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
void TargetProperties::SetDisableASLR(bool b) {
@@ -3764,7 +3624,7 @@ void TargetProperties::SetDisableASLR(bool b) {
bool TargetProperties::GetDetachOnError() const {
const uint32_t idx = ePropertyDetachOnError;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
void TargetProperties::SetDetachOnError(bool b) {
@@ -3775,7 +3635,7 @@ void TargetProperties::SetDetachOnError(bool b) {
bool TargetProperties::GetDisableSTDIO() const {
const uint32_t idx = ePropertyDisableSTDIO;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
void TargetProperties::SetDisableSTDIO(bool b) {
@@ -3789,7 +3649,7 @@ const char *TargetProperties::GetDisassemblyFlavor() const {
x86DisassemblyFlavor flavor_value =
(x86DisassemblyFlavor)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
return return_value;
}
@@ -3797,18 +3657,18 @@ const char *TargetProperties::GetDisassemblyFlavor() const {
InlineStrategy TargetProperties::GetInlineStrategy() const {
const uint32_t idx = ePropertyInlineStrategy;
return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
llvm::StringRef TargetProperties::GetArg0() const {
const uint32_t idx = ePropertyArg0;
- return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, llvm::StringRef());
+ return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx,
+ llvm::StringRef());
}
void TargetProperties::SetArg0(llvm::StringRef arg) {
const uint32_t idx = ePropertyArg0;
- m_collection_sp->SetPropertyAtIndexAsString(
- nullptr, idx, arg);
+ m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, arg);
m_launch_info.SetArg0(arg);
}
@@ -3841,7 +3701,7 @@ void TargetProperties::SetEnvironment(Environment env) {
bool TargetProperties::GetSkipPrologue() const {
const uint32_t idx = ePropertySkipPrologue;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
PathMappingList &TargetProperties::GetSourcePathMap() const {
@@ -3853,7 +3713,7 @@ PathMappingList &TargetProperties::GetSourcePathMap() const {
return option_value->GetCurrentValue();
}
-void TargetProperties::AppendExecutableSearchPaths(const FileSpec& dir) {
+void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) {
const uint32_t idx = ePropertyExecutableSearchPaths;
OptionValueFileSpecList *option_value =
m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
@@ -3892,55 +3752,61 @@ FileSpecList TargetProperties::GetClangModuleSearchPaths() {
bool TargetProperties::GetEnableAutoImportClangModules() const {
const uint32_t idx = ePropertyAutoImportClangModules;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableImportStdModule() const {
const uint32_t idx = ePropertyImportStdModule;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableAutoApplyFixIts() const {
const uint32_t idx = ePropertyAutoApplyFixIts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableNotifyAboutFixIts() const {
const uint32_t idx = ePropertyNotifyAboutFixIts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableSaveObjects() const {
const uint32_t idx = ePropertySaveObjects;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableSyntheticValue() const {
const uint32_t idx = ePropertyEnableSynthetic;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
+}
+
+uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const {
+ const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
const uint32_t idx = ePropertyMaxChildrenCount;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
const uint32_t idx = ePropertyMaxSummaryLength;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
uint32_t TargetProperties::GetMaximumMemReadSize() const {
const uint32_t idx = ePropertyMaxMemReadSize;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
FileSpec TargetProperties::GetStandardInputPath() const {
@@ -4000,52 +3866,52 @@ llvm::StringRef TargetProperties::GetExpressionPrefixContents() {
bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
const uint32_t idx = ePropertyBreakpointUseAvoidList;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetUseHexImmediates() const {
const uint32_t idx = ePropertyUseHexImmediates;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetUseFastStepping() const {
const uint32_t idx = ePropertyUseFastStepping;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {
const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {
const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
return (LoadScriptFromSymFile)
m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {
const uint32_t idx = ePropertyLoadCWDlldbinitFile;
return (LoadCWDlldbinitFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {
const uint32_t idx = ePropertyHexImmediateStyle;
return (Disassembler::HexImmediateStyle)
m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {
const uint32_t idx = ePropertyMemoryModuleLoadLevel;
return (MemoryModuleLoadLevel)
m_collection_sp->GetPropertyAtIndexAsEnumeration(
- nullptr, idx, g_properties[idx].default_uint_value);
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {
@@ -4122,7 +3988,7 @@ void TargetProperties::SetProcessLaunchInfo(
bool TargetProperties::GetRequireHardwareBreakpoints() const {
const uint32_t idx = ePropertyRequireHardwareBreakpoints;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
void TargetProperties::SetRequireHardwareBreakpoints(bool b) {
@@ -4259,3 +4125,10 @@ Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
module_list = event_data->m_module_list;
return module_list;
}
+
+std::recursive_mutex &Target::GetAPIMutex() {
+ if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread())
+ return m_private_mutex;
+ else
+ return m_mutex;
+}
diff --git a/source/Target/TargetProperties.td b/source/Target/TargetProperties.td
new file mode 100644
index 000000000000..9079c3cf4276
--- /dev/null
+++ b/source/Target/TargetProperties.td
@@ -0,0 +1,237 @@
+include "../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "experimental" in {
+ def InjectLocalVars : Property<"inject-local-vars", "Boolean">,
+ Global, DefaultTrue,
+ Desc<"If true, inject local variables explicitly into the expression text. This will fix symbol resolution when there are name collisions between ivars and local variables. But it can make expressions run much more slowly.">;
+ def UseModernTypeLookup : Property<"use-modern-type-lookup", "Boolean">,
+ Global, DefaultFalse,
+ Desc<"If true, use Clang's modern type lookup infrastructure.">;
+}
+
+let Definition = "target" in {
+ def DefaultArch: Property<"default-arch", "Arch">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Default architecture to choose, when there's a choice.">;
+ def MoveToNearestCode: Property<"move-to-nearest-code", "Boolean">,
+ DefaultTrue,
+ Desc<"Move breakpoints to nearest code.">;
+ def Language: Property<"language", "Language">,
+ DefaultEnumValue<"eLanguageTypeUnknown">,
+ Desc<"The language to use when interpreting expressions entered in commands.">;
+ def ExprPrefix: Property<"expr-prefix", "FileSpec">,
+ DefaultStringValue<"">,
+ Desc<"Path to a file containing expressions to be prepended to all expressions.">;
+ def PreferDynamic: Property<"prefer-dynamic-value", "Enum">,
+ DefaultEnumValue<"eDynamicDontRunTarget">,
+ EnumValues<"OptionEnumValues(g_dynamic_value_types)">,
+ Desc<"Should printed values be shown as their dynamic value.">;
+ def EnableSynthetic: Property<"enable-synthetic-value", "Boolean">,
+ DefaultTrue,
+ Desc<"Should synthetic values be used by default whenever available.">;
+ def SkipPrologue: Property<"skip-prologue", "Boolean">,
+ DefaultTrue,
+ Desc<"Skip function prologues when setting breakpoints by name.">;
+ def SourceMap: Property<"source-map", "PathMap">,
+ DefaultStringValue<"">,
+ Desc<"Source path remappings are used to track the change of location between a source file when built, and where it exists on the current system. It consists of an array of duples, the first element of each duple is some part (starting at the root) of the path to the file when it was built, and the second is where the remainder of the original build hierarchy is rooted on the local system. Each element of the array is checked in order and the first one that results in a match wins.">;
+ def ExecutableSearchPaths: Property<"exec-search-paths", "FileSpecList">,
+ DefaultStringValue<"">,
+ Desc<"Executable search paths to use when locating executable files whose paths don't match the local file system.">;
+ def DebugFileSearchPaths: Property<"debug-file-search-paths", "FileSpecList">,
+ DefaultStringValue<"">,
+ Desc<"List of directories to be searched when locating debug symbol files. See also symbols.enable-external-lookup.">;
+ def ClangModuleSearchPaths: Property<"clang-module-search-paths", "FileSpecList">,
+ DefaultStringValue<"">,
+ Desc<"List of directories to be searched when locating modules for Clang.">;
+ def AutoImportClangModules: Property<"auto-import-clang-modules", "Boolean">,
+ DefaultTrue,
+ Desc<"Automatically load Clang modules referred to by the program.">;
+ def ImportStdModule: Property<"import-std-module", "Boolean">,
+ DefaultFalse,
+ Desc<"Import the C++ std module to improve debugging STL containers.">;
+ def AutoApplyFixIts: Property<"auto-apply-fixits", "Boolean">,
+ DefaultTrue,
+ Desc<"Automatically apply fix-it hints to expressions.">;
+ def NotifyAboutFixIts: Property<"notify-about-fixits", "Boolean">,
+ DefaultTrue,
+ Desc<"Print the fixed expression text.">;
+ def SaveObjects: Property<"save-jit-objects", "Boolean">,
+ DefaultFalse,
+ Desc<"Save intermediate object files generated by the LLVM JIT">;
+ def MaxZeroPaddingInFloatFormat: Property<"max-zero-padding-in-float-format", "UInt64">,
+ DefaultUnsignedValue<6>,
+ Desc<"The maximum number of zeroes to insert when displaying a very small float before falling back to scientific notation.">;
+ def MaxChildrenCount: Property<"max-children-count", "SInt64">,
+ DefaultUnsignedValue<256>,
+ Desc<"Maximum number of children to expand in any level of depth.">;
+ def MaxSummaryLength: Property<"max-string-summary-length", "SInt64">,
+ DefaultUnsignedValue<1024>,
+ Desc<"Maximum number of characters to show when using %s in summary strings.">;
+ def MaxMemReadSize: Property<"max-memory-read-size", "SInt64">,
+ DefaultUnsignedValue<1024>,
+ Desc<"Maximum number of bytes that 'memory read' will fetch before --force must be specified.">;
+ def BreakpointUseAvoidList: Property<"breakpoints-use-platform-avoid-list", "Boolean">,
+ DefaultTrue,
+ Desc<"Consult the platform module avoid list when setting non-module specific breakpoints.">;
+ def Arg0: Property<"arg0", "String">,
+ DefaultStringValue<"">,
+ Desc<"The first argument passed to the program in the argument array which can be different from the executable itself.">;
+ def RunArgs: Property<"run-args", "Args">,
+ DefaultStringValue<"">,
+ Desc<"A list containing all the arguments to be passed to the executable when it is run. Note that this does NOT include the argv[0] which is in target.arg0.">;
+ def EnvVars: Property<"env-vars", "Dictionary">,
+ DefaultUnsignedValue<16>,
+ Desc<"A list of all the environment variables to be passed to the executable's environment, and their values.">;
+ def InheritEnv: Property<"inherit-env", "Boolean">,
+ DefaultTrue,
+ Desc<"Inherit the environment from the process that is running LLDB.">;
+ def InputPath: Property<"input-path", "FileSpec">,
+ DefaultStringValue<"">,
+ Desc<"The file/path to be used by the executable program for reading its standard input.">;
+ def OutputPath: Property<"output-path", "FileSpec">,
+ DefaultStringValue<"">,
+ Desc<"The file/path to be used by the executable program for writing its standard output.">;
+ def ErrorPath: Property<"error-path", "FileSpec">,
+ DefaultStringValue<"">,
+ Desc<"The file/path to be used by the executable program for writing its standard error.">;
+ def DetachOnError: Property<"detach-on-error", "Boolean">,
+ DefaultTrue,
+ Desc<"debugserver will detach (rather than killing) a process if it loses connection with lldb.">;
+ def PreloadSymbols: Property<"preload-symbols", "Boolean">,
+ DefaultTrue,
+ Desc<"Enable loading of symbol tables before they are needed.">;
+ def DisableASLR: Property<"disable-aslr", "Boolean">,
+ DefaultTrue,
+ Desc<"Disable Address Space Layout Randomization (ASLR)">;
+ def DisableSTDIO: Property<"disable-stdio", "Boolean">,
+ DefaultFalse,
+ Desc<"Disable stdin/stdout for process (e.g. for a GUI application)">;
+ def InlineStrategy: Property<"inline-breakpoint-strategy", "Enum">,
+ DefaultEnumValue<"eInlineBreakpointsAlways">,
+ EnumValues<"OptionEnumValues(g_inline_breakpoint_enums)">,
+ Desc<"The strategy to use when settings breakpoints by file and line. Breakpoint locations can end up being inlined by the compiler, so that a compile unit 'a.c' might contain an inlined function from another source file. Usually this is limited to breakpoint locations from inlined functions from header or other include files, or more accurately non-implementation source files. Sometimes code might #include implementation files and cause inlined breakpoint locations in inlined implementation files. Always checking for inlined breakpoint locations can be expensive (memory and time), so if you have a project with many headers and find that setting breakpoints is slow, then you can change this setting to headers. This setting allows you to control exactly which strategy is used when setting file and line breakpoints.">;
+ def DisassemblyFlavor: Property<"x86-disassembly-flavor", "Enum">,
+ DefaultEnumValue<"eX86DisFlavorDefault">,
+ EnumValues<"OptionEnumValues(g_x86_dis_flavor_value_types)">,
+ Desc<"The default disassembly flavor to use for x86 or x86-64 targets.">;
+ def UseHexImmediates: Property<"use-hex-immediates", "Boolean">,
+ DefaultTrue,
+ Desc<"Show immediates in disassembly as hexadecimal.">;
+ def HexImmediateStyle: Property<"hex-immediate-style", "Enum">,
+ DefaultEnumValue<"Disassembler::eHexStyleC">,
+ EnumValues<"OptionEnumValues(g_hex_immediate_style_values)">,
+ Desc<"Which style to use for printing hexadecimal disassembly values.">;
+ def UseFastStepping: Property<"use-fast-stepping", "Boolean">,
+ DefaultTrue,
+ Desc<"Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping.">;
+ def LoadScriptFromSymbolFile: Property<"load-script-from-symbol-file", "Enum">,
+ DefaultEnumValue<"eLoadScriptFromSymFileWarn">,
+ EnumValues<"OptionEnumValues(g_load_script_from_sym_file_values)">,
+ Desc<"Allow LLDB to load scripting resources embedded in symbol files when available.">;
+ def LoadCWDlldbinitFile: Property<"load-cwd-lldbinit", "Enum">,
+ DefaultEnumValue<"eLoadCWDlldbinitWarn">,
+ EnumValues<"OptionEnumValues(g_load_cwd_lldbinit_values)">,
+ Desc<"Allow LLDB to .lldbinit files from the current directory automatically.">;
+ def MemoryModuleLoadLevel: Property<"memory-module-load-level", "Enum">,
+ DefaultEnumValue<"eMemoryModuleLoadLevelComplete">,
+ EnumValues<"OptionEnumValues(g_memory_module_load_level_values)">,
+ Desc<"Loading modules from memory can be slow as reading the symbol tables and other data can take a long time depending on your connection to the debug target. This setting helps users control how much information gets loaded when loading modules from memory.'complete' is the default value for this setting which will load all sections and symbols by reading them from memory (slowest, most accurate). 'partial' will load sections and attempt to find function bounds without downloading the symbol table (faster, still accurate, missing symbol names). 'minimal' is the fastest setting and will load section data with no symbols, but should rarely be used as stack frames in these memory regions will be inaccurate and not provide any context (fastest). ">;
+ def DisplayExpressionsInCrashlogs: Property<"display-expression-in-crashlogs", "Boolean">,
+ DefaultFalse,
+ Desc<"Expressions that crash will show up in crash logs if the host system supports executable specific crash log strings and this setting is set to true.">;
+ def TrapHandlerNames: Property<"trap-handler-names", "Array">,
+ Global,
+ DefaultUnsignedValue<16>,
+ Desc<"A list of trap handler function names, e.g. a common Unix user process one is _sigtramp.">;
+ def DisplayRuntimeSupportValues: Property<"display-runtime-support-values", "Boolean">,
+ DefaultFalse,
+ Desc<"If true, LLDB will show variables that are meant to support the operation of a language's runtime support.">;
+ def DisplayRecognizedArguments: Property<"display-recognized-arguments", "Boolean">,
+ DefaultFalse,
+ Desc<"Show recognized arguments in variable listings by default.">;
+ def NonStopModeEnabled: Property<"non-stop-mode", "Boolean">,
+ DefaultFalse,
+ Desc<"Disable lock-step debugging, instead control threads independently.">;
+ def RequireHardwareBreakpoints: Property<"require-hardware-breakpoint", "Boolean">,
+ DefaultFalse,
+ Desc<"Require all breakpoints to be hardware breakpoints.">;
+}
+
+let Definition = "process" in {
+ def DisableMemCache: Property<"disable-memory-cache", "Boolean">,
+ DefaultFalse,
+ Desc<"Disable reading and caching of memory in fixed-size units.">;
+ def ExtraStartCommand: Property<"extra-startup-command", "Array">,
+ DefaultUnsignedValue<16>,
+ Desc<"A list containing extra commands understood by the particular process plugin used. For instance, to turn on debugserver logging set this to 'QSetLogging:bitmask=LOG_DEFAULT;'">;
+ def IgnoreBreakpointsInExpressions: Property<"ignore-breakpoints-in-expressions", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, breakpoints will be ignored during expression evaluation.">;
+ def UnwindOnErrorInExpressions: Property<"unwind-on-error-in-expressions", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, errors in expression evaluation will unwind the stack back to the state before the call.">;
+ def PythonOSPluginPath: Property<"python-os-plugin-path", "FileSpec">,
+ DefaultUnsignedValue<1>,
+ Desc<"A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class.">;
+ def StopOnSharedLibraryEvents: Property<"stop-on-sharedlibrary-events", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, stop when a shared library is loaded or unloaded.">;
+ def DetachKeepsStopped: Property<"detach-keeps-stopped", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, detach will attempt to keep the process stopped.">;
+ def MemCacheLineSize: Property<"memory-cache-line-size", "UInt64">,
+ DefaultUnsignedValue<512>,
+ Desc<"The memory cache line size">;
+ def WarningOptimization: Property<"optimization-warnings", "Boolean">,
+ DefaultTrue,
+ Desc<"If true, warn when stopped in code that is optimized where stepping and variable availability may not behave as expected.">;
+ def StopOnExec: Property<"stop-on-exec", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, stop when a shared library is loaded or unloaded.">;
+ def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">,
+ DefaultUnsignedValue<15>,
+ Desc<"The time in seconds to wait for LLDB-internal utility expressions.">;
+}
+
+let Definition = "platform" in {
+ def UseModuleCache: Property<"use-module-cache", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"Use module cache.">;
+ def ModuleCacheDirectory: Property<"module-cache-directory", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Root directory for cached modules.">;
+}
+
+let Definition = "thread" in {
+ def StepInAvoidsNoDebug: Property<"step-in-avoid-nodebug", "Boolean">,
+ Global,
+ DefaultTrue,
+ Desc<"If true, step-in will not stop in functions with no debug information.">;
+ def StepOutAvoidsNoDebug: Property<"step-out-avoid-nodebug", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, when step-in/step-out/step-over leave the current frame, they will continue to step out till they come to a function with debug information. Passing a frame argument to step-out will override this option.">;
+ def StepAvoidRegex: Property<"step-avoid-regexp", "Regex">,
+ Global,
+ DefaultStringValue<"^std::">,
+ Desc<"A regular expression defining functions step-in won't stop in.">;
+ def StepAvoidLibraries: Property<"step-avoid-libraries", "FileSpecList">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"A list of libraries that source stepping won't stop in.">;
+ def EnableThreadTrace: Property<"trace-thread", "Boolean">,
+ DefaultFalse,
+ Desc<"If true, this thread will single-step and log execution.">;
+ def MaxBacktraceDepth: Property<"max-backtrace-depth", "UInt64">,
+ DefaultUnsignedValue<300000>,
+ Desc<"Maximum number of frames to backtrace.">;
+}
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 7a6b49e55252..e12b90501103 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
@@ -63,31 +64,12 @@ const ThreadPropertiesSP &Thread::GetGlobalProperties() {
return *g_settings_sp_ptr;
}
-static constexpr PropertyDefinition g_properties[] = {
- {"step-in-avoid-nodebug", OptionValue::eTypeBoolean, true, true, nullptr,
- {},
- "If true, step-in will not stop in functions with no debug information."},
- {"step-out-avoid-nodebug", OptionValue::eTypeBoolean, true, false, nullptr,
- {}, "If true, when step-in/step-out/step-over leave the current frame, "
- "they will continue to step out till they come to a function with "
- "debug information. Passing a frame argument to step-out will "
- "override this option."},
- {"step-avoid-regexp", OptionValue::eTypeRegex, true, 0, "^std::", {},
- "A regular expression defining functions step-in won't stop in."},
- {"step-avoid-libraries", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- {}, "A list of libraries that source stepping won't stop in."},
- {"trace-thread", OptionValue::eTypeBoolean, false, false, nullptr, {},
- "If true, this thread will single-step and log execution."},
- {"max-backtrace-depth", OptionValue::eTypeUInt64, false, 300000, nullptr,
- {}, "Maximum number of frames to backtrace."}};
+#define LLDB_PROPERTIES_thread
+#include "TargetProperties.inc"
enum {
- ePropertyStepInAvoidsNoDebug,
- ePropertyStepOutAvoidsNoDebug,
- ePropertyStepAvoidRegex,
- ePropertyStepAvoidLibraries,
- ePropertyEnableThreadTrace,
- ePropertyMaxBacktraceDepth
+#define LLDB_PROPERTIES_thread
+#include "TargetPropertiesEnum.inc"
};
class ThreadOptionValueProperties : public OptionValueProperties {
@@ -125,7 +107,7 @@ ThreadProperties::ThreadProperties(bool is_global) : Properties() {
if (is_global) {
m_collection_sp =
std::make_shared<ThreadOptionValueProperties>(ConstString("thread"));
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_thread_properties);
} else
m_collection_sp = std::make_shared<ThreadOptionValueProperties>(
Thread::GetGlobalProperties().get());
@@ -150,25 +132,25 @@ FileSpecList ThreadProperties::GetLibrariesToAvoid() const {
bool ThreadProperties::GetTraceEnabledState() const {
const uint32_t idx = ePropertyEnableThreadTrace;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_thread_properties[idx].default_uint_value != 0);
}
bool ThreadProperties::GetStepInAvoidsNoDebug() const {
const uint32_t idx = ePropertyStepInAvoidsNoDebug;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_thread_properties[idx].default_uint_value != 0);
}
bool ThreadProperties::GetStepOutAvoidsNoDebug() const {
const uint32_t idx = ePropertyStepOutAvoidsNoDebug;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_thread_properties[idx].default_uint_value != 0);
}
uint64_t ThreadProperties::GetMaxBacktraceDepth() const {
const uint32_t idx = ePropertyMaxBacktraceDepth;
return m_collection_sp->GetPropertyAtIndexAsUInt64(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_thread_properties[idx].default_uint_value != 0);
}
// Thread Event Data
@@ -256,9 +238,8 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id)
m_override_should_notify(eLazyBoolCalculate),
m_extended_info_fetched(false), m_extended_info() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")",
- static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "%p Thread::Thread(tid = 0x%4.4" PRIx64 ")",
+ static_cast<void *>(this), GetID());
CheckInWithManager();
@@ -267,9 +248,8 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id)
Thread::~Thread() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")",
- static_cast<void *>(this), GetID());
+ LLDB_LOGF(log, "%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")",
+ static_cast<void *>(this), GetID());
/// If you hit this assert, it means your derived class forgot to call
/// DoDestroy in its destructor.
assert(m_destroy_called);
@@ -411,6 +391,11 @@ lldb::StopInfoSP Thread::GetStopInfo() {
}
}
+void Thread::CalculatePublicStopInfo() {
+ ResetStopInfo();
+ SetStopInfo(GetStopInfo());
+}
+
lldb::StopInfoSP Thread::GetPrivateStopInfo() {
if (m_destroy_called)
return m_stop_info_sp;
@@ -490,11 +475,10 @@ void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) {
else
m_stop_info_stop_id = UINT32_MAX;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)",
- static_cast<void *>(this), GetID(),
- stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>",
- m_stop_info_stop_id);
+ LLDB_LOGF(log, "%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)",
+ static_cast<void *>(this), GetID(),
+ stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>",
+ m_stop_info_stop_id);
}
void Thread::SetShouldReportStop(Vote vote) {
@@ -721,18 +705,18 @@ bool Thread::ShouldStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (GetResumeState() == eStateSuspended) {
- if (log)
- log->Printf("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
- ", should_stop = 0 (ignore since thread was suspended)",
- __FUNCTION__, GetID(), GetProtocolID());
+ LLDB_LOGF(log,
+ "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
+ ", should_stop = 0 (ignore since thread was suspended)",
+ __FUNCTION__, GetID(), GetProtocolID());
return false;
}
if (GetTemporaryResumeState() == eStateSuspended) {
- if (log)
- log->Printf("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
- ", should_stop = 0 (ignore since thread was suspended)",
- __FUNCTION__, GetID(), GetProtocolID());
+ LLDB_LOGF(log,
+ "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
+ ", should_stop = 0 (ignore since thread was suspended)",
+ __FUNCTION__, GetID(), GetProtocolID());
return false;
}
@@ -740,28 +724,28 @@ bool Thread::ShouldStop(Event *event_ptr) {
// thread caused the process to stop. NOTE: this must take place before the
// plan is moved from the current plan stack to the completed plan stack.
if (!ThreadStoppedForAReason()) {
- if (log)
- log->Printf("Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
- ", pc = 0x%16.16" PRIx64
- ", should_stop = 0 (ignore since no stop reason)",
- __FUNCTION__, GetID(), GetProtocolID(),
- GetRegisterContext() ? GetRegisterContext()->GetPC()
- : LLDB_INVALID_ADDRESS);
+ LLDB_LOGF(log,
+ "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
+ ", pc = 0x%16.16" PRIx64
+ ", should_stop = 0 (ignore since no stop reason)",
+ __FUNCTION__, GetID(), GetProtocolID(),
+ GetRegisterContext() ? GetRegisterContext()->GetPC()
+ : LLDB_INVALID_ADDRESS);
return false;
}
if (log) {
- log->Printf("Thread::%s(%p) for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
- ", pc = 0x%16.16" PRIx64,
- __FUNCTION__, static_cast<void *>(this), GetID(),
- GetProtocolID(),
- GetRegisterContext() ? GetRegisterContext()->GetPC()
- : LLDB_INVALID_ADDRESS);
- log->Printf("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
+ LLDB_LOGF(log,
+ "Thread::%s(%p) for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
+ ", pc = 0x%16.16" PRIx64,
+ __FUNCTION__, static_cast<void *>(this), GetID(), GetProtocolID(),
+ GetRegisterContext() ? GetRegisterContext()->GetPC()
+ : LLDB_INVALID_ADDRESS);
+ LLDB_LOGF(log, "^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
StreamString s;
s.IndentMore();
DumpThreadPlans(&s);
- log->Printf("Plan stack initial state:\n%s", s.GetData());
+ LLDB_LOGF(log, "Plan stack initial state:\n%s", s.GetData());
}
// The top most plan always gets to do the trace log...
@@ -774,9 +758,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
StopInfoSP private_stop_info(GetPrivateStopInfo());
if (private_stop_info &&
!private_stop_info->ShouldStopSynchronous(event_ptr)) {
- if (log)
- log->Printf("StopInfo::ShouldStop async callback says we should not "
- "stop, returning ShouldStop of false.");
+ LLDB_LOGF(log, "StopInfo::ShouldStop async callback says we should not "
+ "stop, returning ShouldStop of false.");
return false;
}
@@ -840,15 +823,13 @@ bool Thread::ShouldStop(Event *event_ptr) {
if (!done_processing_current_plan) {
bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
- if (log)
- log->Printf("Plan %s explains stop, auto-continue %i.",
- current_plan->GetName(), over_ride_stop);
+ LLDB_LOGF(log, "Plan %s explains stop, auto-continue %i.",
+ current_plan->GetName(), over_ride_stop);
// We're starting from the base plan, so just let it decide;
if (PlanIsBasePlan(current_plan)) {
should_stop = current_plan->ShouldStop(event_ptr);
- if (log)
- log->Printf("Base plan says should stop: %i.", should_stop);
+ LLDB_LOGF(log, "Base plan says should stop: %i.", should_stop);
} else {
// Otherwise, don't let the base plan override what the other plans say
// to do, since presumably if there were other plans they would know what
@@ -858,9 +839,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
break;
should_stop = current_plan->ShouldStop(event_ptr);
- if (log)
- log->Printf("Plan %s should stop: %d.", current_plan->GetName(),
- should_stop);
+ LLDB_LOGF(log, "Plan %s should stop: %d.", current_plan->GetName(),
+ should_stop);
if (current_plan->MischiefManaged()) {
if (should_stop)
current_plan->WillStop();
@@ -907,10 +887,10 @@ bool Thread::ShouldStop(Event *event_ptr) {
plan_ptr = GetPreviousPlan(examined_plan);
if (stale) {
- if (log)
- log->Printf(
- "Plan %s being discarded in cleanup, it says it is already done.",
- examined_plan->GetName());
+ LLDB_LOGF(
+ log,
+ "Plan %s being discarded in cleanup, it says it is already done.",
+ examined_plan->GetName());
while (GetCurrentPlan() != examined_plan) {
DiscardPlan();
}
@@ -929,9 +909,9 @@ bool Thread::ShouldStop(Event *event_ptr) {
StreamString s;
s.IndentMore();
DumpThreadPlans(&s);
- log->Printf("Plan stack final state:\n%s", s.GetData());
- log->Printf("vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv",
- should_stop);
+ LLDB_LOGF(log, "Plan stack final state:\n%s", s.GetData());
+ LLDB_LOGF(log, "vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv",
+ should_stop);
}
return should_stop;
}
@@ -943,37 +923,36 @@ Vote Thread::ShouldReportStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (thread_state == eStateSuspended || thread_state == eStateInvalid) {
- if (log)
- log->Printf("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
- ": returning vote %i (state was suspended or invalid)",
- GetID(), eVoteNoOpinion);
+ LLDB_LOGF(log,
+ "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
+ ": returning vote %i (state was suspended or invalid)",
+ GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
if (temp_thread_state == eStateSuspended ||
temp_thread_state == eStateInvalid) {
- if (log)
- log->Printf(
- "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
- ": returning vote %i (temporary state was suspended or invalid)",
- GetID(), eVoteNoOpinion);
+ LLDB_LOGF(log,
+ "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
+ ": returning vote %i (temporary state was suspended or invalid)",
+ GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
if (!ThreadStoppedForAReason()) {
- if (log)
- log->Printf("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
- ": returning vote %i (thread didn't stop for a reason.)",
- GetID(), eVoteNoOpinion);
+ LLDB_LOGF(log,
+ "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
+ ": returning vote %i (thread didn't stop for a reason.)",
+ GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
if (m_completed_plan_stack.size() > 0) {
// Don't use GetCompletedPlan here, since that suppresses private plans.
- if (log)
- log->Printf("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
- ": returning vote for complete stack's back plan",
- GetID());
+ LLDB_LOGF(log,
+ "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
+ ": returning vote for complete stack's back plan",
+ GetID());
return m_completed_plan_stack.back()->ShouldReportStop(event_ptr);
} else {
Vote thread_vote = eVoteNoOpinion;
@@ -988,10 +967,10 @@ Vote Thread::ShouldReportStop(Event *event_ptr) {
else
plan_ptr = GetPreviousPlan(plan_ptr);
}
- if (log)
- log->Printf("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
- ": returning vote %i for current plan",
- GetID(), thread_vote);
+ LLDB_LOGF(log,
+ "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
+ ": returning vote %i for current plan",
+ GetID(), thread_vote);
return thread_vote;
}
@@ -1007,21 +986,21 @@ Vote Thread::ShouldReportRun(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (m_completed_plan_stack.size() > 0) {
// Don't use GetCompletedPlan here, since that suppresses private plans.
- if (log)
- log->Printf("Current Plan for thread %d(%p) (0x%4.4" PRIx64
- ", %s): %s being asked whether we should report run.",
- GetIndexID(), static_cast<void *>(this), GetID(),
- StateAsCString(GetTemporaryResumeState()),
- m_completed_plan_stack.back()->GetName());
+ LLDB_LOGF(log,
+ "Current Plan for thread %d(%p) (0x%4.4" PRIx64
+ ", %s): %s being asked whether we should report run.",
+ GetIndexID(), static_cast<void *>(this), GetID(),
+ StateAsCString(GetTemporaryResumeState()),
+ m_completed_plan_stack.back()->GetName());
return m_completed_plan_stack.back()->ShouldReportRun(event_ptr);
} else {
- if (log)
- log->Printf("Current Plan for thread %d(%p) (0x%4.4" PRIx64
- ", %s): %s being asked whether we should report run.",
- GetIndexID(), static_cast<void *>(this), GetID(),
- StateAsCString(GetTemporaryResumeState()),
- GetCurrentPlan()->GetName());
+ LLDB_LOGF(log,
+ "Current Plan for thread %d(%p) (0x%4.4" PRIx64
+ ", %s): %s being asked whether we should report run.",
+ GetIndexID(), static_cast<void *>(this), GetID(),
+ StateAsCString(GetTemporaryResumeState()),
+ GetCurrentPlan()->GetName());
return GetCurrentPlan()->ShouldReportRun(event_ptr);
}
@@ -1048,9 +1027,9 @@ void Thread::PushPlan(ThreadPlanSP &thread_plan_sp) {
if (log) {
StreamString s;
thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
- log->Printf("Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".",
- static_cast<void *>(this), s.GetData(),
- thread_plan_sp->GetThread().GetID());
+ LLDB_LOGF(log, "Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".",
+ static_cast<void *>(this), s.GetData(),
+ thread_plan_sp->GetThread().GetID());
}
}
}
@@ -1063,8 +1042,8 @@ void Thread::PopPlan() {
else {
ThreadPlanSP &plan = m_plan_stack.back();
if (log) {
- log->Printf("Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
- plan->GetName(), plan->GetThread().GetID());
+ LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
+ plan->GetName(), plan->GetThread().GetID());
}
m_completed_plan_stack.push_back(plan);
plan->WillPop();
@@ -1076,9 +1055,8 @@ void Thread::DiscardPlan() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (m_plan_stack.size() > 1) {
ThreadPlanSP &plan = m_plan_stack.back();
- if (log)
- log->Printf("Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
- plan->GetName(), plan->GetThread().GetID());
+ LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
+ plan->GetName(), plan->GetThread().GetID());
m_discarded_plan_stack.push_back(plan);
plan->WillPop();
@@ -1252,10 +1230,10 @@ void Thread::DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp) {
void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Discarding thread plans for thread tid = 0x%4.4" PRIx64
- ", up to %p",
- GetID(), static_cast<void *>(up_to_plan_ptr));
+ LLDB_LOGF(log,
+ "Discarding thread plans for thread tid = 0x%4.4" PRIx64
+ ", up to %p",
+ GetID(), static_cast<void *>(up_to_plan_ptr));
int stack_size = m_plan_stack.size();
@@ -1285,9 +1263,10 @@ void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
void Thread::DiscardThreadPlans(bool force) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log) {
- log->Printf("Discarding thread plans for thread (tid = 0x%4.4" PRIx64
- ", force %d)",
- GetID(), force);
+ LLDB_LOGF(log,
+ "Discarding thread plans for thread (tid = 0x%4.4" PRIx64
+ ", force %d)",
+ GetID(), force);
}
if (force) {
@@ -1504,9 +1483,18 @@ ThreadPlanSP Thread::QueueThreadPlanForStepUntil(
}
lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
- bool abort_other_plans, const char *class_name, bool stop_other_threads,
+ bool abort_other_plans, const char *class_name,
+ StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
Status &status) {
- ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name));
+
+ StructuredDataImpl *extra_args_impl = nullptr;
+ if (extra_args_sp) {
+ extra_args_impl = new StructuredDataImpl();
+ extra_args_impl->SetObjectSP(extra_args_sp);
+ }
+
+ ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name,
+ extra_args_impl));
status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
return thread_plan_sp;
@@ -2062,6 +2050,7 @@ Unwind *Thread::GetUnwinder() {
case llvm::Triple::x86:
case llvm::Triple::arm:
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::thumb:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
@@ -2072,6 +2061,7 @@ Unwind *Thread::GetUnwinder() {
case llvm::Triple::ppc64le:
case llvm::Triple::systemz:
case llvm::Triple::hexagon:
+ case llvm::Triple::arc:
m_unwinder_up.reset(new UnwindLLDB(*this));
break;
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index afdfda3b0ae1..183b39c2cfa9 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -267,10 +267,11 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
if (log) {
log->PutCString("");
- log->Printf("ThreadList::%s: %" PRIu64 " threads, %" PRIu64
- " unsuspended threads",
- __FUNCTION__, (uint64_t)m_threads.size(),
- (uint64_t)threads_copy.size());
+ LLDB_LOGF(log,
+ "ThreadList::%s: %" PRIu64 " threads, %" PRIu64
+ " unsuspended threads",
+ __FUNCTION__, (uint64_t)m_threads.size(),
+ (uint64_t)threads_copy.size());
}
bool did_anybody_stop_for_a_reason = false;
@@ -279,10 +280,9 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
// what. Otherwise, presume we won't stop.
bool should_stop = false;
if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
- if (log)
- log->Printf(
- "ThreadList::%s handling interrupt event, should stop set to true",
- __FUNCTION__);
+ LLDB_LOGF(
+ log, "ThreadList::%s handling interrupt event, should stop set to true",
+ __FUNCTION__);
should_stop = true;
}
@@ -334,15 +334,14 @@ bool ThreadList::ShouldStop(Event *event_ptr) {
if (!should_stop && !did_anybody_stop_for_a_reason) {
should_stop = true;
- if (log)
- log->Printf("ThreadList::%s we stopped but no threads had a stop reason, "
- "overriding should_stop and stopping.",
- __FUNCTION__);
+ LLDB_LOGF(log,
+ "ThreadList::%s we stopped but no threads had a stop reason, "
+ "overriding should_stop and stopping.",
+ __FUNCTION__);
}
- if (log)
- log->Printf("ThreadList::%s overall should_stop = %i", __FUNCTION__,
- should_stop);
+ LLDB_LOGF(log, "ThreadList::%s overall should_stop = %i", __FUNCTION__,
+ should_stop);
if (should_stop) {
for (pos = threads_copy.begin(); pos != end; ++pos) {
@@ -363,9 +362,8 @@ Vote ThreadList::ShouldReportStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
- (uint64_t)m_threads.size());
+ LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
+ (uint64_t)m_threads.size());
// Run through the threads and ask whether we should report this event. For
// stopping, a YES vote wins over everything. A NO vote wins over NO
@@ -430,10 +428,10 @@ Vote ThreadList::ShouldReportRun(Event *event_ptr) {
result = eVoteYes;
break;
case eVoteNo:
- if (log)
- log->Printf("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
- ") says don't report.",
- (*pos)->GetIndexID(), (*pos)->GetID());
+ LLDB_LOGF(log,
+ "ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
+ ") says don't report.",
+ (*pos)->GetIndexID(), (*pos)->GetID());
result = eVoteNo;
break;
}
@@ -464,8 +462,9 @@ void ThreadList::RefreshStateAfterStop() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("Turning off notification of new threads while single stepping "
- "a thread.");
+ LLDB_LOGF(log,
+ "Turning off notification of new threads while single stepping "
+ "a thread.");
collection::iterator pos, end = m_threads.end();
for (pos = m_threads.begin(); pos != end; ++pos)
@@ -517,14 +516,14 @@ bool ThreadList::WillResume() {
if (wants_solo_run) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("Turning on notification of new threads while single "
- "stepping a thread.");
+ LLDB_LOGF(log, "Turning on notification of new threads while single "
+ "stepping a thread.");
m_process->StartNoticingNewThreads();
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf("Turning off notification of new threads while single "
- "stepping a thread.");
+ LLDB_LOGF(log, "Turning off notification of new threads while single "
+ "stepping a thread.");
m_process->StopNoticingNewThreads();
}
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
index 1d8cc18db4d6..ba56f8d15d8a 100644
--- a/source/Target/ThreadPlan.cpp
+++ b/source/Target/ThreadPlan.cpp
@@ -108,7 +108,8 @@ bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {
addr_t pc = reg_ctx->GetPC();
addr_t sp = reg_ctx->GetSP();
addr_t fp = reg_ctx->GetFP();
- log->Printf(
+ LLDB_LOGF(
+ log,
"%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64
", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
"plan = '%s', state = %s, stop others = %d",
diff --git a/source/Target/ThreadPlanBase.cpp b/source/Target/ThreadPlanBase.cpp
index 9cd4bcb455be..821643d4bce5 100644
--- a/source/Target/ThreadPlanBase.cpp
+++ b/source/Target/ThreadPlanBase.cpp
@@ -92,11 +92,11 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
// If we are going to stop for a breakpoint, then unship the other
// plans at this point. Don't force the discard, however, so Master
// plans can stay in place if they want to.
- if (log)
- log->Printf(
- "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
- " (breakpoint hit.)",
- m_thread.GetID());
+ LLDB_LOGF(
+ log,
+ "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
+ " (breakpoint hit.)",
+ m_thread.GetID());
m_thread.DiscardThreadPlans(false);
return true;
}
@@ -122,11 +122,11 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
// If we crashed, discard thread plans and stop. Don't force the
// discard, however, since on rerun the target may clean up this
// exception and continue normally from there.
- if (log)
- log->Printf(
- "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
- " (exception: %s)",
- m_thread.GetID(), stop_info_sp->GetDescription());
+ LLDB_LOGF(
+ log,
+ "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
+ " (exception: %s)",
+ m_thread.GetID(), stop_info_sp->GetDescription());
m_thread.DiscardThreadPlans(false);
return true;
@@ -134,22 +134,22 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
// If we crashed, discard thread plans and stop. Don't force the
// discard, however, since on rerun the target may clean up this
// exception and continue normally from there.
- if (log)
- log->Printf(
- "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
- " (exec.)",
- m_thread.GetID());
+ LLDB_LOGF(
+ log,
+ "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
+ " (exec.)",
+ m_thread.GetID());
m_thread.DiscardThreadPlans(false);
return true;
case eStopReasonThreadExiting:
case eStopReasonSignal:
if (stop_info_sp->ShouldStop(event_ptr)) {
- if (log)
- log->Printf(
- "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
- " (signal: %s)",
- m_thread.GetID(), stop_info_sp->GetDescription());
+ LLDB_LOGF(
+ log,
+ "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
+ " (signal: %s)",
+ m_thread.GetID(), stop_info_sp->GetDescription());
m_thread.DiscardThreadPlans(false);
return true;
} else {
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index 68d771c37946..23d114e30990 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -59,46 +59,21 @@ bool ThreadPlanCallFunction::ConstructorSetup(
m_constructor_errors.Printf(
"Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".",
m_function_sp);
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
- m_constructor_errors.GetData());
+ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
+ m_constructor_errors.GetData());
return false;
}
- Module *exe_module = GetTarget().GetExecutableModulePointer();
-
- if (exe_module == nullptr) {
+ llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress();
+ if (!start_address) {
m_constructor_errors.Printf(
- "Can't execute code without an executable module.");
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
- m_constructor_errors.GetData());
+ "%s", llvm::toString(start_address.takeError()).c_str());
+ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
+ m_constructor_errors.GetData());
return false;
- } else {
- ObjectFile *objectFile = exe_module->GetObjectFile();
- if (!objectFile) {
- m_constructor_errors.Printf(
- "Could not find object file for module \"%s\".",
- exe_module->GetFileSpec().GetFilename().AsCString());
-
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): %s.",
- static_cast<void *>(this), m_constructor_errors.GetData());
- return false;
- }
-
- m_start_addr = objectFile->GetEntryPointAddress();
- if (!m_start_addr.IsValid()) {
- m_constructor_errors.Printf(
- "Could not find entry point address for executable module \"%s\".",
- exe_module->GetFileSpec().GetFilename().AsCString());
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): %s.",
- static_cast<void *>(this), m_constructor_errors.GetData());
- return false;
- }
}
+ m_start_addr = *start_address;
start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
// Checkpoint the thread state so we can restore it later.
@@ -109,9 +84,8 @@ bool ThreadPlanCallFunction::ConstructorSetup(
if (!thread.CheckpointThreadState(m_stored_thread_state)) {
m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
"checkpoint thread state.");
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
- m_constructor_errors.GetData());
+ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
+ m_constructor_errors.GetData());
return false;
}
function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
@@ -196,10 +170,10 @@ void ThreadPlanCallFunction::DoTakedown(bool success) {
if (!m_valid) {
// Don't call DoTakedown if we were never valid to begin with.
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): Log called on "
- "ThreadPlanCallFunction that was never valid.",
- static_cast<void *>(this));
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction(%p): Log called on "
+ "ThreadPlanCallFunction that was never valid.",
+ static_cast<void *>(this));
return;
}
@@ -207,20 +181,20 @@ void ThreadPlanCallFunction::DoTakedown(bool success) {
if (success) {
SetReturnValue();
}
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): DoTakedown called for thread "
- "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
- static_cast<void *>(this), m_thread.GetID(), m_valid,
- IsPlanComplete());
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction(%p): DoTakedown called for thread "
+ "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
+ static_cast<void *>(this), m_thread.GetID(), m_valid,
+ IsPlanComplete());
m_takedown_done = true;
m_stop_address =
m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
m_real_stop_info_sp = GetPrivateStopInfo();
if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore "
- "register state",
- static_cast<void *>(this));
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
+ "register state",
+ static_cast<void *>(this));
}
SetPlanComplete(success);
ClearBreakpoints();
@@ -228,11 +202,11 @@ void ThreadPlanCallFunction::DoTakedown(bool success) {
ReportRegisterState("Restoring thread state after function call. "
"Restored register state:");
} else {
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
- "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
- static_cast<void *>(this), m_thread.GetID(), m_valid,
- IsPlanComplete());
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
+ "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
+ static_cast<void *>(this), m_thread.GetID(), m_valid,
+ IsPlanComplete());
}
}
@@ -288,10 +262,9 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
stop_reason = eStopReasonNone;
else
stop_reason = m_real_stop_info_sp->GetStopReason();
- if (log)
- log->Printf(
- "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
- Thread::StopReasonAsCString(stop_reason));
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
+ Thread::StopReasonAsCString(stop_reason));
if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
return true;
@@ -300,9 +273,8 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
// then we should not consider ourselves complete. Return true to
// acknowledge the stop.
if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
- if (log)
- log->Printf("ThreadPlanCallFunction::PlanExplainsStop: The event is an "
- "Interrupt, returning true.");
+ LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
+ "Interrupt, returning true.");
return true;
}
// We control breakpoints separately from other "stop reasons." So first,
@@ -321,10 +293,10 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
bool is_internal = true;
for (uint32_t i = 0; i < num_owners; i++) {
Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
- if (log)
- log->Printf("ThreadPlanCallFunction::PlanExplainsStop: hit "
- "breakpoint %d while calling function",
- bp.GetID());
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction::PlanExplainsStop: hit "
+ "breakpoint %d while calling function",
+ bp.GetID());
if (!bp.IsInternal()) {
is_internal = false;
@@ -332,25 +304,23 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
}
}
if (is_internal) {
- if (log)
- log->Printf("ThreadPlanCallFunction::PlanExplainsStop hit an "
- "internal breakpoint, not stopping.");
+ LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an "
+ "internal breakpoint, not stopping.");
return false;
}
}
if (m_ignore_breakpoints) {
- if (log)
- log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
- "breakpoints, overriding breakpoint stop info ShouldStop, "
- "returning true");
+ LLDB_LOGF(log,
+ "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
+ "breakpoints, overriding breakpoint stop info ShouldStop, "
+ "returning true");
m_real_stop_info_sp->OverrideShouldStop(false);
return true;
} else {
- if (log)
- log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not "
- "ignoring breakpoints, overriding breakpoint stop info "
- "ShouldStop, returning true");
+ LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
+ "ignoring breakpoints, overriding breakpoint stop info "
+ "ShouldStop, returning true");
m_real_stop_info_sp->OverrideShouldStop(true);
return false;
}
@@ -418,9 +388,8 @@ bool ThreadPlanCallFunction::MischiefManaged() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (IsPlanComplete()) {
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
+ static_cast<void *>(this));
ThreadPlan::MischiefManaged();
return true;
@@ -469,9 +438,8 @@ bool ThreadPlanCallFunction::BreakpointsExplainStop() {
m_objc_language_runtime->ExceptionBreakpointsExplainStop(
stop_info_sp))) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
- "exception breakpoint, setting plan complete.");
+ LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
+ "exception breakpoint, setting plan complete.");
SetPlanComplete(false);
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index 864808a4b5ea..436938c8f207 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -69,9 +69,8 @@ bool ThreadPlanCallUserExpression::MischiefManaged() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (IsPlanComplete()) {
- if (log)
- log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.",
- static_cast<void *>(this));
+ LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
+ static_cast<void *>(this));
if (m_manage_materialization && PlanSucceeded() && m_user_expression_sp) {
lldb::addr_t function_stack_top;
diff --git a/source/Target/ThreadPlanPython.cpp b/source/Target/ThreadPlanPython.cpp
index 8b30c4ea7cb1..df432a0af3da 100644
--- a/source/Target/ThreadPlanPython.cpp
+++ b/source/Target/ThreadPlanPython.cpp
@@ -25,10 +25,11 @@ using namespace lldb_private;
// ThreadPlanPython
-ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name)
+ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
+ StructuredDataImpl *args_data)
: ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
eVoteNoOpinion, eVoteNoOpinion),
- m_class_name(class_name), m_did_push(false) {
+ m_class_name(class_name), m_args_data(args_data), m_did_push(false) {
SetIsMasterPlan(true);
SetOkayToDiscard(true);
SetPrivate(false);
@@ -45,7 +46,9 @@ bool ThreadPlanPython::ValidatePlan(Stream *error) {
if (!m_implementation_sp) {
if (error)
- error->Printf("Python thread plan does not have an implementation");
+ error->Printf("Error constructing Python ThreadPlan: %s",
+ m_error_str.empty() ? "<unknown error>"
+ : m_error_str.c_str());
return false;
}
@@ -63,16 +66,16 @@ void ThreadPlanPython::DidPush() {
.GetScriptInterpreter();
if (script_interp) {
m_implementation_sp = script_interp->CreateScriptedThreadPlan(
- m_class_name.c_str(), this->shared_from_this());
+ m_class_name.c_str(), m_args_data, m_error_str,
+ this->shared_from_this());
}
}
}
bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
bool should_stop = true;
if (m_implementation_sp) {
@@ -93,9 +96,8 @@ bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
bool ThreadPlanPython::IsPlanStale() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
bool is_stale = true;
if (m_implementation_sp) {
@@ -116,9 +118,8 @@ bool ThreadPlanPython::IsPlanStale() {
bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
bool explains_stop = true;
if (m_implementation_sp) {
@@ -139,9 +140,8 @@ bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
bool ThreadPlanPython::MischiefManaged() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
bool mischief_managed = true;
if (m_implementation_sp) {
// I don't really need mischief_managed, since it's simpler to just call
@@ -155,9 +155,8 @@ bool ThreadPlanPython::MischiefManaged() {
lldb::StateType ThreadPlanPython::GetPlanRunState() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
lldb::StateType run_state = eStateRunning;
if (m_implementation_sp) {
ScriptInterpreter *script_interp = m_thread.GetProcess()
@@ -188,8 +187,7 @@ void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
bool ThreadPlanPython::WillStop() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
- m_class_name.c_str());
+ LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
+ m_class_name.c_str());
return true;
}
diff --git a/source/Target/ThreadPlanRunToAddress.cpp b/source/Target/ThreadPlanRunToAddress.cpp
index a973bd112796..160743a9f3f8 100644
--- a/source/Target/ThreadPlanRunToAddress.cpp
+++ b/source/Target/ThreadPlanRunToAddress.cpp
@@ -182,8 +182,7 @@ bool ThreadPlanRunToAddress::MischiefManaged() {
m_break_ids[i] = LLDB_INVALID_BREAK_ID;
}
}
- if (log)
- log->Printf("Completed run to address plan.");
+ LLDB_LOGF(log, "Completed run to address plan.");
ThreadPlan::MischiefManaged();
return true;
} else
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp
index a0b7072a1071..9599d8197b07 100644
--- a/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/source/Target/ThreadPlanShouldStopHere.cpp
@@ -46,8 +46,8 @@ bool ThreadPlanShouldStopHere::InvokeShouldStopHereCallback(
lldb::addr_t current_addr =
m_owner->GetThread().GetRegisterContext()->GetPC(0);
- log->Printf("ShouldStopHere callback returned %u from 0x%" PRIx64 ".",
- should_stop_here, current_addr);
+ LLDB_LOGF(log, "ShouldStopHere callback returned %u from 0x%" PRIx64 ".",
+ should_stop_here, current_addr);
}
}
@@ -69,8 +69,7 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
(operation == eFrameCompareSameParent &&
flags.Test(eStepInAvoidNoDebug))) {
if (!frame->HasDebugInformation()) {
- if (log)
- log->Printf("Stepping out of frame with no debug info");
+ LLDB_LOGF(log, "Stepping out of frame with no debug info");
should_stop_here = false;
}
@@ -118,16 +117,14 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
symbol_end.Slide(sc.symbol->GetByteSize() - 1);
if (range.ContainsFileAddress(sc.symbol->GetAddress()) &&
range.ContainsFileAddress(symbol_end)) {
- if (log)
- log->Printf("Stopped in a function with only line 0 lines, just "
- "stepping out.");
+ LLDB_LOGF(log, "Stopped in a function with only line 0 lines, just "
+ "stepping out.");
just_step_out = true;
}
}
if (!just_step_out) {
- if (log)
- log->Printf("ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
- "Queueing StepInRange plan to step through line 0 code.");
+ LLDB_LOGF(log, "ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
+ "Queueing StepInRange plan to step through line 0 code.");
return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(
false, range, sc, nullptr, eOnlyDuringStepping, status,
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index 2065fa55fa6a..71045cc7a990 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -148,7 +148,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
s.Address(
m_thread.GetRegisterContext()->GetPC(),
m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
- log->Printf("ThreadPlanStepInRange reached %s.", s.GetData());
+ LLDB_LOGF(log, "ThreadPlanStepInRange reached %s.", s.GetData());
}
if (IsPlanComplete())
@@ -197,13 +197,14 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
CheckShouldStopHereAndQueueStepOut(frame_order, m_status);
if (log) {
if (m_sub_plan_sp)
- log->Printf("ShouldStopHere found plan to step out of this frame.");
+ LLDB_LOGF(log,
+ "ShouldStopHere found plan to step out of this frame.");
else
- log->Printf("ShouldStopHere no plan to step out of this frame.");
+ LLDB_LOGF(log, "ShouldStopHere no plan to step out of this frame.");
}
} else if (log) {
- log->Printf(
- "Thought I stepped out, but in fact arrived at a trampoline.");
+ LLDB_LOGF(
+ log, "Thought I stepped out, but in fact arrived at a trampoline.");
}
} else if (frame_order == eFrameCompareEqual && InSymbol()) {
// If we are not in a place we should step through, we're done. One
@@ -237,9 +238,10 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
if (log) {
if (m_sub_plan_sp)
- log->Printf("Found a step through plan: %s", m_sub_plan_sp->GetName());
+ LLDB_LOGF(log, "Found a step through plan: %s",
+ m_sub_plan_sp->GetName());
else
- log->Printf("No step through plan found.");
+ LLDB_LOGF(log, "No step through plan found.");
}
// If not, give the "should_stop" callback a chance to push a plan to get
@@ -289,8 +291,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
if (bytes_to_skip != 0) {
func_start_address.Slide(bytes_to_skip);
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP);
- if (log)
- log->Printf("Pushing past prologue ");
+ LLDB_LOGF(log, "Pushing past prologue ");
m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(
false, func_start_address, true, m_status);
@@ -312,10 +313,10 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) {
void ThreadPlanStepInRange::SetAvoidRegexp(const char *name) {
auto name_ref = llvm::StringRef::withNullAsEmpty(name);
- if (!m_avoid_regexp_up)
+ if (m_avoid_regexp_up)
+ *m_avoid_regexp_up = RegularExpression(name_ref);
+ else
m_avoid_regexp_up.reset(new RegularExpression(name_ref));
-
- m_avoid_regexp_up->Compile(name_ref);
}
void ThreadPlanStepInRange::SetDefaultFlagValue(uint32_t new_value) {
@@ -360,25 +361,17 @@ bool ThreadPlanStepInRange::FrameMatchesAvoidCriteria() {
sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments)
.GetCString();
if (frame_function_name) {
- size_t num_matches = 0;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- num_matches = 1;
-
- RegularExpression::Match regex_match(num_matches);
-
+ llvm::SmallVector<llvm::StringRef, 2> matches;
bool return_value =
- avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
- if (return_value) {
- if (log) {
- std::string match;
- regex_match.GetMatchAtIndex(frame_function_name, 0, match);
- log->Printf("Stepping out of function \"%s\" because it matches "
- "the avoid regexp \"%s\" - match substring: \"%s\".",
- frame_function_name,
- avoid_regexp_to_use->GetText().str().c_str(),
- match.c_str());
- }
+ avoid_regexp_to_use->Execute(frame_function_name, &matches);
+ if (return_value && matches.size() > 1) {
+ std::string match = matches[1].str();
+ LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP),
+ "Stepping out of function \"%s\" because it matches "
+ "the avoid regexp \"%s\" - match substring: \"%s\".",
+ frame_function_name,
+ avoid_regexp_to_use->GetText().str().c_str(),
+ match.c_str());
}
return return_value;
}
@@ -424,10 +417,11 @@ bool ThreadPlanStepInRange::DefaultShouldStopHereCallback(
should_stop_here = false;
}
if (log && !should_stop_here)
- log->Printf("Stepping out of frame %s which did not match step into "
- "target %s.",
- sc.GetFunctionName().AsCString(),
- step_in_range_plan->m_step_into_target.AsCString());
+ LLDB_LOGF(log,
+ "Stepping out of frame %s which did not match step into "
+ "target %s.",
+ sc.GetFunctionName().AsCString(),
+ step_in_range_plan->m_step_into_target.AsCString());
}
}
@@ -496,10 +490,10 @@ bool ThreadPlanStepInRange::DoWillResume(lldb::StateType resume_state,
bool step_without_resume = m_thread.DecrementCurrentInlinedDepth();
if (step_without_resume) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("ThreadPlanStepInRange::DoWillResume: returning false, "
- "inline_depth: %d",
- m_thread.GetCurrentInlinedDepth());
+ LLDB_LOGF(log,
+ "ThreadPlanStepInRange::DoWillResume: returning false, "
+ "inline_depth: %d",
+ m_thread.GetCurrentInlinedDepth());
SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread));
// FIXME: Maybe it would be better to create a InlineStep stop reason, but
diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp
index a11b623c8acf..0c75cb811156 100644
--- a/source/Target/ThreadPlanStepInstruction.cpp
+++ b/source/Target/ThreadPlanStepInstruction.cpp
@@ -114,8 +114,9 @@ bool ThreadPlanStepInstruction::IsPlanStale() {
return !m_step_over;
} else {
if (log) {
- log->Printf("ThreadPlanStepInstruction::IsPlanStale - Current frame is "
- "older than start frame, plan is stale.");
+ LLDB_LOGF(log,
+ "ThreadPlanStepInstruction::IsPlanStale - Current frame is "
+ "older than start frame, plan is stale.");
}
return true;
}
@@ -127,9 +128,9 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0);
if (!cur_frame_sp) {
- if (log)
- log->Printf(
- "ThreadPlanStepInstruction couldn't get the 0th frame, stopping.");
+ LLDB_LOGF(
+ log,
+ "ThreadPlanStepInstruction couldn't get the 0th frame, stopping.");
SetPlanComplete();
return true;
}
@@ -168,8 +169,9 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
cur_frame_sp->GetConcreteFrameIndex()) {
SetPlanComplete();
if (log) {
- log->Printf("Frame we stepped into is inlined into the frame "
- "we were stepping from, stopping.");
+ LLDB_LOGF(log,
+ "Frame we stepped into is inlined into the frame "
+ "we were stepping from, stopping.");
}
return true;
}
@@ -188,7 +190,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
s.Address(return_addr, m_thread.CalculateTarget()
->GetArchitecture()
.GetAddressByteSize());
- log->Printf("%s.", s.GetData());
+ LLDB_LOGF(log, "%s.", s.GetData());
}
// StepInstruction should probably have the tri-state RunMode, but
@@ -209,8 +211,7 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) {
return true;
}
} else {
- if (log)
- log->Printf("Could not find previous frame, stopping.");
+ LLDB_LOGF(log, "Could not find previous frame, stopping.");
SetPlanComplete();
return true;
}
@@ -243,8 +244,7 @@ bool ThreadPlanStepInstruction::WillStop() { return true; }
bool ThreadPlanStepInstruction::MischiefManaged() {
if (IsPlanComplete()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Completed single instruction step plan.");
+ LLDB_LOGF(log, "Completed single instruction step plan.");
ThreadPlan::MischiefManaged();
return true;
} else {
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index bf55c376513d..d7dae446b229 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -408,7 +408,7 @@ bool ThreadPlanStepOut::MischiefManaged() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log)
- log->Printf("Completed step out plan.");
+ LLDB_LOGF(log, "Completed step out plan.");
if (m_return_bp_id != LLDB_INVALID_BREAK_ID) {
m_thread.CalculateTarget()->RemoveBreakpointByID(m_return_bp_id);
m_return_bp_id = LLDB_INVALID_BREAK_ID;
@@ -433,7 +433,7 @@ bool ThreadPlanStepOut::QueueInlinedStepPlan(bool queue_now) {
if (log) {
StreamString s;
immediate_return_from_sp->Dump(&s, true, false);
- log->Printf("Queuing inlined frame to step past: %s.", s.GetData());
+ LLDB_LOGF(log, "Queuing inlined frame to step past: %s.", s.GetData());
}
Block *from_block = immediate_return_from_sp->GetFrameBlock();
diff --git a/source/Target/ThreadPlanStepOverBreakpoint.cpp b/source/Target/ThreadPlanStepOverBreakpoint.cpp
index 4770b57ab7f2..725669b1e9a8 100644
--- a/source/Target/ThreadPlanStepOverBreakpoint.cpp
+++ b/source/Target/ThreadPlanStepOverBreakpoint.cpp
@@ -62,11 +62,9 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) {
StopReason reason = stop_info_sp->GetStopReason();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ LLDB_LOGF(log, "Step over breakpoint stopped for reason: %s.",
+ Thread::StopReasonAsCString(reason));
- if (log)
- log->Printf("Step over breakpoint stopped for reason: %s.",
- Thread::StopReasonAsCString(reason));
-
switch (reason) {
case eStopReasonTrace:
case eStopReasonNone:
@@ -91,9 +89,10 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) {
lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
if (pc_addr == m_breakpoint_addr) {
- if (log)
- log->Printf("Got breakpoint stop reason but pc: 0x%" PRIx64
- "hasn't changed.", pc_addr);
+ LLDB_LOGF(log,
+ "Got breakpoint stop reason but pc: 0x%" PRIx64
+ "hasn't changed.",
+ pc_addr);
return true;
}
@@ -149,8 +148,7 @@ bool ThreadPlanStepOverBreakpoint::MischiefManaged() {
return false;
} else {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Completed step over breakpoint plan.");
+ LLDB_LOGF(log, "Completed step over breakpoint plan.");
// Otherwise, re-enable the breakpoint we were stepping over, and we're
// done.
ReenableBreakpointSite();
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
index 3aaeac9f5b21..2de678597c8a 100644
--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -131,7 +131,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
s.Address(
m_thread.GetRegisterContext()->GetPC(),
m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
- log->Printf("ThreadPlanStepOverRange reached %s.", s.GetData());
+ LLDB_LOGF(log, "ThreadPlanStepOverRange reached %s.", s.GetData());
}
// If we're out of the range but in the same frame or in our caller's frame
@@ -155,8 +155,8 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) {
stop_others, m_status);
if (new_plan_sp && log)
- log->Printf(
- "Thought I stepped out, but in fact arrived at a trampoline.");
+ LLDB_LOGF(log,
+ "Thought I stepped out, but in fact arrived at a trampoline.");
} else if (frame_order == eFrameCompareYounger) {
// Make sure we really are in a new frame. Do that by unwinding and seeing
// if the start function really is our start function...
@@ -371,10 +371,10 @@ bool ThreadPlanStepOverRange::DoWillResume(lldb::StateType resume_state,
bool in_inlined_stack = m_thread.DecrementCurrentInlinedDepth();
if (in_inlined_stack) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("ThreadPlanStepInRange::DoWillResume: adjusting range to "
- "the frame at inlined depth %d.",
- m_thread.GetCurrentInlinedDepth());
+ LLDB_LOGF(log,
+ "ThreadPlanStepInRange::DoWillResume: adjusting range to "
+ "the frame at inlined depth %d.",
+ m_thread.GetCurrentInlinedDepth());
StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0);
if (stack_sp) {
Block *frame_block = stack_sp->GetFrameBlock();
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
index 49c72dbf0911..27513a34eadb 100644
--- a/source/Target/ThreadPlanStepRange.cpp
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -68,9 +68,8 @@ Vote ThreadPlanStepRange::ShouldReportStop(Event *event_ptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
const Vote vote = IsPlanComplete() ? eVoteYes : eVoteNo;
- if (log)
- log->Printf("ThreadPlanStepRange::ShouldReportStop() returning vote %i\n",
- vote);
+ LLDB_LOGF(log, "ThreadPlanStepRange::ShouldReportStop() returning vote %i\n",
+ vote);
return vote;
}
@@ -137,7 +136,8 @@ bool ThreadPlanStepRange::InRange() {
true, Address::DumpStyleLoadAddress,
Address::DumpStyleLoadAddress, true);
- log->Printf(
+ LLDB_LOGF(
+ log,
"Step range plan stepped to another range of same line: %s",
s.GetData());
}
@@ -155,9 +155,10 @@ bool ThreadPlanStepRange::InRange() {
true, Address::DumpStyleLoadAddress,
Address::DumpStyleLoadAddress, true);
- log->Printf("Step range plan stepped to a range at linenumber 0 "
- "stepping through that range: %s",
- s.GetData());
+ LLDB_LOGF(log,
+ "Step range plan stepped to a range at linenumber 0 "
+ "stepping through that range: %s",
+ s.GetData());
}
} else if (new_context.line_entry.range.GetBaseAddress().GetLoadAddress(
m_thread.CalculateTarget().get()) != pc_load_addr) {
@@ -177,9 +178,10 @@ bool ThreadPlanStepRange::InRange() {
true, Address::DumpStyleLoadAddress,
Address::DumpStyleLoadAddress, true);
- log->Printf("Step range plan stepped to the middle of new "
- "line(%d): %s, continuing to clear this line.",
- new_context.line_entry.line, s.GetData());
+ LLDB_LOGF(log,
+ "Step range plan stepped to the middle of new "
+ "line(%d): %s, continuing to clear this line.",
+ new_context.line_entry.line, s.GetData());
}
}
}
@@ -187,7 +189,7 @@ bool ThreadPlanStepRange::InRange() {
}
if (!ret_value && log)
- log->Printf("Step range plan out of range to 0x%" PRIx64, pc_load_addr);
+ LLDB_LOGF(log, "Step range plan out of range to 0x%" PRIx64, pc_load_addr);
return ret_value;
}
@@ -285,9 +287,8 @@ InstructionList *ThreadPlanStepRange::GetInstructionsForAddress(
void ThreadPlanStepRange::ClearNextBranchBreakpoint() {
if (m_next_branch_bp_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Removing next branch breakpoint: %d.",
- m_next_branch_bp_sp->GetID());
+ LLDB_LOGF(log, "Removing next branch breakpoint: %d.",
+ m_next_branch_bp_sp->GetID());
GetTarget().RemoveBreakpointByID(m_next_branch_bp_sp->GetID());
m_next_branch_bp_sp.reset();
m_could_not_resolve_hw_bp = false;
@@ -357,11 +358,12 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
bp_site_id = bp_site->GetID();
}
}
- log->Printf("ThreadPlanStepRange::SetNextBranchBreakpoint - Setting "
- "breakpoint %d (site %d) to run to address 0x%" PRIx64,
- m_next_branch_bp_sp->GetID(), bp_site_id,
- run_to_address.GetLoadAddress(
- &m_thread.GetProcess()->GetTarget()));
+ LLDB_LOGF(log,
+ "ThreadPlanStepRange::SetNextBranchBreakpoint - Setting "
+ "breakpoint %d (site %d) to run to address 0x%" PRIx64,
+ m_next_branch_bp_sp->GetID(), bp_site_id,
+ run_to_address.GetLoadAddress(
+ &m_thread.GetProcess()->GetTarget()));
}
m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
@@ -402,11 +404,11 @@ bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop(
break;
}
}
- if (log)
- log->Printf("ThreadPlanStepRange::NextRangeBreakpointExplainsStop - Hit "
- "next range breakpoint which has %" PRIu64
- " owners - explains stop: %u.",
- (uint64_t)num_owners, explains_stop);
+ LLDB_LOGF(log,
+ "ThreadPlanStepRange::NextRangeBreakpointExplainsStop - Hit "
+ "next range breakpoint which has %" PRIu64
+ " owners - explains stop: %u.",
+ (uint64_t)num_owners, explains_stop);
ClearNextBranchBreakpoint();
return explains_stop;
}
@@ -445,8 +447,7 @@ bool ThreadPlanStepRange::MischiefManaged() {
if (done) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Completed step through range plan.");
+ LLDB_LOGF(log, "Completed step through range plan.");
ClearNextBranchBreakpoint();
ThreadPlan::MischiefManaged();
return true;
@@ -461,8 +462,8 @@ bool ThreadPlanStepRange::IsPlanStale() {
if (frame_order == eFrameCompareOlder) {
if (log) {
- log->Printf("ThreadPlanStepRange::IsPlanStale returning true, we've "
- "stepped out.");
+ LLDB_LOGF(log, "ThreadPlanStepRange::IsPlanStale returning true, we've "
+ "stepped out.");
}
return true;
} else if (frame_order == eFrameCompareEqual && InSymbol()) {
diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp
index e46eba00184e..92b7fce1bc90 100644
--- a/source/Target/ThreadPlanStepThrough.cpp
+++ b/source/Target/ThreadPlanStepThrough.cpp
@@ -64,8 +64,8 @@ ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread,
}
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
if (log) {
- log->Printf("Setting backstop breakpoint %d at address: 0x%" PRIx64,
- m_backstop_bkpt_id, m_backstop_addr);
+ LLDB_LOGF(log, "Setting backstop breakpoint %d at address: 0x%" PRIx64,
+ m_backstop_bkpt_id, m_backstop_addr);
}
}
}
@@ -103,11 +103,12 @@ void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() {
if (m_sub_plan_sp) {
StreamString s;
m_sub_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
- log->Printf("Found step through plan from 0x%" PRIx64 ": %s",
- current_address, s.GetData());
+ LLDB_LOGF(log, "Found step through plan from 0x%" PRIx64 ": %s",
+ current_address, s.GetData());
} else {
- log->Printf("Couldn't find step through plan from address 0x%" PRIx64 ".",
- current_address);
+ LLDB_LOGF(log,
+ "Couldn't find step through plan from address 0x%" PRIx64 ".",
+ current_address);
}
}
}
@@ -234,8 +235,7 @@ bool ThreadPlanStepThrough::MischiefManaged() {
if (!IsPlanComplete()) {
return false;
} else {
- if (log)
- log->Printf("Completed step through step plan.");
+ LLDB_LOGF(log, "Completed step through step plan.");
ClearBackstopBreakpoint();
ThreadPlan::MischiefManaged();
diff --git a/source/Target/ThreadPlanStepUntil.cpp b/source/Target/ThreadPlanStepUntil.cpp
index d4109c3d38da..54d276337488 100644
--- a/source/Target/ThreadPlanStepUntil.cpp
+++ b/source/Target/ThreadPlanStepUntil.cpp
@@ -326,8 +326,7 @@ bool ThreadPlanStepUntil::MischiefManaged() {
bool done = false;
if (IsPlanComplete()) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Completed step until plan.");
+ LLDB_LOGF(log, "Completed step until plan.");
Clear();
done = true;
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index 4e79b6b1e59d..5782fe8e6443 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -46,7 +46,7 @@ Stream *ThreadPlanTracer::GetLogStream() {
else {
TargetSP target_sp(m_thread.CalculateTarget());
if (target_sp)
- return target_sp->GetDebugger().GetOutputFile().get();
+ return &(target_sp->GetDebugger().GetOutputStream());
}
return nullptr;
}
@@ -93,15 +93,20 @@ Disassembler *ThreadPlanAssemblyTracer::GetDisassembler() {
TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() {
if (!m_intptr_type.IsValid()) {
- TargetSP target_sp(m_thread.CalculateTarget());
- if (target_sp) {
- TypeSystem *type_system =
- target_sp->GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC);
- if (type_system)
- m_intptr_type =
- TypeFromUser(type_system->GetBuiltinTypeForEncodingAndBitSize(
+ if (auto target_sp = m_thread.CalculateTarget()) {
+ auto type_system_or_err =
+ target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES),
+ std::move(err),
+ "Unable to get integer pointer type from TypeSystem");
+ } else {
+ m_intptr_type = TypeFromUser(
+ type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint,
target_sp->GetArchitecture().GetAddressByteSize() * 8));
+ }
}
}
return m_intptr_type;
diff --git a/source/Utility/ArchSpec.cpp b/source/Utility/ArchSpec.cpp
index 81b87fff88d4..40cc4a092b0d 100644
--- a/source/Utility/ArchSpec.cpp
+++ b/source/Utility/ArchSpec.cpp
@@ -101,6 +101,8 @@ static const CoreDefinition g_core_definitions[] = {
ArchSpec::eCore_arm_arm64, "arm64"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
ArchSpec::eCore_arm_armv8, "armv8"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::aarch64_32,
+ ArchSpec::eCore_arm_arm64_32, "arm64_32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
ArchSpec::eCore_arm_aarch64, "aarch64"},
@@ -214,6 +216,7 @@ static const CoreDefinition g_core_definitions[] = {
ArchSpec::eCore_uknownMach32, "unknown-mach-32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch,
ArchSpec::eCore_uknownMach64, "unknown-mach-64"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}
};
// Ensure that we have an entry in the g_core_definitions for each core. If you
@@ -243,19 +246,9 @@ void ArchSpec::ListSupportedArchNames(StringList &list) {
list.AppendString(g_core_definitions[i].name);
}
-size_t ArchSpec::AutoComplete(CompletionRequest &request) {
- if (!request.GetCursorArgumentPrefix().empty()) {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
- if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
- request.GetCursorArgumentPrefix()))
- request.AddCompletion(g_core_definitions[i].name);
- }
- } else {
- StringList matches;
- ListSupportedArchNames(matches);
- request.AddCompletions(matches);
- }
- return request.GetNumberOfMatches();
+void ArchSpec::AutoComplete(CompletionRequest &request) {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ request.TryCompleteCurrentArg(g_core_definitions[i].name);
}
#define CPU_ANY (UINT32_MAX)
@@ -306,6 +299,10 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = {
SUBTYPE_MASK},
{ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX,
SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 0,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 1,
+ UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, CPU_ANY,
UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_thumb, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
@@ -446,6 +443,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el
{ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON,
LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON
+ {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARC
};
static const ArchDefinition g_elf_arch_def = {
@@ -469,7 +468,9 @@ static const ArchDefinitionEntry g_coff_arch_entries[] = {
{ArchSpec::eCore_thumb, llvm::COFF::IMAGE_FILE_MACHINE_THUMB,
LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARMv7
{ArchSpec::eCore_x86_64_x86_64, llvm::COFF::IMAGE_FILE_MACHINE_AMD64,
- LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu} // AMD64
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // AMD64
+ {ArchSpec::eCore_arm_arm64, llvm::COFF::IMAGE_FILE_MACHINE_ARM64,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu} // ARM64
};
static const ArchDefinition g_coff_arch_def = {
@@ -760,6 +761,7 @@ bool ArchSpec::CharIsSignedByDefault() const {
return true;
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::aarch64_be:
case llvm::Triple::arm:
case llvm::Triple::armeb:
@@ -946,8 +948,10 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
}
} else {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, cpu, sub);
+ LLDB_LOGF(log,
+ "Unable to find a core definition for cpu 0x%" PRIx32
+ " sub %" PRId32,
+ cpu, sub);
}
}
CoreUpdated(update_triple);
@@ -1245,6 +1249,14 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
}
break;
+ case ArchSpec::eCore_arm_arm64_32:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ try_inverse = false;
+ }
+ break;
+
case ArchSpec::eCore_mips32:
if (!enforce_exact_match) {
if (core2 >= ArchSpec::kCore_mips32_first &&
diff --git a/source/Utility/Args.cpp b/source/Utility/Args.cpp
index 77b0d43254a1..9fcc833ce432 100644
--- a/source/Utility/Args.cpp
+++ b/source/Utility/Args.cpp
@@ -163,7 +163,6 @@ Args::ArgEntry::ArgEntry(llvm::StringRef str, char quote) : quote(quote) {
::memcpy(data(), str.data() ? str.data() : "", size);
ptr[size] = 0;
- ref = llvm::StringRef(c_str(), size);
}
// Args constructor
@@ -172,8 +171,8 @@ Args::Args(llvm::StringRef command) { SetCommandString(command); }
Args::Args(const Args &rhs) { *this = rhs; }
Args::Args(const StringList &list) : Args() {
- for (size_t i = 0; i < list.GetSize(); ++i)
- AppendArgument(list[i]);
+ for (const std::string &arg : list)
+ AppendArgument(arg);
}
Args &Args::operator=(const Args &rhs) {
@@ -182,7 +181,7 @@ Args &Args::operator=(const Args &rhs) {
m_argv.clear();
m_entries.clear();
for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
+ m_entries.emplace_back(entry.ref(), entry.quote);
m_argv.push_back(m_entries.back().data());
}
m_argv.push_back(nullptr);
@@ -199,7 +198,7 @@ void Args::Dump(Stream &s, const char *label_name) const {
int i = 0;
for (auto &entry : m_entries) {
s.Indent();
- s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref);
+ s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref());
}
s.Format("{0}[{1}]=NULL\n", label_name, i);
s.EOL();
@@ -211,7 +210,7 @@ bool Args::GetCommandString(std::string &command) const {
for (size_t i = 0; i < m_entries.size(); ++i) {
if (i > 0)
command += ' ';
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
}
return !m_entries.empty();
@@ -226,10 +225,10 @@ bool Args::GetQuotedCommandString(std::string &command) const {
if (m_entries[i].quote) {
command += m_entries[i].quote;
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
command += m_entries[i].quote;
} else {
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
}
}
@@ -260,12 +259,6 @@ const char *Args::GetArgumentAtIndex(size_t idx) const {
return nullptr;
}
-char Args::GetArgumentQuoteCharAtIndex(size_t idx) const {
- if (idx < m_entries.size())
- return m_entries[idx].quote;
- return '\0';
-}
-
char **Args::GetArgumentVector() {
assert(!m_argv.empty());
// TODO: functions like execve and posix_spawnp exhibit undefined behavior
@@ -299,7 +292,7 @@ void Args::AppendArguments(const Args &rhs) {
assert(m_argv.back() == nullptr);
m_argv.pop_back();
for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
+ m_entries.emplace_back(entry.ref(), entry.quote);
m_argv.push_back(m_entries.back().data());
}
m_argv.push_back(nullptr);
@@ -342,15 +335,8 @@ void Args::ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
if (idx >= m_entries.size())
return;
- if (arg_str.size() > m_entries[idx].ref.size()) {
- m_entries[idx] = ArgEntry(arg_str, quote_char);
- m_argv[idx] = m_entries[idx].data();
- } else {
- const char *src_data = arg_str.data() ? arg_str.data() : "";
- ::memcpy(m_entries[idx].data(), src_data, arg_str.size());
- m_entries[idx].ptr[arg_str.size()] = 0;
- m_entries[idx].ref = m_entries[idx].ref.take_front(arg_str.size());
- }
+ m_entries[idx] = ArgEntry(arg_str, quote_char);
+ m_argv[idx] = m_entries[idx].data();
}
void Args::DeleteArgumentAtIndex(size_t idx) {
@@ -388,29 +374,6 @@ void Args::Clear() {
m_argv.push_back(nullptr);
}
-const char *Args::StripSpaces(std::string &s, bool leading, bool trailing,
- bool return_null_if_empty) {
- static const char *k_white_space = " \t\v";
- if (!s.empty()) {
- if (leading) {
- size_t pos = s.find_first_not_of(k_white_space);
- if (pos == std::string::npos)
- s.clear();
- else if (pos > 0)
- s.erase(0, pos);
- }
-
- if (trailing) {
- size_t rpos = s.find_last_not_of(k_white_space);
- if (rpos != std::string::npos && rpos + 1 < s.size())
- s.erase(rpos + 1);
- }
- }
- if (return_null_if_empty && s.empty())
- return nullptr;
- return s.c_str();
-}
-
const char *Args::GetShellSafeArgument(const FileSpec &shell,
const char *unsafe_arg,
std::string &safe_arg) {
diff --git a/source/Utility/Broadcaster.cpp b/source/Utility/Broadcaster.cpp
index 597888cfa0e2..148fdf7ba5b1 100644
--- a/source/Utility/Broadcaster.cpp
+++ b/source/Utility/Broadcaster.cpp
@@ -214,11 +214,12 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp,
if (Log *log = lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS)) {
StreamString event_description;
event_sp->Dump(&event_description);
- log->Printf("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
- "unique =%i) hijack = %p",
- static_cast<void *>(this), GetBroadcasterName(),
- event_description.GetData(), unique,
- static_cast<void *>(hijacking_listener_sp.get()));
+ LLDB_LOGF(log,
+ "%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
+ "unique =%i) hijack = %p",
+ static_cast<void *>(this), GetBroadcasterName(),
+ event_description.GetData(), unique,
+ static_cast<void *>(hijacking_listener_sp.get()));
}
if (hijacking_listener_sp) {
diff --git a/source/Utility/CompletionRequest.cpp b/source/Utility/CompletionRequest.cpp
index c62ec4f56ffa..3b5a4570e324 100644
--- a/source/Utility/CompletionRequest.cpp
+++ b/source/Utility/CompletionRequest.cpp
@@ -13,46 +13,32 @@ using namespace lldb_private;
CompletionRequest::CompletionRequest(llvm::StringRef command_line,
unsigned raw_cursor_pos,
- int match_start_point,
- int max_return_elements,
CompletionResult &result)
: m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
- m_match_start_point(match_start_point),
- m_max_return_elements(max_return_elements), m_result(result) {
+ m_result(result) {
+ assert(raw_cursor_pos <= command_line.size() && "Out of bounds cursor?");
// We parse the argument up to the cursor, so the last argument in
// parsed_line is the one containing the cursor, and the cursor is after the
// last character.
- m_parsed_line = Args(command_line);
- m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos));
+ llvm::StringRef partial_command(command_line.substr(0, raw_cursor_pos));
+ m_parsed_line = Args(partial_command);
- m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1;
-
- if (m_cursor_index == -1)
+ if (GetParsedLine().GetArgumentCount() == 0) {
+ m_cursor_index = 0;
m_cursor_char_position = 0;
- else
+ } else {
+ m_cursor_index = GetParsedLine().GetArgumentCount() - 1U;
m_cursor_char_position =
- strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));
-
- const char *cursor = command_line.data() + raw_cursor_pos;
- if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
- // We are just after a space. If we are in an argument, then we will
- // continue parsing, but if we are between arguments, then we have to
- // complete whatever the next element would be. We can distinguish the two
- // cases because if we are in an argument (e.g. because the space is
- // protected by a quote) then the space will also be in the parsed
- // argument...
-
- const char *current_elem =
- m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index);
- if (m_cursor_char_position == 0 ||
- current_elem[m_cursor_char_position - 1] != ' ') {
- m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(),
- '\0');
- m_cursor_index++;
- m_cursor_char_position = 0;
- }
+ strlen(GetParsedLine().GetArgumentAtIndex(m_cursor_index));
}
+
+ // The cursor is after a space but the space is not part of the argument.
+ // Let's add an empty fake argument to the end to make sure the completion
+ // code. Note: The space could be part of the last argument when it's quoted.
+ if (partial_command.endswith(" ") &&
+ !GetCursorArgumentPrefix().endswith(" "))
+ AppendEmptyArgument();
}
std::string CompletionResult::Completion::GetUniqueKey() const {
@@ -66,13 +52,16 @@ std::string CompletionResult::Completion::GetUniqueKey() const {
std::string result;
result.append(std::to_string(m_completion.size()));
result.append(m_completion);
+ result.append(std::to_string(static_cast<int>(m_mode)));
+ result.append(":");
result.append(m_descripton);
return result;
}
void CompletionResult::AddResult(llvm::StringRef completion,
- llvm::StringRef description) {
- Completion r(completion, description);
+ llvm::StringRef description,
+ CompletionMode mode) {
+ Completion r(completion, description, mode);
// Add the completion if we haven't seen the same value before.
if (m_added_values.insert(r.GetUniqueKey()).second)
@@ -82,11 +71,11 @@ void CompletionResult::AddResult(llvm::StringRef completion,
void CompletionResult::GetMatches(StringList &matches) const {
matches.Clear();
for (const Completion &completion : m_results)
- matches.AppendString(completion.m_completion);
+ matches.AppendString(completion.GetCompletion());
}
void CompletionResult::GetDescriptions(StringList &descriptions) const {
descriptions.Clear();
for (const Completion &completion : m_results)
- descriptions.AppendString(completion.m_descripton);
+ descriptions.AppendString(completion.GetDescription());
}
diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp
index 46b7ab259383..2516ecf6a989 100644
--- a/source/Utility/ConstString.cpp
+++ b/source/Utility/ConstString.cpp
@@ -59,23 +59,6 @@ public:
return nullptr;
}
- bool SetMangledCounterparts(const char *key_ccstr, const char *value_ccstr) {
- if (key_ccstr != nullptr && value_ccstr != nullptr) {
- {
- const uint8_t h = hash(llvm::StringRef(key_ccstr));
- llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
- GetStringMapEntryFromKeyData(key_ccstr).setValue(value_ccstr);
- }
- {
- const uint8_t h = hash(llvm::StringRef(value_ccstr));
- llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
- GetStringMapEntryFromKeyData(value_ccstr).setValue(key_ccstr);
- }
- return true;
- }
- return false;
- }
-
const char *GetConstCString(const char *cstr) {
if (cstr != nullptr)
return GetConstCStringWithLength(cstr, strlen(cstr));
diff --git a/source/Utility/DataExtractor.cpp b/source/Utility/DataExtractor.cpp
index 79a1f75d737c..f642a8fc7639 100644
--- a/source/Utility/DataExtractor.cpp
+++ b/source/Utility/DataExtractor.cpp
@@ -816,26 +816,25 @@ DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
// non-zero and there aren't enough available bytes, nullptr will be returned
// and "offset_ptr" will not be updated.
const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
- const char *cstr = reinterpret_cast<const char *>(PeekData(*offset_ptr, 1));
- if (cstr) {
- const char *cstr_end = cstr;
- const char *end = reinterpret_cast<const char *>(m_end);
- while (cstr_end < end && *cstr_end)
- ++cstr_end;
-
- // Now we are either at the end of the data or we point to the
- // NULL C string terminator with cstr_end...
- if (*cstr_end == '\0') {
- // Advance the offset with one extra byte for the NULL terminator
- *offset_ptr += (cstr_end - cstr + 1);
- return cstr;
- }
+ const char *start = reinterpret_cast<const char *>(PeekData(*offset_ptr, 1));
+ // Already at the end of the data.
+ if (!start)
+ return nullptr;
- // We reached the end of the data without finding a NULL C string
- // terminator. Fall through and return nullptr otherwise anyone that would
- // have used the result as a C string can wander into unknown memory...
- }
- return nullptr;
+ const char *end = reinterpret_cast<const char *>(m_end);
+
+ // Check all bytes for a null terminator that terminates a C string.
+ const char *terminator_or_end = std::find(start, end, '\0');
+
+ // We didn't find a null terminator, so return nullptr to indicate that there
+ // is no valid C string at that offset.
+ if (terminator_or_end == end)
+ return nullptr;
+
+ // Update offset_ptr for the caller to point to the data behind the
+ // terminator (which is 1 byte long).
+ *offset_ptr += (terminator_or_end - start + 1UL);
+ return start;
}
// Extracts a NULL terminated C string from the fixed length field of length
diff --git a/source/Utility/FileCollector.cpp b/source/Utility/FileCollector.cpp
deleted file mode 100644
index ed9359192205..000000000000
--- a/source/Utility/FileCollector.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- FileCollector.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/Utility/FileCollector.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-
-using namespace lldb_private;
-using namespace llvm;
-
-static bool IsCaseSensitivePath(StringRef path) {
- SmallString<256> tmp_dest = path, upper_dest, real_dest;
-
- // Remove component traversals, links, etc.
- if (!sys::fs::real_path(path, tmp_dest))
- return true; // Current default value in vfs.yaml
- path = tmp_dest;
-
- // Change path to all upper case and ask for its real path, if the latter
- // exists and is equal to path, it's not case sensitive. Default to case
- // sensitive in the absence of real_path, since this is the YAMLVFSWriter
- // default.
- upper_dest = path.upper();
- if (sys::fs::real_path(upper_dest, real_dest) && path.equals(real_dest))
- return false;
- return true;
-}
-
-FileCollector::FileCollector(const FileSpec &root, const FileSpec &overlay_root)
- : m_root(root), m_overlay_root(overlay_root) {
- sys::fs::create_directories(m_root.GetPath(), true);
-}
-
-bool FileCollector::GetRealPath(StringRef src_path,
- SmallVectorImpl<char> &result) {
- SmallString<256> real_path;
- StringRef FileName = sys::path::filename(src_path);
- std::string directory = sys::path::parent_path(src_path).str();
- auto dir_with_symlink = m_symlink_map.find(directory);
-
- // Use real_path to fix any symbolic link component present in a path.
- // Computing the real path is expensive, cache the search through the
- // parent path directory.
- if (dir_with_symlink == m_symlink_map.end()) {
- auto ec = sys::fs::real_path(directory, real_path);
- if (ec)
- return false;
- m_symlink_map[directory] = real_path.str();
- } else {
- real_path = dir_with_symlink->second;
- }
-
- sys::path::append(real_path, FileName);
- result.swap(real_path);
- return true;
-}
-
-void FileCollector::AddFile(const Twine &file) {
- std::lock_guard<std::mutex> lock(m_mutex);
- std::string file_str = file.str();
- if (MarkAsSeen(file_str))
- AddFileImpl(file_str);
-}
-
-void FileCollector::AddFileImpl(StringRef src_path) {
- std::string root = m_root.GetPath();
-
- // We need an absolute src path to append to the root.
- SmallString<256> absolute_src = src_path;
- sys::fs::make_absolute(absolute_src);
-
- // Canonicalize src to a native path to avoid mixed separator styles.
- sys::path::native(absolute_src);
-
- // Remove redundant leading "./" pieces and consecutive separators.
- absolute_src = sys::path::remove_leading_dotslash(absolute_src);
-
- // Canonicalize the source path by removing "..", "." components.
- SmallString<256> virtual_path = absolute_src;
- sys::path::remove_dots(virtual_path, /*remove_dot_dot=*/true);
-
- // If a ".." component is present after a symlink component, remove_dots may
- // lead to the wrong real destination path. Let the source be canonicalized
- // like that but make sure we always use the real path for the destination.
- SmallString<256> copy_from;
- if (!GetRealPath(absolute_src, copy_from))
- copy_from = virtual_path;
-
- SmallString<256> dst_path = StringRef(root);
- sys::path::append(dst_path, sys::path::relative_path(copy_from));
-
- // Always map a canonical src path to its real path into the YAML, by doing
- // this we map different virtual src paths to the same entry in the VFS
- // overlay, which is a way to emulate symlink inside the VFS; this is also
- // needed for correctness, not doing that can lead to module redefinition
- // errors.
- AddFileToMapping(virtual_path, dst_path);
-}
-
-/// Set the access and modification time for the given file from the given
-/// status object.
-static std::error_code
-CopyAccessAndModificationTime(StringRef filename,
- const sys::fs::file_status &stat) {
- int fd;
-
- if (auto ec =
- sys::fs::openFileForWrite(filename, fd, sys::fs::CD_OpenExisting))
- return ec;
-
- if (auto ec = sys::fs::setLastAccessAndModificationTime(
- fd, stat.getLastAccessedTime(), stat.getLastModificationTime()))
- return ec;
-
- if (auto ec = sys::Process::SafelyCloseFileDescriptor(fd))
- return ec;
-
- return {};
-}
-
-std::error_code FileCollector::CopyFiles(bool stop_on_error) {
- for (auto &entry : m_vfs_writer.getMappings()) {
- // Create directory tree.
- if (std::error_code ec =
- sys::fs::create_directories(sys::path::parent_path(entry.RPath),
- /*IgnoreExisting=*/true)) {
- if (stop_on_error)
- return ec;
- }
-
- // Copy file over.
- if (std::error_code ec = sys::fs::copy_file(entry.VPath, entry.RPath)) {
- if (stop_on_error)
- return ec;
- }
-
- // Copy over permissions.
- if (auto perms = sys::fs::getPermissions(entry.VPath)) {
- if (std::error_code ec = sys::fs::setPermissions(entry.RPath, *perms)) {
- if (stop_on_error)
- return ec;
- }
- }
-
- // Copy over modification time.
- sys::fs::file_status stat;
- if (std::error_code ec = sys::fs::status(entry.VPath, stat)) {
- if (stop_on_error)
- return ec;
- continue;
- }
- CopyAccessAndModificationTime(entry.RPath, stat);
- }
- return {};
-}
-
-std::error_code FileCollector::WriteMapping(const FileSpec &mapping_file) {
- std::lock_guard<std::mutex> lock(m_mutex);
-
- std::string root = m_overlay_root.GetPath();
-
- m_vfs_writer.setOverlayDir(root);
- m_vfs_writer.setCaseSensitivity(IsCaseSensitivePath(root));
- m_vfs_writer.setUseExternalNames(false);
-
- std::error_code ec;
- raw_fd_ostream os(mapping_file.GetPath(), ec, sys::fs::F_Text);
- if (ec)
- return ec;
-
- m_vfs_writer.write(os);
-
- return {};
-}
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index 35d22404b948..f22ab4d84e40 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -72,8 +72,8 @@ FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
SetFile(path, style);
}
-FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &Triple)
- : FileSpec{path, Triple.isOSWindows() ? Style::windows : Style::posix} {}
+FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &triple)
+ : FileSpec{path, triple.isOSWindows() ? Style::windows : Style::posix} {}
// Copy constructor
FileSpec::FileSpec(const FileSpec *rhs) : m_directory(), m_filename() {
@@ -228,8 +228,8 @@ void FileSpec::SetFile(llvm::StringRef pathname, Style style) {
m_directory.SetString(directory);
}
-void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &Triple) {
- return SetFile(path, Triple.isOSWindows() ? Style::windows : Style::posix);
+void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &triple) {
+ return SetFile(path, triple.isOSWindows() ? Style::windows : Style::posix);
}
// Convert to pointer operator. This allows code to check any FileSpec objects
diff --git a/source/Utility/GDBRemote.cpp b/source/Utility/GDBRemote.cpp
new file mode 100644
index 000000000000..85c4bc69a8d1
--- /dev/null
+++ b/source/Utility/GDBRemote.cpp
@@ -0,0 +1,105 @@
+//===-- GDBRemote.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/Utility/GDBRemote.h"
+
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Stream.h"
+
+#include <stdio.h>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+StreamGDBRemote::StreamGDBRemote() : StreamString() {}
+
+StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
+ ByteOrder byte_order)
+ : StreamString(flags, addr_size, byte_order) {}
+
+StreamGDBRemote::~StreamGDBRemote() {}
+
+int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
+ int bytes_written = 0;
+ const uint8_t *src = static_cast<const uint8_t *>(s);
+ bool binary_is_set = m_flags.Test(eBinary);
+ m_flags.Clear(eBinary);
+ while (src_len) {
+ uint8_t byte = *src;
+ src++;
+ src_len--;
+ if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
+ bytes_written += PutChar(0x7d);
+ byte ^= 0x20;
+ }
+ bytes_written += PutChar(byte);
+ };
+ if (binary_is_set)
+ m_flags.Set(eBinary);
+ return bytes_written;
+}
+
+void GDBRemotePacket::Serialize(raw_ostream &strm) const {
+ yaml::Output yout(strm);
+ yout << const_cast<GDBRemotePacket &>(*this);
+ strm.flush();
+}
+
+llvm::StringRef GDBRemotePacket::GetTypeStr() const {
+ switch (type) {
+ case GDBRemotePacket::ePacketTypeSend:
+ return "send";
+ case GDBRemotePacket::ePacketTypeRecv:
+ return "read";
+ case GDBRemotePacket::ePacketTypeInvalid:
+ return "invalid";
+ }
+ llvm_unreachable("All enum cases should be handled");
+}
+
+void GDBRemotePacket::Dump(Stream &strm) const {
+ strm.Printf("tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", tid,
+ bytes_transmitted, GetTypeStr().data(), packet.data.c_str());
+}
+
+void yaml::ScalarEnumerationTraits<GDBRemotePacket::Type>::enumeration(
+ IO &io, GDBRemotePacket::Type &value) {
+ io.enumCase(value, "Invalid", GDBRemotePacket::ePacketTypeInvalid);
+ io.enumCase(value, "Send", GDBRemotePacket::ePacketTypeSend);
+ io.enumCase(value, "Recv", GDBRemotePacket::ePacketTypeRecv);
+}
+
+void yaml::ScalarTraits<GDBRemotePacket::BinaryData>::output(
+ const GDBRemotePacket::BinaryData &Val, void *, raw_ostream &Out) {
+ Out << toHex(Val.data);
+}
+
+StringRef yaml::ScalarTraits<GDBRemotePacket::BinaryData>::input(
+ StringRef Scalar, void *, GDBRemotePacket::BinaryData &Val) {
+ Val.data = fromHex(Scalar);
+ return {};
+}
+
+void yaml::MappingTraits<GDBRemotePacket>::mapping(IO &io,
+ GDBRemotePacket &Packet) {
+ io.mapRequired("packet", Packet.packet);
+ io.mapRequired("type", Packet.type);
+ io.mapRequired("bytes", Packet.bytes_transmitted);
+ io.mapRequired("index", Packet.packet_idx);
+ io.mapRequired("tid", Packet.tid);
+}
+
+StringRef
+yaml::MappingTraits<GDBRemotePacket>::validate(IO &io,
+ GDBRemotePacket &Packet) {
+ if (Packet.bytes_transmitted != Packet.packet.data.size())
+ return "BinaryData size doesn't match bytes transmitted";
+
+ return {};
+}
diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp
deleted file mode 100644
index 2c3f6229eda1..000000000000
--- a/source/Utility/JSON.cpp
+++ /dev/null
@@ -1,550 +0,0 @@
-//===--------------------- JSON.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/Utility/JSON.h"
-
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/StreamString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ErrorHandling.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <utility>
-
-using namespace lldb_private;
-
-std::string JSONString::json_string_quote_metachars(const std::string &s) {
- if (s.find_first_of("\\\n\"") == std::string::npos)
- return s;
-
- std::string output;
- const size_t s_size = s.size();
- const char *s_chars = s.c_str();
- for (size_t i = 0; i < s_size; i++) {
- unsigned char ch = *(s_chars + i);
- if (ch == '"' || ch == '\\' || ch == '\n') {
- output.push_back('\\');
- if (ch == '\n') ch = 'n';
- }
- output.push_back(ch);
- }
- return output;
-}
-
-JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {}
-
-JSONString::JSONString(const char *s)
- : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {}
-
-JSONString::JSONString(const std::string &s)
- : JSONValue(JSONValue::Kind::String), m_data(s) {}
-
-void JSONString::Write(Stream &s) {
- s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str());
-}
-
-uint64_t JSONNumber::GetAsUnsigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return m_data.m_unsigned;
- case DataType::Signed:
- return static_cast<uint64_t>(m_data.m_signed);
- case DataType::Double:
- return static_cast<uint64_t>(m_data.m_double);
- }
- llvm_unreachable("Unhandled data type");
-}
-
-int64_t JSONNumber::GetAsSigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return static_cast<int64_t>(m_data.m_unsigned);
- case DataType::Signed:
- return m_data.m_signed;
- case DataType::Double:
- return static_cast<int64_t>(m_data.m_double);
- }
- llvm_unreachable("Unhandled data type");
-}
-
-double JSONNumber::GetAsDouble() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return static_cast<double>(m_data.m_unsigned);
- case DataType::Signed:
- return static_cast<double>(m_data.m_signed);
- case DataType::Double:
- return m_data.m_double;
- }
- llvm_unreachable("Unhandled data type");
-}
-
-void JSONNumber::Write(Stream &s) {
- switch (m_data_type) {
- case DataType::Unsigned:
- s.Printf("%" PRIu64, m_data.m_unsigned);
- break;
- case DataType::Signed:
- s.Printf("%" PRId64, m_data.m_signed);
- break;
- case DataType::Double:
- s.Printf("%g", m_data.m_double);
- break;
- }
-}
-
-JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {}
-
-void JSONTrue::Write(Stream &s) { s.Printf("true"); }
-
-JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {}
-
-void JSONFalse::Write(Stream &s) { s.Printf("false"); }
-
-JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {}
-
-void JSONNull::Write(Stream &s) { s.Printf("null"); }
-
-JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {}
-
-void JSONObject::Write(Stream &s) {
- bool first = true;
- s.PutChar('{');
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s.PutChar(',');
- JSONString key(iter->first);
- JSONValue::SP value(iter->second);
- key.Write(s);
- s.PutChar(':');
- value->Write(s);
- }
- s.PutChar('}');
-}
-
-bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) {
- if (key.empty() || nullptr == value.get())
- return false;
- m_elements[key] = value;
- return true;
-}
-
-JSONValue::SP JSONObject::GetObject(const std::string &key) {
- auto iter = m_elements.find(key), end = m_elements.end();
- if (iter == end)
- return JSONValue::SP();
- return iter->second;
-}
-
-JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {}
-
-void JSONArray::Write(Stream &s) {
- bool first = true;
- s.PutChar('[');
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s.PutChar(',');
- (*iter)->Write(s);
- }
- s.PutChar(']');
-}
-
-bool JSONArray::SetObject(Index i, JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- if (i < m_elements.size()) {
- m_elements[i] = value;
- return true;
- }
- if (i == m_elements.size()) {
- m_elements.push_back(value);
- return true;
- }
- return false;
-}
-
-bool JSONArray::AppendObject(JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- m_elements.push_back(value);
- return true;
-}
-
-JSONValue::SP JSONArray::GetObject(Index i) {
- if (i < m_elements.size())
- return m_elements[i];
- return JSONValue::SP();
-}
-
-JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); }
-
-JSONParser::JSONParser(llvm::StringRef data) : StringExtractor(data) {}
-
-JSONParser::Token JSONParser::GetToken(std::string &value) {
- StreamString error;
-
- value.clear();
- SkipSpaces();
- const uint64_t start_index = m_index;
- const char ch = GetChar();
- switch (ch) {
- case '{':
- return Token::ObjectStart;
- case '}':
- return Token::ObjectEnd;
- case '[':
- return Token::ArrayStart;
- case ']':
- return Token::ArrayEnd;
- case ',':
- return Token::Comma;
- case ':':
- return Token::Colon;
- case '\0':
- return Token::EndOfFile;
- case 't':
- if (GetChar() == 'r')
- if (GetChar() == 'u')
- if (GetChar() == 'e')
- return Token::True;
- break;
-
- case 'f':
- if (GetChar() == 'a')
- if (GetChar() == 'l')
- if (GetChar() == 's')
- if (GetChar() == 'e')
- return Token::False;
- break;
-
- case 'n':
- if (GetChar() == 'u')
- if (GetChar() == 'l')
- if (GetChar() == 'l')
- return Token::Null;
- break;
-
- case '"': {
- while (true) {
- bool was_escaped = false;
- int escaped_ch = GetEscapedChar(was_escaped);
- if (escaped_ch == -1) {
- error.Printf(
- "error: an error occurred getting a character from offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
-
- } else {
- const bool is_end_quote = escaped_ch == '"';
- const bool is_null = escaped_ch == 0;
- if (was_escaped || (!is_end_quote && !is_null)) {
- if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) {
- value.append(1, static_cast<char>(escaped_ch));
- } else {
- error.Printf("error: wide character support is needed for unicode "
- "character 0x%4.4x at offset %" PRIu64,
- escaped_ch, start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- } else if (is_end_quote) {
- return Token::String;
- } else if (is_null) {
- value = "error: missing end quote for string";
- return Token::Status;
- }
- }
- }
- } break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- bool done = false;
- bool got_decimal_point = false;
- uint64_t exp_index = 0;
- bool got_int_digits = (ch >= '0') && (ch <= '9');
- bool got_frac_digits = false;
- bool got_exp_digits = false;
- while (!done) {
- const char next_ch = PeekChar();
- switch (next_ch) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (exp_index != 0) {
- got_exp_digits = true;
- } else if (got_decimal_point) {
- got_frac_digits = true;
- } else {
- got_int_digits = true;
- }
- ++m_index; // Skip this character
- break;
-
- case '.':
- if (got_decimal_point) {
- error.Printf("error: extra decimal point found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- } else {
- got_decimal_point = true;
- ++m_index; // Skip this character
- }
- break;
-
- case 'e':
- case 'E':
- if (exp_index != 0) {
- error.Printf(
- "error: extra exponent character found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- } else {
- exp_index = m_index;
- ++m_index; // Skip this character
- }
- break;
-
- case '+':
- case '-':
- // The '+' and '-' can only come after an exponent character...
- if (exp_index == m_index - 1) {
- ++m_index; // Skip the exponent sign character
- } else {
- error.Printf("error: unexpected %c character at offset %" PRIu64,
- next_ch, start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- break;
-
- default:
- done = true;
- break;
- }
- }
-
- if (m_index > start_index) {
- value = m_packet.substr(start_index, m_index - start_index);
- if (got_decimal_point) {
- if (exp_index != 0) {
- // We have an exponent, make sure we got exponent digits
- if (got_exp_digits) {
- return Token::Float;
- } else {
- error.Printf("error: got exponent character but no exponent digits "
- "at offset in float value \"%s\"",
- value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- } else {
- // No exponent, but we need at least one decimal after the decimal
- // point
- if (got_frac_digits) {
- return Token::Float;
- } else {
- error.Printf("error: no digits after decimal point \"%s\"",
- value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- }
- } else {
- // No decimal point
- if (got_int_digits) {
- // We need at least some integer digits to make an integer
- return Token::Integer;
- } else {
- error.Printf("error: no digits negate sign \"%s\"", value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- }
- } else {
- error.Printf("error: invalid number found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- } break;
- default:
- break;
- }
- error.Printf("error: failed to parse token at offset %" PRIu64
- " (around character '%c')",
- start_index, ch);
- value = std::move(error.GetString());
- return Token::Status;
-}
-
-int JSONParser::GetEscapedChar(bool &was_escaped) {
- was_escaped = false;
- const char ch = GetChar();
- if (ch == '\\') {
- was_escaped = true;
- const char ch2 = GetChar();
- switch (ch2) {
- case '"':
- case '\\':
- case '/':
- default:
- break;
-
- case 'b':
- return '\b';
- case 'f':
- return '\f';
- case 'n':
- return '\n';
- case 'r':
- return '\r';
- case 't':
- return '\t';
- case 'u': {
- const int hi_byte = DecodeHexU8();
- const int lo_byte = DecodeHexU8();
- if (hi_byte >= 0 && lo_byte >= 0)
- return hi_byte << 8 | lo_byte;
- return -1;
- } break;
- }
- return ch2;
- }
- return ch;
-}
-
-JSONValue::SP JSONParser::ParseJSONObject() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- std::unique_ptr<JSONObject> dict_up(new JSONObject());
-
- std::string value;
- std::string key;
- while (true) {
- JSONParser::Token token = GetToken(value);
-
- if (token == JSONParser::Token::String) {
- key.swap(value);
- token = GetToken(value);
- if (token == JSONParser::Token::Colon) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- dict_up->SetObject(key, value_sp);
- else
- break;
- }
- } else if (token == JSONParser::Token::ObjectEnd) {
- return JSONValue::SP(dict_up.release());
- } else if (token == JSONParser::Token::Comma) {
- continue;
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONArray() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- std::unique_ptr<JSONArray> array_up(new JSONArray());
-
- std::string value;
- std::string key;
- while (true) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- array_up->AppendObject(value_sp);
- else
- break;
-
- JSONParser::Token token = GetToken(value);
- if (token == JSONParser::Token::Comma) {
- continue;
- } else if (token == JSONParser::Token::ArrayEnd) {
- return JSONValue::SP(array_up.release());
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONValue() {
- std::string value;
- const JSONParser::Token token = GetToken(value);
- switch (token) {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject();
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray();
-
- case JSONParser::Token::Integer: {
- if (value.front() == '-') {
- int64_t sval = 0;
- if (!llvm::StringRef(value).getAsInteger(0, sval))
- return JSONValue::SP(new JSONNumber(sval));
- } else {
- uint64_t uval = 0;
- if (!llvm::StringRef(value).getAsInteger(0, uval))
- return JSONValue::SP(new JSONNumber(uval));
- }
- } break;
-
- case JSONParser::Token::Float: {
- double D;
- if (!llvm::StringRef(value).getAsDouble(D))
- return JSONValue::SP(new JSONNumber(D));
- } break;
-
- case JSONParser::Token::String:
- return JSONValue::SP(new JSONString(value));
-
- case JSONParser::Token::True:
- return JSONValue::SP(new JSONTrue());
-
- case JSONParser::Token::False:
- return JSONValue::SP(new JSONFalse());
-
- case JSONParser::Token::Null:
- return JSONValue::SP(new JSONNull());
-
- default:
- break;
- }
- return JSONValue::SP();
-}
diff --git a/source/Utility/Listener.cpp b/source/Utility/Listener.cpp
index 50c56406c2ca..c2e537ba7dee 100644
--- a/source/Utility/Listener.cpp
+++ b/source/Utility/Listener.cpp
@@ -42,8 +42,8 @@ Listener::Listener(const char *name)
m_events_mutex() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log != nullptr)
- log->Printf("%p Listener::Listener('%s')", static_cast<void *>(this),
- m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast<void *>(this),
+ m_name.c_str());
}
Listener::~Listener() {
@@ -51,9 +51,8 @@ Listener::~Listener() {
Clear();
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
- __FUNCTION__, m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
void Listener::Clear() {
@@ -78,9 +77,8 @@ void Listener::Clear() {
manager_sp->RemoveListener(this);
}
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
- __FUNCTION__, m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
@@ -101,10 +99,11 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr)
- log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
- "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
- static_cast<void *>(this), static_cast<void *>(broadcaster),
- event_mask, acquired_mask, m_name.c_str());
+ LLDB_LOGF(log,
+ "%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, acquired_mask, m_name.c_str());
return acquired_mask;
}
@@ -132,12 +131,13 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr) {
void **pointer = reinterpret_cast<void **>(&callback);
- log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
- "mask = 0x%8.8x, callback = %p, user_data = %p) "
- "acquired_mask = 0x%8.8x for %s",
- static_cast<void *>(this), static_cast<void *>(broadcaster),
- event_mask, *pointer, static_cast<void *>(callback_user_data),
- acquired_mask, m_name.c_str());
+ LLDB_LOGF(log,
+ "%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x, callback = %p, user_data = %p) "
+ "acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, *pointer, static_cast<void *>(callback_user_data),
+ acquired_mask, m_name.c_str());
}
return acquired_mask;
@@ -202,9 +202,9 @@ void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) {
void Listener::AddEvent(EventSP &event_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr)
- log->Printf("%p Listener('%s')::AddEvent (event_sp = {%p})",
- static_cast<void *>(this), m_name.c_str(),
- static_cast<void *>(event_sp.get()));
+ LLDB_LOGF(log, "%p Listener('%s')::AddEvent (event_sp = {%p})",
+ static_cast<void *>(this), m_name.c_str(),
+ static_cast<void *>(event_sp.get()));
std::lock_guard<std::mutex> guard(m_events_mutex);
m_events.push_back(event_sp);
@@ -290,14 +290,15 @@ bool Listener::FindNextEventInternal(
event_sp = *pos;
if (log != nullptr)
- log->Printf("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
- "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
- "remove=%i) event %p",
- static_cast<void *>(this), GetName(),
- static_cast<void *>(broadcaster),
- static_cast<const void *>(broadcaster_names),
- num_broadcaster_names, event_type_mask, remove,
- static_cast<void *>(event_sp.get()));
+ LLDB_LOGF(log,
+ "%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
+ "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
+ "remove=%i) event %p",
+ static_cast<void *>(this), GetName(),
+ static_cast<void *>(broadcaster),
+ static_cast<const void *>(broadcaster_names),
+ num_broadcaster_names, event_type_mask, remove,
+ static_cast<void *>(event_sp.get()));
if (remove) {
m_events.erase(pos);
@@ -366,15 +367,13 @@ bool Listener::GetEventInternal(
if (result == std::cv_status::timeout) {
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf("%p Listener::GetEventInternal() timed out for %s",
- static_cast<void *>(this), m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::GetEventInternal() timed out for %s",
+ static_cast<void *>(this), m_name.c_str());
return false;
} else if (result != std::cv_status::no_timeout) {
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf("%p Listener::GetEventInternal() unknown error for %s",
- static_cast<void *>(this), m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::GetEventInternal() unknown error for %s",
+ static_cast<void *>(this), m_name.c_str());
return false;
}
}
diff --git a/source/Utility/Log.cpp b/source/Utility/Log.cpp
index 217b0d2ba97b..ab5e630114a6 100644
--- a/source/Utility/Log.cpp
+++ b/source/Utility/Log.cpp
@@ -9,7 +9,6 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/VASPrintf.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator.h"
@@ -38,13 +37,22 @@ using namespace lldb_private;
llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map;
-void Log::ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry) {
- stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
- stream << " all - all available logging categories\n";
- stream << " default - default set of logging categories\n";
+void Log::ForEachCategory(
+ const Log::ChannelMap::value_type &entry,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+ lambda("all", "all available logging categories");
+ lambda("default", "default set of logging categories");
for (const auto &category : entry.second.m_channel.categories)
- stream << llvm::formatv(" {0} - {1}\n", category.name,
- category.description);
+ lambda(category.name, category.description);
+}
+
+void Log::ListCategories(llvm::raw_ostream &stream,
+ const ChannelMap::value_type &entry) {
+ stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
+ ForEachCategory(entry,
+ [&stream](llvm::StringRef name, llvm::StringRef description) {
+ stream << llvm::formatv(" {0} - {1}\n", name, description);
+ });
}
uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
@@ -237,6 +245,23 @@ void Log::DisableAllLogChannels() {
entry.second.Disable(UINT32_MAX);
}
+void Log::ForEachChannelCategory(
+ llvm::StringRef channel,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+ auto ch = g_channel_map->find(channel);
+ if (ch == g_channel_map->end())
+ return;
+
+ ForEachCategory(*ch, lambda);
+}
+
+std::vector<llvm::StringRef> Log::ListChannels() {
+ std::vector<llvm::StringRef> result;
+ for (const auto &channel : *g_channel_map)
+ result.push_back(channel.first());
+ return result;
+}
+
void Log::ListAllLogChannels(llvm::raw_ostream &stream) {
if (g_channel_map->empty()) {
stream << "No logging channels are currently registered.\n";
diff --git a/source/Utility/Logging.cpp b/source/Utility/Logging.cpp
index c0856e5d9267..22f38192fa5d 100644
--- a/source/Utility/Logging.cpp
+++ b/source/Utility/Logging.cpp
@@ -62,13 +62,3 @@ Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) {
Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) {
return g_log_channel.GetLogIfAny(mask);
}
-
-
-void lldb_private::LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...) {
- if (Log *log = GetLogIfAnyCategoriesSet(mask)) {
- va_list args;
- va_start(args, format);
- log->VAPrintf(format, args);
- va_end(args);
- }
-}
diff --git a/source/Utility/ProcessInfo.cpp b/source/Utility/ProcessInfo.cpp
index b67ae8779000..5743d223be4f 100644
--- a/source/Utility/ProcessInfo.cpp
+++ b/source/Utility/ProcessInfo.cpp
@@ -42,8 +42,8 @@ const char *ProcessInfo::GetName() const {
return m_executable.GetFilename().GetCString();
}
-size_t ProcessInfo::GetNameLength() const {
- return m_executable.GetFilename().GetLength();
+llvm::StringRef ProcessInfo::GetNameAsStringRef() const {
+ return m_executable.GetFilename().GetStringRef();
}
void ProcessInfo::Dump(Stream &s, Platform *platform) const {
@@ -169,13 +169,15 @@ void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,
if (verbose) {
s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "
- " %s\n",
+ " %s\n",
label);
- s.PutCString("====== ====== ========== ========== ========== ========== "
- "======================== ============================\n");
+ s.PutCString(
+ "====== ====== ========== ========== ========== ========== "
+ "============================== ============================\n");
} else {
- s.Printf("PID PARENT USER TRIPLE %s\n", label);
- s.PutCString("====== ====== ========== ======================== "
+ s.Printf("PID PARENT USER TRIPLE %s\n",
+ label);
+ s.PutCString("====== ====== ========== ============================== "
"============================\n");
}
}
@@ -189,34 +191,47 @@ void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
if (m_arch.IsValid())
m_arch.DumpTriple(arch_strm);
- auto print = [&](UserIDResolver::id_t id,
- llvm::Optional<llvm::StringRef> (UserIDResolver::*get)(
+ auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,
+ uint32_t (ProcessInstanceInfo::*getID)() const,
+ llvm::Optional<llvm::StringRef> (UserIDResolver::*getName)(
UserIDResolver::id_t id)) {
- if (auto name = (resolver.*get)(id))
- s.Format("{0,-10} ", *name);
+ const char *format = "{0,-10} ";
+ if (!(this->*isValid)()) {
+ s.Format(format, "");
+ return;
+ }
+ uint32_t id = (this->*getID)();
+ if (auto name = (resolver.*getName)(id))
+ s.Format(format, *name);
else
- s.Format("{0,-10} ", id);
+ s.Format(format, id);
};
if (verbose) {
- print(m_uid, &UserIDResolver::GetUserName);
- print(m_gid, &UserIDResolver::GetGroupName);
- print(m_euid, &UserIDResolver::GetUserName);
- print(m_egid, &UserIDResolver::GetGroupName);
-
- s.Printf("%-24s ", arch_strm.GetData());
+ print(&ProcessInstanceInfo::UserIDIsValid,
+ &ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);
+ print(&ProcessInstanceInfo::GroupIDIsValid,
+ &ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);
+ print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveUserID,
+ &UserIDResolver::GetUserName);
+ print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveGroupID,
+ &UserIDResolver::GetGroupName);
+
+ s.Printf("%-30s ", arch_strm.GetData());
} else {
- print(m_euid, &UserIDResolver::GetUserName);
- s.Printf(" %-24s ", arch_strm.GetData());
+ print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveUserID,
+ &UserIDResolver::GetUserName);
+ s.Printf("%-30s ", arch_strm.GetData());
}
if (verbose || show_args) {
+ s.PutCString(m_arg0);
const uint32_t argc = m_arguments.GetArgumentCount();
- if (argc > 0) {
- for (uint32_t i = 0; i < argc; i++) {
- if (i > 0)
- s.PutChar(' ');
- s.PutCString(m_arguments.GetArgumentAtIndex(i));
- }
+ for (uint32_t i = 0; i < argc; i++) {
+ s.PutChar(' ');
+ s.PutCString(m_arguments.GetArgumentAtIndex(i));
}
} else {
s.PutCString(GetName());
@@ -226,8 +241,14 @@ void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
}
}
+bool ProcessInstanceInfoMatch::ArchitectureMatches(
+ const ArchSpec &arch_spec) const {
+ return !m_match_info.GetArchitecture().IsValid() ||
+ m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);
+}
+
bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
- if (m_name_match_type == NameMatch::Ignore || process_name == nullptr)
+ if (m_name_match_type == NameMatch::Ignore)
return true;
const char *match_name = m_match_info.GetName();
if (!match_name)
@@ -236,11 +257,8 @@ bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
}
-bool ProcessInstanceInfoMatch::Matches(
+bool ProcessInstanceInfoMatch::ProcessIDsMatch(
const ProcessInstanceInfo &proc_info) const {
- if (!NameMatches(proc_info.GetName()))
- return false;
-
if (m_match_info.ProcessIDIsValid() &&
m_match_info.GetProcessID() != proc_info.GetProcessID())
return false;
@@ -248,7 +266,11 @@ bool ProcessInstanceInfoMatch::Matches(
if (m_match_info.ParentProcessIDIsValid() &&
m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
return false;
+ return true;
+}
+bool ProcessInstanceInfoMatch::UserIDsMatch(
+ const ProcessInstanceInfo &proc_info) const {
if (m_match_info.UserIDIsValid() &&
m_match_info.GetUserID() != proc_info.GetUserID())
return false;
@@ -264,13 +286,14 @@ bool ProcessInstanceInfoMatch::Matches(
if (m_match_info.EffectiveGroupIDIsValid() &&
m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
return false;
-
- if (m_match_info.GetArchitecture().IsValid() &&
- !m_match_info.GetArchitecture().IsCompatibleMatch(
- proc_info.GetArchitecture()))
- return false;
return true;
}
+bool ProcessInstanceInfoMatch::Matches(
+ const ProcessInstanceInfo &proc_info) const {
+ return ArchitectureMatches(proc_info.GetArchitecture()) &&
+ ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&
+ NameMatches(proc_info.GetName());
+}
bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
if (m_name_match_type != NameMatch::Ignore)
diff --git a/source/Utility/RegularExpression.cpp b/source/Utility/RegularExpression.cpp
index 0192e8b8a01a..fd9d963f7294 100644
--- a/source/Utility/RegularExpression.cpp
+++ b/source/Utility/RegularExpression.cpp
@@ -8,168 +8,34 @@
#include "lldb/Utility/RegularExpression.h"
-#include "llvm/ADT/StringRef.h"
-
#include <string>
-// Enable enhanced mode if it is available. This allows for things like \d for
-// digit, \s for space, and many more, but it isn't available everywhere.
-#if defined(REG_ENHANCED)
-#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
-#else
-#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
-#endif
-
using namespace lldb_private;
-RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() {
- memset(&m_preg, 0, sizeof(m_preg));
-}
-
-// Constructor that compiles "re" using "flags" and stores the resulting
-// compiled regular expression into this object.
RegularExpression::RegularExpression(llvm::StringRef str)
- : RegularExpression() {
- Compile(str);
-}
+ : m_regex_text(str),
+ // m_regex does not reference str anymore after it is constructed.
+ m_regex(llvm::Regex(str)) {}
RegularExpression::RegularExpression(const RegularExpression &rhs)
- : RegularExpression() {
- Compile(rhs.GetText());
-}
-
-const RegularExpression &RegularExpression::
-operator=(const RegularExpression &rhs) {
- if (&rhs != this)
- Compile(rhs.GetText());
- return *this;
-}
-
-// Destructor
-//
-// Any previously compiled regular expression contained in this object will be
-// freed.
-RegularExpression::~RegularExpression() { Free(); }
-
-// Compile a regular expression using the supplied regular expression text and
-// flags. The compiled regular expression lives in this object so that it can
-// be readily used for regular expression matches. Execute() can be called
-// after the regular expression is compiled. Any previously compiled regular
-// expression contained in this object will be freed.
-//
-// RETURNS
-// True if the regular expression compiles successfully, false
-// otherwise.
-bool RegularExpression::Compile(llvm::StringRef str) {
- Free();
-
- // regcomp() on darwin does not recognize "" as a valid regular expression,
- // so we substitute it with an equivalent non-empty one.
- m_re = str.empty() ? "()" : str;
- m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS);
- return m_comp_err == 0;
-}
+ : RegularExpression(rhs.GetText()) {}
-// Execute a regular expression match using the compiled regular expression
-// that is already in this object against the match string "s". If any parens
-// are used for regular expression matches "match_count" should indicate the
-// number of regmatch_t values that are present in "match_ptr". The regular
-// expression will be executed using the "execute_flags".
-bool RegularExpression::Execute(llvm::StringRef str, Match *match) const {
- int err = 1;
- if (m_comp_err == 0) {
- // Argument to regexec must be null-terminated.
- std::string reg_str = str;
- if (match) {
- err = ::regexec(&m_preg, reg_str.c_str(), match->GetSize(),
- match->GetData(), 0);
- } else {
- err = ::regexec(&m_preg, reg_str.c_str(), 0, nullptr, 0);
- }
- }
-
- if (err != 0) {
- // The regular expression didn't compile, so clear the matches
- if (match)
- match->Clear();
+bool RegularExpression::Execute(
+ llvm::StringRef str,
+ llvm::SmallVectorImpl<llvm::StringRef> *matches) const {
+ if (!IsValid())
return false;
- }
- return true;
-}
-
-bool RegularExpression::Match::GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- std::string &match_str) const {
- llvm::StringRef match_str_ref;
- if (GetMatchAtIndex(s, idx, match_str_ref)) {
- match_str = match_str_ref.str();
- return true;
- }
- return false;
+ return m_regex.match(str, matches);
}
-bool RegularExpression::Match::GetMatchAtIndex(
- llvm::StringRef s, uint32_t idx, llvm::StringRef &match_str) const {
- if (idx < m_matches.size()) {
- if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1)
- return false;
-
- if (m_matches[idx].rm_eo == m_matches[idx].rm_so) {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- } else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) {
- match_str = s.substr(m_matches[idx].rm_so,
- m_matches[idx].rm_eo - m_matches[idx].rm_so);
- return true;
- }
- }
- return false;
-}
-
-bool RegularExpression::Match::GetMatchSpanningIndices(
- llvm::StringRef s, uint32_t idx1, uint32_t idx2,
- llvm::StringRef &match_str) const {
- if (idx1 < m_matches.size() && idx2 < m_matches.size()) {
- if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- } else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) {
- match_str = s.substr(m_matches[idx1].rm_so,
- m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
- return true;
- }
- }
- return false;
-}
+bool RegularExpression::IsValid() const { return m_regex.isValid(); }
-// Returns true if the regular expression compiled and is ready for execution.
-bool RegularExpression::IsValid() const { return m_comp_err == 0; }
-
-// Returns the text that was used to compile the current regular expression.
-llvm::StringRef RegularExpression::GetText() const { return m_re; }
-
-// Free any contained compiled regular expressions.
-void RegularExpression::Free() {
- if (m_comp_err == 0) {
- m_re.clear();
- regfree(&m_preg);
- // Set a compile error since we no longer have a valid regex
- m_comp_err = 1;
- }
-}
-
-size_t RegularExpression::GetErrorAsCString(char *err_str,
- size_t err_str_max_len) const {
- if (m_comp_err == 0) {
- if (err_str && err_str_max_len)
- *err_str = '\0';
- return 0;
- }
-
- return ::regerror(m_comp_err, &m_preg, err_str, err_str_max_len);
-}
+llvm::StringRef RegularExpression::GetText() const { return m_regex_text; }
-bool RegularExpression::operator<(const RegularExpression &rhs) const {
- return (m_re < rhs.m_re);
+llvm::Error RegularExpression::GetError() const {
+ std::string error;
+ if (!m_regex.isValid(error))
+ return llvm::make_error<llvm::StringError>(llvm::inconvertibleErrorCode(),
+ error);
+ return llvm::Error::success();
}
diff --git a/source/Utility/Reproducer.cpp b/source/Utility/Reproducer.cpp
index 479ed311d1de..4777d7576a32 100644
--- a/source/Utility/Reproducer.cpp
+++ b/source/Utility/Reproducer.cpp
@@ -136,7 +136,17 @@ FileSpec Reproducer::GetReproducerPath() const {
return {};
}
-Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {}
+static FileSpec MakeAbsolute(FileSpec file_spec) {
+ SmallString<128> path;
+ file_spec.GetPath(path, false);
+ llvm::sys::fs::make_absolute(path);
+ return FileSpec(path, file_spec.GetPathStyle());
+}
+
+Generator::Generator(FileSpec root)
+ : m_root(MakeAbsolute(std::move(root))), m_done(false) {
+ GetOrCreate<repro::WorkingDirectoryProvider>();
+}
Generator::~Generator() {}
@@ -175,8 +185,8 @@ void Generator::AddProvidersToIndex() {
index.AppendPathComponent("index.yaml");
std::error_code EC;
- auto strm = llvm::make_unique<raw_fd_ostream>(index.GetPath(), EC,
- sys::fs::OpenFlags::F_None);
+ auto strm = std::make_unique<raw_fd_ostream>(index.GetPath(), EC,
+ sys::fs::OpenFlags::OF_None);
yaml::Output yout(*strm);
std::vector<std::string> files;
@@ -188,7 +198,8 @@ void Generator::AddProvidersToIndex() {
yout << files;
}
-Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}
+Loader::Loader(FileSpec root)
+ : m_root(MakeAbsolute(std::move(root))), m_loaded(false) {}
llvm::Error Loader::LoadIndex() {
if (m_loaded)
@@ -223,7 +234,7 @@ bool Loader::HasFile(StringRef file) {
llvm::Expected<std::unique_ptr<DataRecorder>>
DataRecorder::Create(const FileSpec &filename) {
std::error_code ec;
- auto recorder = llvm::make_unique<DataRecorder>(std::move(filename), ec);
+ auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
if (ec)
return llvm::errorCodeToError(ec);
return std::move(recorder);
@@ -254,7 +265,7 @@ void CommandProvider::Keep() {
FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
if (ec)
return;
yaml::Output yout(os);
@@ -266,20 +277,78 @@ void CommandProvider::Discard() { m_data_recorders.clear(); }
void VersionProvider::Keep() {
FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
if (ec)
return;
os << m_version << "\n";
}
+void WorkingDirectoryProvider::Keep() {
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_cwd << "\n";
+}
+
+llvm::raw_ostream *ProcessGDBRemoteProvider::GetHistoryStream() {
+ FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
+
+ std::error_code EC;
+ m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
+ sys::fs::OpenFlags::OF_Text);
+ return m_stream_up.get();
+}
+
+std::unique_ptr<CommandLoader> CommandLoader::Create(Loader *loader) {
+ if (!loader)
+ return {};
+
+ FileSpec file = loader->GetFile<repro::CommandProvider::Info>();
+ if (!file)
+ return {};
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
+ if (auto err = error_or_file.getError())
+ return {};
+
+ std::vector<std::string> files;
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> files;
+
+ if (auto err = yin.error())
+ return {};
+
+ for (auto &file : files) {
+ FileSpec absolute_path =
+ loader->GetRoot().CopyByAppendingPathComponent(file);
+ file = absolute_path.GetPath();
+ }
+
+ return std::make_unique<CommandLoader>(std::move(files));
+}
+
+llvm::Optional<std::string> CommandLoader::GetNextFile() {
+ if (m_index >= m_files.size())
+ return {};
+ return m_files[m_index++];
+}
+
void ProviderBase::anchor() {}
-char ProviderBase::ID = 0;
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
+char ProcessGDBRemoteProvider::ID = 0;
+char ProviderBase::ID = 0;
char VersionProvider::ID = 0;
+char WorkingDirectoryProvider::ID = 0;
const char *CommandProvider::Info::file = "command-interpreter.yaml";
const char *CommandProvider::Info::name = "command-interpreter";
const char *FileProvider::Info::file = "files.yaml";
const char *FileProvider::Info::name = "files";
+const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
+const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
const char *VersionProvider::Info::file = "version.txt";
const char *VersionProvider::Info::name = "version";
+const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
+const char *WorkingDirectoryProvider::Info::name = "cwd";
diff --git a/source/Utility/Scalar.cpp b/source/Utility/Scalar.cpp
index 23d50b9eaba5..e9aec17b6650 100644
--- a/source/Utility/Scalar.cpp
+++ b/source/Utility/Scalar.cpp
@@ -416,6 +416,51 @@ Scalar &Scalar::operator=(llvm::APInt rhs) {
Scalar::~Scalar() = default;
+Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
+ // Scalar types are always host types, hence the sizeof().
+ if (sign) {
+ if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
+ if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
+ if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
+ if (bit_size <= 128) return Scalar::e_sint128;
+ if (bit_size <= 256) return Scalar::e_sint256;
+ if (bit_size <= 512) return Scalar::e_sint512;
+ } else {
+ if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
+ if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
+ if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
+ if (bit_size <= 128) return Scalar::e_uint128;
+ if (bit_size <= 256) return Scalar::e_uint256;
+ if (bit_size <= 512) return Scalar::e_uint512;
+ }
+ return Scalar::e_void;
+}
+
+void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) {
+ switch (type) {
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ case e_sint512:
+ m_integer = m_integer.sextOrTrunc(bits);
+ break;
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ case e_uint128:
+ case e_uint256:
+ case e_uint512:
+ m_integer = m_integer.zextOrTrunc(bits);
+ break;
+ default:
+ llvm_unreachable("Promoting a Scalar to a specific number of bits is only "
+ "supported for integer types.");
+ }
+ m_type = type;
+}
+
bool Scalar::Promote(Scalar::Type type) {
bool success = false;
switch (m_type) {
diff --git a/source/Utility/SelectHelper.cpp b/source/Utility/SelectHelper.cpp
index ff21d99e400a..9f5ca586e1ef 100644
--- a/source/Utility/SelectHelper.cpp
+++ b/source/Utility/SelectHelper.cpp
@@ -92,7 +92,7 @@ static void updateMaxFd(llvm::Optional<lldb::socket_t> &vold,
lldb_private::Status SelectHelper::Select() {
lldb_private::Status error;
-#ifdef _MSC_VER
+#ifdef _WIN32
// On windows FD_SETSIZE limits the number of file descriptors, not their
// numeric value.
lldbassert(m_fd_map.size() <= FD_SETSIZE);
@@ -107,7 +107,7 @@ lldb_private::Status SelectHelper::Select() {
for (auto &pair : m_fd_map) {
pair.second.PrepareForSelect();
const lldb::socket_t fd = pair.first;
-#if !defined(__APPLE__) && !defined(_MSC_VER)
+#if !defined(__APPLE__) && !defined(_WIN32)
lldbassert(fd < static_cast<int>(FD_SETSIZE));
if (fd >= static_cast<int>(FD_SETSIZE)) {
error.SetErrorStringWithFormat("%i is too large for select()", fd);
diff --git a/source/Utility/StreamGDBRemote.cpp b/source/Utility/StreamGDBRemote.cpp
deleted file mode 100644
index c710bbe3eecb..000000000000
--- a/source/Utility/StreamGDBRemote.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- StreamGDBRemote.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/Utility/StreamGDBRemote.h"
-
-#include "lldb/Utility/Flags.h"
-#include "lldb/Utility/Stream.h"
-
-#include <stdio.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-StreamGDBRemote::StreamGDBRemote() : StreamString() {}
-
-StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
- ByteOrder byte_order)
- : StreamString(flags, addr_size, byte_order) {}
-
-StreamGDBRemote::~StreamGDBRemote() {}
-
-int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
- int bytes_written = 0;
- const uint8_t *src = static_cast<const uint8_t *>(s);
- bool binary_is_set = m_flags.Test(eBinary);
- m_flags.Clear(eBinary);
- while (src_len) {
- uint8_t byte = *src;
- src++;
- src_len--;
- if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
- bytes_written += PutChar(0x7d);
- byte ^= 0x20;
- }
- bytes_written += PutChar(byte);
- };
- if (binary_is_set)
- m_flags.Set(eBinary);
- return bytes_written;
-}
diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
index 502f468da3cc..87fe4f13e450 100644
--- a/source/Utility/StringExtractor.cpp
+++ b/source/Utility/StringExtractor.cpp
@@ -296,34 +296,6 @@ size_t StringExtractor::GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest) {
return bytes_extracted;
}
-// Consume ASCII hex nibble character pairs until we have decoded byte_size
-// bytes of data.
-
-uint64_t StringExtractor::GetHexWithFixedSize(uint32_t byte_size,
- bool little_endian,
- uint64_t fail_value) {
- if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2) {
- uint64_t result = 0;
- uint32_t i;
- if (little_endian) {
- // Little Endian
- uint32_t shift_amount;
- for (i = 0, shift_amount = 0; i < byte_size && IsGood();
- ++i, shift_amount += 8) {
- result |= (static_cast<uint64_t>(GetHexU8()) << shift_amount);
- }
- } else {
- // Big Endian
- for (i = 0; i < byte_size && IsGood(); ++i) {
- result <<= 8;
- result |= GetHexU8();
- }
- }
- }
- m_index = UINT64_MAX;
- return fail_value;
-}
-
size_t StringExtractor::GetHexByteString(std::string &str) {
str.clear();
str.reserve(GetBytesLeft() / 2);
diff --git a/source/Utility/StringLexer.cpp b/source/Utility/StringLexer.cpp
index 958a9580db7a..c357cb0fb553 100644
--- a/source/Utility/StringLexer.cpp
+++ b/source/Utility/StringLexer.cpp
@@ -11,7 +11,7 @@
#include <algorithm>
#include <assert.h>
-using namespace lldb_utility;
+using namespace lldb_private;
StringLexer::StringLexer(std::string s) : m_data(s), m_position(0) {}
diff --git a/source/Utility/StringList.cpp b/source/Utility/StringList.cpp
index fb0d9be8797d..5e06b6b69fc0 100644
--- a/source/Utility/StringList.cpp
+++ b/source/Utility/StringList.cpp
@@ -61,10 +61,8 @@ void StringList::AppendList(const char **strv, int strc) {
}
void StringList::AppendList(StringList strings) {
- size_t len = strings.GetSize();
-
- for (size_t i = 0; i < len; ++i)
- m_strings.push_back(strings.GetStringAtIndex(i));
+ m_strings.reserve(m_strings.size() + strings.GetSize());
+ m_strings.insert(m_strings.end(), strings.begin(), strings.end());
}
size_t StringList::GetSize() const { return m_strings.size(); }
@@ -100,10 +98,9 @@ void StringList::Join(const char *separator, Stream &strm) {
void StringList::Clear() { m_strings.clear(); }
-void StringList::LongestCommonPrefix(std::string &common_prefix) {
- common_prefix.clear();
+std::string StringList::LongestCommonPrefix() {
if (m_strings.empty())
- return;
+ return {};
auto args = llvm::makeArrayRef(m_strings);
llvm::StringRef prefix = args.front();
@@ -115,7 +112,7 @@ void StringList::LongestCommonPrefix(std::string &common_prefix) {
}
prefix = prefix.take_front(count);
}
- common_prefix = prefix;
+ return prefix.str();
}
void StringList::InsertStringAtIndex(size_t idx, const char *str) {
@@ -226,29 +223,6 @@ StringList &StringList::operator=(const std::vector<std::string> &rhs) {
return *this;
}
-size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches,
- size_t &exact_idx) const {
- matches.Clear();
- exact_idx = SIZE_MAX;
- if (s.empty()) {
- // No string, so it matches everything
- matches = *this;
- return matches.GetSize();
- }
-
- const size_t s_len = s.size();
- const size_t num_strings = m_strings.size();
-
- for (size_t i = 0; i < num_strings; ++i) {
- if (m_strings[i].find(s) == 0) {
- if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
- exact_idx = matches.GetSize();
- matches.AppendString(m_strings[i]);
- }
- }
- return matches.GetSize();
-}
-
void StringList::LogDump(Log *log, const char *name) {
if (!log)
return;
diff --git a/source/Utility/StructuredData.cpp b/source/Utility/StructuredData.cpp
index 0e203f9739d1..783a08082174 100644
--- a/source/Utility/StructuredData.cpp
+++ b/source/Utility/StructuredData.cpp
@@ -9,9 +9,7 @@
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -21,11 +19,20 @@
#include <limits>
using namespace lldb_private;
+using namespace llvm;
-// Functions that use a JSONParser to parse JSON into StructuredData
-static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser);
+static StructuredData::ObjectSP ParseJSONValue(json::Value &value);
+static StructuredData::ObjectSP ParseJSONObject(json::Object *object);
+static StructuredData::ObjectSP ParseJSONArray(json::Array *array);
+
+StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
+ llvm::Expected<json::Value> value = json::parse(json_text);
+ if (!value) {
+ llvm::consumeError(value.takeError());
+ return nullptr;
+ }
+ return ParseJSONValue(*value);
+}
StructuredData::ObjectSP
StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
@@ -38,112 +45,53 @@ StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
buffer_or_error.getError().message());
return return_sp;
}
-
- JSONParser json_parser(buffer_or_error.get()->getBuffer());
- return_sp = ParseJSONValue(json_parser);
- return return_sp;
+ return ParseJSON(buffer_or_error.get()->getBuffer().str());
}
-static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- auto dict_up = llvm::make_unique<StructuredData::Dictionary>();
+static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
+ if (json::Object *O = value.getAsObject())
+ return ParseJSONObject(O);
- std::string value;
- std::string key;
- while (true) {
- JSONParser::Token token = json_parser.GetToken(value);
+ if (json::Array *A = value.getAsArray())
+ return ParseJSONArray(A);
- if (token == JSONParser::Token::String) {
- key.swap(value);
- token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Colon) {
- StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
- if (value_sp)
- dict_up->AddItem(key, value_sp);
- else
- break;
- }
- } else if (token == JSONParser::Token::ObjectEnd) {
- return StructuredData::ObjectSP(dict_up.release());
- } else if (token == JSONParser::Token::Comma) {
- continue;
- } else {
- break;
- }
- }
- return StructuredData::ObjectSP();
-}
+ std::string s;
+ if (json::fromJSON(value, s))
+ return std::make_shared<StructuredData::String>(s);
-static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- auto array_up = llvm::make_unique<StructuredData::Array>();
+ bool b;
+ if (json::fromJSON(value, b))
+ return std::make_shared<StructuredData::Boolean>(b);
- std::string value;
- std::string key;
- while (true) {
- StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
- if (value_sp)
- array_up->AddItem(value_sp);
- else
- break;
+ int64_t i;
+ if (json::fromJSON(value, i))
+ return std::make_shared<StructuredData::Integer>(i);
+
+ double d;
+ if (json::fromJSON(value, d))
+ return std::make_shared<StructuredData::Float>(d);
- JSONParser::Token token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Comma) {
- continue;
- } else if (token == JSONParser::Token::ArrayEnd) {
- return StructuredData::ObjectSP(array_up.release());
- } else {
- break;
- }
- }
return StructuredData::ObjectSP();
}
-static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) {
- std::string value;
- const JSONParser::Token token = json_parser.GetToken(value);
- switch (token) {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject(json_parser);
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray(json_parser);
-
- case JSONParser::Token::Integer: {
- uint64_t uval;
- if (llvm::to_integer(value, uval, 0))
- return std::make_shared<StructuredData::Integer>(uval);
- } break;
-
- case JSONParser::Token::Float: {
- double val;
- if (llvm::to_float(value, val))
- return std::make_shared<StructuredData::Float>(val);
- } break;
-
- case JSONParser::Token::String:
- return std::make_shared<StructuredData::String>(value);
-
- case JSONParser::Token::True:
- case JSONParser::Token::False:
- return std::make_shared<StructuredData::Boolean>(token ==
- JSONParser::Token::True);
-
- case JSONParser::Token::Null:
- return std::make_shared<StructuredData::Null>();
-
- default:
- break;
+static StructuredData::ObjectSP ParseJSONObject(json::Object *object) {
+ auto dict_up = std::make_unique<StructuredData::Dictionary>();
+ for (auto &KV : *object) {
+ StringRef key = KV.first;
+ json::Value value = KV.second;
+ if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
+ dict_up->AddItem(key, value_sp);
}
- return StructuredData::ObjectSP();
+ return dict_up;
}
-StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
- JSONParser json_parser(json_text);
- StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
- return object_sp;
+static StructuredData::ObjectSP ParseJSONArray(json::Array *array) {
+ auto array_up = std::make_unique<StructuredData::Array>();
+ for (json::Value &value : *array) {
+ if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
+ array_up->AddItem(value_sp);
+ }
+ return array_up;
}
StructuredData::ObjectSP
@@ -181,98 +129,48 @@ StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) {
}
void StructuredData::Object::DumpToStdout(bool pretty_print) const {
- StreamString stream;
- Dump(stream, pretty_print);
- llvm::outs() << stream.GetString();
+ json::OStream stream(llvm::outs(), pretty_print ? 2 : 0);
+ Serialize(stream);
}
-void StructuredData::Array::Dump(Stream &s, bool pretty_print) const {
- bool first = true;
- s << "[";
- if (pretty_print) {
- s << "\n";
- s.IndentMore();
- }
+void StructuredData::Array::Serialize(json::OStream &s) const {
+ s.arrayBegin();
for (const auto &item_sp : m_items) {
- if (first) {
- first = false;
- } else {
- s << ",";
- if (pretty_print)
- s << "\n";
- }
-
- if (pretty_print)
- s.Indent();
- item_sp->Dump(s, pretty_print);
- }
- if (pretty_print) {
- s.IndentLess();
- s.EOL();
- s.Indent();
+ item_sp->Serialize(s);
}
- s << "]";
+ s.arrayEnd();
}
-void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const {
- s.Printf("%" PRIu64, m_value);
+void StructuredData::Integer::Serialize(json::OStream &s) const {
+ s.value(static_cast<int64_t>(m_value));
}
-void StructuredData::Float::Dump(Stream &s, bool pretty_print) const {
- s.Printf("%lg", m_value);
+void StructuredData::Float::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const {
- if (m_value)
- s.PutCString("true");
- else
- s.PutCString("false");
+void StructuredData::Boolean::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::String::Dump(Stream &s, bool pretty_print) const {
- std::string quoted;
- const size_t strsize = m_value.size();
- for (size_t i = 0; i < strsize; ++i) {
- char ch = m_value[i];
- if (ch == '"' || ch == '\\')
- quoted.push_back('\\');
- quoted.push_back(ch);
- }
- s.Printf("\"%s\"", quoted.c_str());
+void StructuredData::String::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const {
- bool first = true;
- s << "{";
- if (pretty_print) {
- s << "\n";
- s.IndentMore();
- }
+void StructuredData::Dictionary::Serialize(json::OStream &s) const {
+ s.objectBegin();
for (const auto &pair : m_dict) {
- if (first)
- first = false;
- else {
- s << ",";
- if (pretty_print)
- s << "\n";
- }
- if (pretty_print)
- s.Indent();
- s << "\"" << pair.first.AsCString() << "\" : ";
- pair.second->Dump(s, pretty_print);
- }
- if (pretty_print) {
- s.IndentLess();
- s.EOL();
- s.Indent();
+ s.attributeBegin(pair.first.AsCString());
+ pair.second->Serialize(s);
+ s.attributeEnd();
}
- s << "}";
+ s.objectEnd();
}
-void StructuredData::Null::Dump(Stream &s, bool pretty_print) const {
- s << "null";
+void StructuredData::Null::Serialize(json::OStream &s) const {
+ s.value(nullptr);
}
-void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const {
- s << "0x" << m_object;
+void StructuredData::Generic::Serialize(json::OStream &s) const {
+ s.value(llvm::formatv("{0:X}", m_object));
}
diff --git a/tools/argdumper/argdumper.cpp b/tools/argdumper/argdumper.cpp
index 7fd8999c5dce..1cf0d6dae7a4 100644
--- a/tools/argdumper/argdumper.cpp
+++ b/tools/argdumper/argdumper.cpp
@@ -6,27 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Utility/JSON.h"
-#include "lldb/Utility/StreamString.h"
+#include "llvm/Support/JSON.h"
-#include <iostream>
-
-using namespace lldb_private;
+using namespace llvm;
int main(int argc, char *argv[]) {
- JSONArray::SP arguments(new JSONArray());
+ json::Array Arguments;
for (int i = 1; i < argc; i++) {
- arguments->AppendObject(JSONString::SP(new JSONString(argv[i])));
+ Arguments.push_back(argv[i]);
}
-
- JSONObject::SP object(new JSONObject());
- object->SetObject("arguments", arguments);
-
- StreamString ss;
-
- object->Write(ss);
-
- std::cout << ss.GetData() << std::endl;
-
+ llvm::outs() << json::Object({{"arguments", std::move(Arguments)}});
return 0;
}
diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c
index 570c42981a24..d4706eaf5386 100644
--- a/tools/compact-unwind/compact-unwind-dumper.c
+++ b/tools/compact-unwind/compact-unwind-dumper.c
@@ -1149,7 +1149,7 @@ void print_encoding(struct baton baton, uint8_t *function_start,
print_encoding_x86_64(baton, function_start, encoding);
} else if (baton.cputype == CPU_TYPE_I386) {
print_encoding_i386(baton, function_start, encoding);
- } else if (baton.cputype == CPU_TYPE_ARM64) {
+ } else if (baton.cputype == CPU_TYPE_ARM64 || baton.cputype == CPU_TYPE_ARM64_32) {
print_encoding_arm64(baton, function_start, encoding);
} else if (baton.cputype == CPU_TYPE_ARM) {
print_encoding_armv7(baton, function_start, encoding);
diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp
index 043aba7b07ba..6ab2bd93659f 100644
--- a/tools/driver/Driver.cpp
+++ b/tools/driver/Driver.cpp
@@ -11,6 +11,7 @@
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBReproducer.h"
@@ -18,8 +19,8 @@
#include "lldb/API/SBStringList.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
@@ -229,6 +230,7 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
if (args.hasArg(OPT_no_use_colors)) {
m_debugger.SetUseColor(false);
+ m_option_data.m_debug_mode = true;
}
if (auto *arg = args.getLastArg(OPT_file)) {
@@ -262,14 +264,6 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
m_debugger.SetScriptLanguage(m_debugger.GetScriptingLanguage(arg_value));
}
- if (args.hasArg(OPT_no_use_colors)) {
- m_option_data.m_debug_mode = true;
- }
-
- if (args.hasArg(OPT_no_use_colors)) {
- m_debugger.SetUseColor(false);
- }
-
if (args.hasArg(OPT_source_quietly)) {
m_option_data.m_source_quietly = true;
}
@@ -506,16 +500,16 @@ int Driver::MainLoop() {
SBCommandReturnObject result;
sb_interpreter.SourceInitFileInHomeDirectory(result);
if (m_option_data.m_debug_mode) {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
}
// Source the local .lldbinit file if it exists and we're allowed to source.
// Here we want to always print the return object because it contains the
// warning and instructions to load local lldbinit files.
sb_interpreter.SourceInitFileInCurrentWorkingDirectory(result);
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
// We allow the user to specify an exit code when calling quit which we will
// return when exiting.
@@ -581,8 +575,8 @@ int Driver::MainLoop() {
}
if (m_option_data.m_debug_mode) {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
}
const bool handle_events = true;
@@ -813,23 +807,9 @@ llvm::Optional<int> InitializeReproducer(opt::InputArgList &input_args) {
return llvm::None;
}
-int
-#ifdef _MSC_VER
-wmain(int argc, wchar_t const *wargv[])
-#else
-main(int argc, char const *argv[])
-#endif
+int main(int argc, char const *argv[])
{
-#ifdef _MSC_VER
- // Convert wide arguments to UTF-8
- std::vector<std::string> argvStrings(argc);
- std::vector<const char *> argvPointers(argc);
- for (int i = 0; i != argc; ++i) {
- llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
- argvPointers[i] = argvStrings[i].c_str();
- }
- const char **argv = argvPointers.data();
-#endif
+ llvm::InitLLVM IL(argc, argv);
// Print stack trace on crash.
llvm::StringRef ToolName = llvm::sys::path::filename(argv[0]);
@@ -873,6 +853,16 @@ main(int argc, char const *argv[])
signal(SIGCONT, sigcont_handler);
#endif
+ // Occasionally, during test teardown, LLDB writes to a closed pipe.
+ // Sometimes the communication is inherently unreliable, so LLDB tries to
+ // avoid being killed due to SIGPIPE. However, LLVM's default SIGPIPE behavior
+ // is to exit with IO_ERR. Opt LLDB out of that.
+ //
+ // We don't disable LLVM's signal handling entirely because we still want
+ // pretty stack traces, and file cleanup (for when, say, the clang embedded
+ // in LLDB leaves behind temporary objects).
+ llvm::sys::SetPipeSignalFunction(nullptr);
+
int exit_code = 0;
// Create a scope for driver so that the driver object will destroy itself
// before SBDebugger::Terminate() is called.
diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h
index 064491503e0c..cf6c4ec8e146 100644
--- a/tools/driver/Platform.h
+++ b/tools/driver/Platform.h
@@ -9,12 +9,17 @@
#ifndef lldb_Platform_h_
#define lldb_Platform_h_
+#include "lldb/Host/Config.h"
+
#if defined(_WIN32)
#include <io.h>
#if defined(_MSC_VER)
#include <signal.h>
#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
#include "lldb/Host/windows/windows.h"
#include <inttypes.h>
diff --git a/tools/lldb-instr/Instrument.cpp b/tools/lldb-instr/Instrument.cpp
index f30707c22b04..9b2970030cb0 100644
--- a/tools/lldb-instr/Instrument.cpp
+++ b/tools/lldb-instr/Instrument.cpp
@@ -335,7 +335,7 @@ public:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef File) override {
MyRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
- return llvm::make_unique<SBConsumer>(MyRewriter, CI.getASTContext());
+ return std::make_unique<SBConsumer>(MyRewriter, CI.getASTContext());
}
private:
@@ -348,8 +348,8 @@ int main(int argc, const char **argv) {
"instrumentation framework.");
auto PCHOpts = std::make_shared<PCHContainerOperations>();
- PCHOpts->registerWriter(llvm::make_unique<ObjectFilePCHContainerWriter>());
- PCHOpts->registerReader(llvm::make_unique<ObjectFilePCHContainerReader>());
+ PCHOpts->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
+ PCHOpts->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
ClangTool T(OP.getCompilations(), OP.getSourcePathList(), PCHOpts);
return T.run(newFrontendActionFactory<SBAction>().get());
diff --git a/tools/lldb-mi/MICmdArgContext.cpp b/tools/lldb-mi/MICmdArgContext.cpp
deleted file mode 100644
index 18da5b5d67a3..000000000000
--- a/tools/lldb-mi/MICmdArgContext.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-//===-- MICmdArgContext.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgContext constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgContext::CMICmdArgContext() {}
-
-//++
-// Details: CMICmdArgContext constructor.
-// Type: Method.
-// Args: vrCmdLineArgsRaw - (R) The text description of the arguments
-// options.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgContext::CMICmdArgContext(const CMIUtilString &vrCmdLineArgsRaw)
- : m_strCmdArgsAndOptions(vrCmdLineArgsRaw) {}
-
-//++
-// Details: CMICmdArgContext destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgContext::~CMICmdArgContext() {}
-
-//++
-// Details: Retrieve the remainder of the command's argument options left to
-// parse.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Argument options text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdArgContext::GetArgsLeftToParse() const {
- return m_strCmdArgsAndOptions;
-}
-
-//++
-// Details: Ask if this arguments string has any arguments.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Has one or more arguments present, false = no
-// arguments.
-// Throws: None.
-//--
-bool CMICmdArgContext::IsEmpty() const {
- return m_strCmdArgsAndOptions.empty();
-}
-
-//++
-// Details: Remove the argument from the options text and any space after the
-// argument
-// if applicable.
-// Type: Method.
-// Args: vArg - (R) The name of the argument.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgContext::RemoveArg(const CMIUtilString &vArg) {
- if (vArg.empty())
- return MIstatus::success;
-
- const size_t nLen = vArg.length();
- const size_t nLenCntxt = m_strCmdArgsAndOptions.length();
- if (nLen > nLenCntxt)
- return MIstatus::failure;
-
- size_t nExtraSpace = 0;
- size_t nPos = m_strCmdArgsAndOptions.find(vArg);
- while (1) {
- if (nPos == std::string::npos)
- return MIstatus::success;
-
- bool bPass1 = false;
- if (nPos != 0) {
- if (m_strCmdArgsAndOptions[nPos - 1] == ' ')
- bPass1 = true;
- } else
- bPass1 = true;
-
- const size_t nEnd = nPos + nLen;
-
- if (bPass1) {
- bool bPass2 = false;
- if (nEnd < nLenCntxt) {
- if (m_strCmdArgsAndOptions[nEnd] == ' ') {
- bPass2 = true;
- nExtraSpace = 1;
- }
- } else
- bPass2 = true;
-
- if (bPass2)
- break;
- }
-
- nPos = m_strCmdArgsAndOptions.find(vArg, nEnd);
- }
-
- const size_t nPosEnd = nLen + nExtraSpace;
- m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.replace(nPos, nPosEnd, "");
- m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Remove the argument at the Nth word position along in the context
-// string.
-// Any space after the argument is removed if applicable. A search is
-// not
-// performed as there may be more than one vArg with the same 'name' in
-// the
-// context string.
-// Type: Method.
-// Args: vArg - (R) The name of the argument.
-// nArgIndex - (R) The word count position to which to remove the
-// vArg word.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgContext::RemoveArgAtPos(const CMIUtilString &vArg,
- size_t nArgIndex) {
- size_t nWordIndex = 0;
- CMIUtilString strBuildContextUp;
- const CMIUtilString::VecString_t vecWords(GetArgs());
- const bool bSpaceRequired(GetNumberArgsPresent() > 2);
-
- CMIUtilString::VecString_t::const_iterator it = vecWords.begin();
- const CMIUtilString::VecString_t::const_iterator itEnd = vecWords.end();
- while (it != itEnd) {
- const CMIUtilString &rWord(*it);
- if (nWordIndex++ != nArgIndex) {
- // Single words
- strBuildContextUp += rWord;
- if (bSpaceRequired)
- strBuildContextUp += " ";
- } else {
- // If quoted loose quoted text
- if (++it != itEnd) {
- CMIUtilString words = rWord;
- while (vArg != words) {
- if (bSpaceRequired)
- words += " ";
- words += *it;
- if (++it == itEnd)
- break;
- }
- if (it != itEnd)
- --it;
- }
- }
-
- // Next
- if (it != itEnd)
- ++it;
- }
-
- m_strCmdArgsAndOptions = strBuildContextUp;
- m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve number of arguments or options present in the command's
-// option text.
-// Type: Method.
-// Args: None.
-// Return: size_t - 0 to n arguments present.
-// Throws: None.
-//--
-size_t CMICmdArgContext::GetNumberArgsPresent() const {
- CMIUtilString::VecString_t vecOptions;
- return m_strCmdArgsAndOptions.SplitConsiderQuotes(" ", vecOptions);
-}
-
-//++
-// Details: Retrieve all the arguments or options remaining in *this context.
-// Type: Method.
-// Args: None.
-// Return: MIUtilString::VecString_t - List of args remaining.
-// Throws: None.
-//--
-CMIUtilString::VecString_t CMICmdArgContext::GetArgs() const {
- CMIUtilString::VecString_t vecOptions;
- m_strCmdArgsAndOptions.SplitConsiderQuotes(" ", vecOptions);
- return vecOptions;
-}
-
-//++
-// Details: Copy assignment operator.
-// Type: Method.
-// Args: vOther - (R) The variable to copy from.
-// Return: CMIUtilString & - this object.
-// Throws: None.
-//--
-CMICmdArgContext &CMICmdArgContext::operator=(const CMICmdArgContext &vOther) {
- if (this != &vOther) {
- m_strCmdArgsAndOptions = vOther.m_strCmdArgsAndOptions;
- }
-
- return *this;
-}
diff --git a/tools/lldb-mi/MICmdArgContext.h b/tools/lldb-mi/MICmdArgContext.h
deleted file mode 100644
index 801d2d90cdc5..000000000000
--- a/tools/lldb-mi/MICmdArgContext.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- MICmdArgContext.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code class. Command arguments and options string. Holds
-// the context string.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgContext {
- // Methods:
-public:
- /* ctor */ CMICmdArgContext();
- /* ctor */ CMICmdArgContext(const CMIUtilString &vrCmdLineArgsRaw);
- //
- const CMIUtilString &GetArgsLeftToParse() const;
- size_t GetNumberArgsPresent() const;
- CMIUtilString::VecString_t GetArgs() const;
- bool IsEmpty() const;
- bool RemoveArg(const CMIUtilString &vArg);
- bool RemoveArgAtPos(const CMIUtilString &vArg, size_t nArgIndex);
- //
- CMICmdArgContext &operator=(const CMICmdArgContext &vOther);
-
- // Overridden:
-public:
- // From CMIUtilString
- /* dtor */ virtual ~CMICmdArgContext();
-
- // Attributes:
-private:
- CMIUtilString m_strCmdArgsAndOptions;
-};
diff --git a/tools/lldb-mi/MICmdArgSet.cpp b/tools/lldb-mi/MICmdArgSet.cpp
deleted file mode 100644
index 0d67c03bfeae..000000000000
--- a/tools/lldb-mi/MICmdArgSet.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-//===-- MICmdArgSet.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgSet.h"
-#include "MICmdArgValBase.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMICmdArgSet constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgSet::CMICmdArgSet()
- : m_bIsArgsPresentButNotHandledByCmd(false), m_constStrCommaSpc(", ") {}
-
-//++
-// Details: CMICmdArgSet destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgSet::~CMICmdArgSet() {
- // Tidy up
- Destroy();
-}
-
-//++
-// Details: Release resources used by *this container object.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdArgSet::Destroy() {
- // Delete command argument objects
- if (!m_setCmdArgs.empty()) {
- SetCmdArgs_t::iterator it = m_setCmdArgs.begin();
- while (it != m_setCmdArgs.end()) {
- CMICmdArgValBase *pArg(*it);
- delete pArg;
-
- // Next
- ++it;
- }
- m_setCmdArgs.clear();
- }
-
- m_setCmdArgsThatNotValid.clear();
- m_setCmdArgsThatAreMissing.clear();
- m_setCmdArgsNotHandledByCmd.clear();
- m_setCmdArgsMissingInfo.clear();
- m_bIsArgsPresentButNotHandledByCmd = false;
-}
-
-//++
-// Details: Retrieve the state flag indicating that the command set up ready to
-// parse
-// command arguments or options found that one or more arguments was
-// indeed
-// present but not handled. This is given as a warning in the MI log
-// file.
-// Type: Method.
-// Args: None.
-// Return: bool - True = one or more args not handled, false = all args handled
-// Throws: None.
-//--
-bool CMICmdArgSet::IsArgsPresentButNotHandledByCmd() const {
- return m_bIsArgsPresentButNotHandledByCmd;
-}
-
-//++
-// Details: Add the list of command's arguments to parse and validate another
-// one.
-// Type: Method.
-// Args: vArg - (R) A command argument object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdArgSet::Add(CMICmdArgValBase *vArg) { m_setCmdArgs.push_back(vArg); }
-
-//++
-// Details: After validating an options line of text (the context) and there is
-// a failure,
-// it is likely a mandatory command argument that is required is
-// missing. This
-// function returns the argument that should be present.
-// Type: Method.
-// Args: None.
-// Return: SetCmdArgs_t & - Set of argument objects.
-// Throws: None.
-//--
-const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsThatAreMissing() const {
- return m_setCmdArgsThatAreMissing;
-}
-
-//++
-// Details: After validating an options line of text (the context) and there is
-// a failure,
-// it may be because one or more arguments were unable to extract a
-// value. This
-// function returns the argument that were found to be invalid.
-// Type: Method.
-// Args: None.
-// Return: SetCmdArgs_t & - Set of argument objects.
-// Throws: None.
-//--
-const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsThatInvalid() const {
- return m_setCmdArgsThatNotValid;
-}
-
-//++
-// Details: The list of argument or option (objects) that were specified by the
-// command
-// and so recognised when parsed but were not handled. Ideally the
-// command
-// should handle all arguments and options presented to it. The command
-// sends
-// warning to the MI log file to say that these options were not
-// handled.
-// Used as one way to determine option that maybe should really be
-// implemented
-// and not just ignored.
-// Type: Method.
-// Args: None.
-// Return: SetCmdArgs_t & - Set of argument objects.
-// Throws: None.
-//--
-const CMICmdArgSet::SetCmdArgs_t &CMICmdArgSet::GetArgsNotHandledByCmd() const {
- return m_setCmdArgsNotHandledByCmd;
-}
-
-//++
-// Details: Given a set of command argument objects parse the context option
-// string to
-// find those argument and retrieve their value. If the function fails
-// call
-// GetArgsThatAreMissing() to see which commands that were mandatory
-// were
-// missing or failed to parse.
-// Type: Method.
-// Args: vStrMiCmd - (R) Command's name.
-// vCmdArgsText - (RW) A command's options or argument.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgSet::Validate(const CMIUtilString &vStrMiCmd,
- CMICmdArgContext &vwCmdArgsText) {
- m_cmdArgContext = vwCmdArgsText;
-
- // Iterate all the arguments or options required by a command
- SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
- while (it != m_setCmdArgs.end()) {
- CMICmdArgValBase *pArg = *it;
-
- if (!pArg->Validate(vwCmdArgsText)) {
- if (pArg->GetFound()) {
- if (pArg->GetIsMissingOptions())
- m_setCmdArgsMissingInfo.push_back(pArg);
- else if (!pArg->GetValid())
- m_setCmdArgsThatNotValid.push_back(pArg);
- } else if (pArg->GetIsMandatory())
- m_setCmdArgsThatAreMissing.push_back(pArg);
- }
-
- if (pArg->GetFound() && !pArg->GetIsHandledByCmd()) {
- m_bIsArgsPresentButNotHandledByCmd = true;
- m_setCmdArgsNotHandledByCmd.push_back(pArg);
- }
-
- // Next
- ++it;
- }
-
- // report any issues with arguments/options
- if (IsArgsPresentButNotHandledByCmd())
- WarningArgsNotHandledbyCmdLogFile(vStrMiCmd);
-
- return ValidationFormErrorMessages(vwCmdArgsText);
-}
-
-//++
-// Details: Having validated the command's options text and failed for some
-// reason form
-// the error message made up with the faults found.
-// Type: Method.
-// vCmdArgsText - (RW) A command's options or argument.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgSet::ValidationFormErrorMessages(
- const CMICmdArgContext &vwCmdArgsText) {
- CMIUtilString strListMissing;
- CMIUtilString strListInvalid;
- CMIUtilString strListMissingInfo;
- const bool bArgsMissing = (m_setCmdArgsThatAreMissing.size() > 0);
- const bool bArgsInvalid = (m_setCmdArgsThatNotValid.size() > 0);
- const bool bArgsMissingInfo = (m_setCmdArgsMissingInfo.size() > 0);
- if (!(bArgsMissing || bArgsInvalid || bArgsMissingInfo))
- return MIstatus::success;
- if (bArgsMissing) {
- MIuint i = 0;
- SetCmdArgs_t::const_iterator it = m_setCmdArgsThatAreMissing.begin();
- while (it != m_setCmdArgsThatAreMissing.end()) {
- if (i++ > 0)
- strListMissing += m_constStrCommaSpc;
-
- const CMICmdArgValBase *pArg(*it);
- strListMissing += pArg->GetName();
-
- // Next
- ++it;
- }
- }
- if (bArgsInvalid) {
- MIuint i = 0;
- SetCmdArgs_t::const_iterator it = m_setCmdArgsThatNotValid.begin();
- while (it != m_setCmdArgsThatNotValid.end()) {
- if (i++ > 0)
- strListMissing += m_constStrCommaSpc;
-
- const CMICmdArgValBase *pArg(*it);
- strListInvalid += pArg->GetName();
-
- // Next
- ++it;
- }
- }
- if (bArgsMissingInfo) {
- MIuint i = 0;
- SetCmdArgs_t::const_iterator it = m_setCmdArgsMissingInfo.begin();
- while (it != m_setCmdArgsMissingInfo.end()) {
- if (i++ > 0)
- strListMissingInfo += m_constStrCommaSpc;
-
- const CMICmdArgValBase *pArg(*it);
- strListMissingInfo += pArg->GetName();
-
- // Next
- ++it;
- }
- }
-
- bool bHaveOneError = false;
- CMIUtilString strError = MIRSRC(IDS_CMD_ARGS_ERR_PREFIX_MSG);
- if (bArgsMissing && bArgsInvalid) {
- bHaveOneError = true;
- strError +=
- CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID),
- strListMissing.c_str(), strListInvalid.c_str());
- }
- if (bArgsMissing) {
- if (bHaveOneError)
- strError += ". ";
- bHaveOneError = true;
- strError += CMIUtilString::Format(
- MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY), strListMissing.c_str());
- }
- if (bArgsMissingInfo) {
- if (bHaveOneError)
- strError += ". ";
- bHaveOneError = true;
- strError +=
- CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF),
- strListMissingInfo.c_str());
- }
- if (bArgsInvalid) {
- if (bHaveOneError)
- strError += ". ";
- bHaveOneError = true;
- strError += CMIUtilString::Format(
- MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID), strListInvalid.c_str());
- }
- if (!vwCmdArgsText.IsEmpty()) {
- if (bHaveOneError)
- strError += ". ";
- bHaveOneError = true;
- strError +=
- CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN),
- vwCmdArgsText.GetArgsLeftToParse().c_str());
- }
-
- if (bHaveOneError) {
- SetErrorDescription(strError);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Ask if the command's argument options text had any arguments.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Has one or more arguments present, false = no
-// arguments.
-// Throws: None.
-//--
-bool CMICmdArgSet::IsArgContextEmpty() const {
- return m_cmdArgContext.IsEmpty();
-}
-
-//++
-// Details: Retrieve the number of arguments that are being used for the
-// command.
-// Type: Method.
-// Args: None.
-// Return: size_t - Argument count.
-// Throws: None.
-//--
-size_t CMICmdArgSet::GetCount() const { return m_setCmdArgs.size(); }
-
-//++
-// Details: Given a set of command argument objects retrieve the argument with
-// the
-// specified name.
-// Type: Method.
-// Args: vpArg - (W) A pointer to a command's argument object.
-// Return: True - Argument found.
-// False - Argument not found.
-// Throws: None.
-//--
-bool CMICmdArgSet::GetArg(const CMIUtilString &vArgName,
- CMICmdArgValBase *&vpArg) const {
- bool bFound = false;
- SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
- while (it != m_setCmdArgs.end()) {
- CMICmdArgValBase *pArg(*it);
- if (pArg->GetName() == vArgName) {
- bFound = true;
- vpArg = pArg;
- break;
- }
-
- // Next
- ++it;
- }
-
- return bFound;
-}
-
-//++
-// Details: Write a warning message to the MI Log file about the command's
-// arguments or
-// options that were found present but not handled.
-// Type: Method.
-// Args: vrCmdName - (R) The command's name.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdArgSet::WarningArgsNotHandledbyCmdLogFile(
- const CMIUtilString &vrCmdName) {
-#if MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
-
- CMIUtilString strArgsNotHandled;
- const CMICmdArgSet::SetCmdArgs_t &rSetArgs = GetArgsNotHandledByCmd();
- MIuint nCnt = 0;
- CMICmdArgSet::SetCmdArgs_t::const_iterator it = rSetArgs.begin();
- while (it != rSetArgs.end()) {
- if (nCnt++ > 0)
- strArgsNotHandled += m_constStrCommaSpc;
- const CMICmdArgValBase *pArg = *it;
- strArgsNotHandled += pArg->GetName();
-
- // Next
- ++it;
- }
-
- const CMIUtilString strWarningMsg(
- CMIUtilString::Format(MIRSRC(IDS_CMD_WRN_ARGS_NOT_HANDLED),
- vrCmdName.c_str(), strArgsNotHandled.c_str()));
- m_pLog->WriteLog(strWarningMsg);
-
-#endif // MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
-}
diff --git a/tools/lldb-mi/MICmdArgSet.h b/tools/lldb-mi/MICmdArgSet.h
deleted file mode 100644
index 4df5aaf51567..000000000000
--- a/tools/lldb-mi/MICmdArgSet.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- MICmdArgSet.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-#include <vector>
-
-#include "MICmdArgContext.h"
-#include "MICmnBase.h"
-
-// Declarations:
-class CMICmdArgValBase;
-
-//++
-//============================================================================
-// Details: MI common code class. Command arguments container class.
-// A command may have one or more arguments of which some may be
-// optional.
-// *this class contains a list of the command's arguments which are
-// validates against the commands argument options string (context
-// string).
-// Each argument tries to extract the value it is looking for.
-// Argument objects added to *this container are owned by this
-// container
-// and are deleted when this container goes out of scope. Allocate
-// argument
-// objects on the heap.
-// It is assumed the arguments to be parsed are read from left to right
-// in
-// order. The order added to *this container is the order they will
-// parsed.
-//--
-class CMICmdArgSet : public CMICmnBase {
- // Classes:
-public:
- //++
- // Description: ArgSet's interface for command arguments to implement.
- //--
- class IArg {
- public:
- virtual bool GetFound() const = 0;
- virtual bool GetIsHandledByCmd() const = 0;
- virtual bool GetIsMandatory() const = 0;
- virtual bool GetIsMissingOptions() const = 0;
- virtual const CMIUtilString &GetName() const = 0;
- virtual bool GetValid() const = 0;
- virtual bool Validate(CMICmdArgContext &vwArgContext) = 0;
-
- virtual ~IArg() = default;
- };
-
- // Typedefs:
- typedef std::vector<CMICmdArgValBase *> SetCmdArgs_t;
-
- // Methods:
- CMICmdArgSet();
-
- void Add(CMICmdArgValBase *vArg);
- bool GetArg(const CMIUtilString &vArgName, CMICmdArgValBase *&vpArg) const;
- const SetCmdArgs_t &GetArgsThatAreMissing() const;
- const SetCmdArgs_t &GetArgsThatInvalid() const;
- size_t GetCount() const;
- bool IsArgContextEmpty() const;
- bool IsArgsPresentButNotHandledByCmd() const;
- void WarningArgsNotHandledbyCmdLogFile(const CMIUtilString &vrCmdName);
- bool Validate(const CMIUtilString &vStrMiCmd,
- CMICmdArgContext &vwCmdArgsText);
-
- // Overrideable:
- ~CMICmdArgSet() override;
-
- // Methods:
-private:
- const SetCmdArgs_t &GetArgsNotHandledByCmd() const;
- void Destroy(); // Release resources used by *this object
- bool ValidationFormErrorMessages(const CMICmdArgContext &vwCmdArgsText);
-
- // Attributes:
- bool m_bIsArgsPresentButNotHandledByCmd; // True = The driver's client
- // presented the command with options
- // recognised but not handled by
- // a command, false = all args handled
- SetCmdArgs_t m_setCmdArgs; // The set of arguments that are that the command
- // is expecting to find in the options string
- SetCmdArgs_t m_setCmdArgsThatAreMissing; // The set of arguments that are
- // required by the command but are
- // missing
- SetCmdArgs_t m_setCmdArgsThatNotValid; // The set of arguments found in the
- // text but for some reason unable to
- // extract a value
- SetCmdArgs_t m_setCmdArgsNotHandledByCmd; // The set of arguments specified by
- // the command which were present to
- // the command but not handled
- SetCmdArgs_t m_setCmdArgsMissingInfo; // The set of arguments that were
- // present but were found to be missing
- // additional information i.e.
- // --thread 3 but 3 is missing
- CMICmdArgContext m_cmdArgContext; // Copy of the command's argument options
- // text before validate takes place (empties
- // it of content)
- const CMIUtilString m_constStrCommaSpc;
-};
diff --git a/tools/lldb-mi/MICmdArgValBase.cpp b/tools/lldb-mi/MICmdArgValBase.cpp
deleted file mode 100644
index dc9c7e0257e7..000000000000
--- a/tools/lldb-mi/MICmdArgValBase.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- MICmdArgValBase.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 "MICmdArgValBase.h"
-#include "MICmdArgContext.h"
-#include "MIUtilString.h"
-
-//++
-// Details: CMICmdArgValBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValBase::CMICmdArgValBase()
- : m_bFound(false), m_bValid(false), m_bMandatory(false), m_bHandled(false),
- m_bIsMissingOptions(false) {}
-
-//++
-// Details: CMICmdArgValBase constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValBase::CMICmdArgValBase(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : m_bFound(false), m_bValid(false), m_bMandatory(vbMandatory),
- m_strArgName(vrArgName), m_bHandled(vbHandleByCmd),
- m_bIsMissingOptions(false) {}
-
-//++
-// Details: Retrieve the state flag of whether the argument is handled by the
-// command or
-// not.
-// Type: Method.
-// Args: None.
-// Return: True - Command needs more information.
-// False - All information is present as expected.
-// Throws: None.
-//--
-bool CMICmdArgValBase::GetIsMissingOptions() const {
- return m_bIsMissingOptions;
-}
-
-//++
-// Details: Retrieve the state flag of whether the argument is handled by the
-// command or
-// not.
-// Type: Method.
-// Args: None.
-// Return: True - Command handles *this argument or option.
-// False - Not handled (argument specified but ignored).
-// Throws: None.
-//--
-bool CMICmdArgValBase::GetIsHandledByCmd() const { return m_bHandled; }
-
-//++
-// Details: Retrieve the name of *this argument.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Return the text name.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdArgValBase::GetName() const { return m_strArgName; }
-
-//++
-// Details: Retrieve the state flag of whether the argument was found in the
-// command's
-// argument / options string.
-// Type: Method.
-// Args: None.
-// Return: True - Argument found.
-// False - Argument not found.
-// Throws: None.
-//--
-bool CMICmdArgValBase::GetFound() const { return m_bFound; }
-
-//++
-// Details: Retrieve the state flag indicating whether the value was obtained
-// from the
-// text arguments string and is valid.
-// Type: Method.
-// Args: None.
-// Return: True - Argument valid.
-// False - Argument not valid.
-// Throws: None.
-//--
-bool CMICmdArgValBase::GetValid() const { return m_bValid; }
-
-//++
-// Details: Retrieve the state flag indicating whether *this argument is a
-// mandatory
-// argument for the command or is optional to be present.
-// Type: Method.
-// Args: None.
-// Return: True - Mandatory.
-// False - Optional.
-// Throws: None.
-//--
-bool CMICmdArgValBase::GetIsMandatory() const { return m_bMandatory; }
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overrideable.
-// Args: vArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValBase::Validate(CMICmdArgContext &vwArgContext) {
- MIunused(vwArgContext);
-
- // Override to implement
-
- return MIstatus::failure;
-}
diff --git a/tools/lldb-mi/MICmdArgValBase.h b/tools/lldb-mi/MICmdArgValBase.h
deleted file mode 100644
index feb7fe4f04d3..000000000000
--- a/tools/lldb-mi/MICmdArgValBase.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- MICmdArgValBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-#include "MICmdArgSet.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument base class. Arguments objects
-// needing specialization derived from *this class. An argument knows
-// what type of argument it is and how it is to interpret the options
-// (context) string to find and validate a matching argument and so
-// extract a value from it.
-// Argument objects are added to the CMICmdArgSet container object.
-// Once added the container they belong to that contain and will be
-// deleted when the container goes out of scope. Allocate argument
-// objects on the heap and pass in to the Add().
-// Note the code is written such that a command will produce an error
-// should it be presented with arguments or options it does not
-// understand.
-// A command can recognise an option or argument then ignore if it
-// wishes (a warning is sent to the MI's Log file). This is so it is
-// hardwired to fail and catch arguments or options that presented by
-// different driver clients.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValBase : public CMICmdArgSet::IArg {
- // Methods:
-public:
- CMICmdArgValBase();
- CMICmdArgValBase(const CMIUtilString &vrArgName, const bool vbMandatory,
- const bool vbHandleByCmd);
-
- // Overrideable:
- ~CMICmdArgValBase() override = default;
-
- // Overridden:
- // From CMICmdArgSet::IArg
- bool GetFound() const override;
- bool GetIsHandledByCmd() const override;
- bool GetIsMandatory() const override;
- bool GetIsMissingOptions() const override;
- const CMIUtilString &GetName() const override;
- bool GetValid() const override;
- bool Validate(CMICmdArgContext &vwArgContext) override;
-
- // Attributes:
-protected:
- bool
- m_bFound; // True = yes found in arguments options text, false = not found
- bool m_bValid; // True = yes argument parsed and valid, false = not valid
- bool
- m_bMandatory; // True = yes arg must be present, false = optional argument
- CMIUtilString m_strArgName;
- bool m_bHandled; // True = Command processes *this option, false = not handled
- bool m_bIsMissingOptions; // True = Command needs more information, false = ok
-};
-
-//++
-//============================================================================
-// Details: MI common code class. Templated command argument base class.
-//--
-template <class T> class CMICmdArgValBaseTemplate : public CMICmdArgValBase {
- // Methods:
-public:
- CMICmdArgValBaseTemplate() = default;
- CMICmdArgValBaseTemplate(const CMIUtilString &vrArgName,
- const bool vbMandatory, const bool vbHandleByCmd);
- //
- const T &GetValue() const;
-
- // Overrideable:
- ~CMICmdArgValBaseTemplate() override = default;
-
- // Attributes:
-protected:
- T m_argValue;
-};
-
-//++
-// Details: CMICmdArgValBaseTemplate constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-template <class T>
-CMICmdArgValBaseTemplate<T>::CMICmdArgValBaseTemplate(
- const CMIUtilString &vrArgName, const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValBase(vrArgName, vbMandatory, vbHandleByCmd) {}
-
-//++
-// Details: Retrieve the value the argument parsed from the command's argument /
-// options
-// text string.
-// Type: Method.
-// Args: None.
-// Return: Template type & - The arg value of *this object.
-// Throws: None.
-//--
-template <class T> const T &CMICmdArgValBaseTemplate<T>::GetValue() const {
- return m_argValue;
-}
diff --git a/tools/lldb-mi/MICmdArgValConsume.cpp b/tools/lldb-mi/MICmdArgValConsume.cpp
deleted file mode 100644
index 01d001366596..000000000000
--- a/tools/lldb-mi/MICmdArgValConsume.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- MICmdArgValConsume.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValConsume.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValConsume constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValConsume::CMICmdArgValConsume() {}
-
-//++
-// Details: CMICmdArgValConsume constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValConsume::CMICmdArgValConsume(const CMIUtilString &vrArgName,
- const bool vbMandatory)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, true) {}
-
-//++
-// Details: CMICmdArgValConsume destructor.
-// Type: Overidden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValConsume::~CMICmdArgValConsume() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (R) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValConsume::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- // Consume the optional file, line, linenum arguments till the mode '--'
- // argument
- const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rTxt(*it);
-
- if (rTxt == "--") {
- m_bFound = true;
- m_bValid = true;
- if (!vwArgContext.RemoveArg(rTxt))
- return MIstatus::failure;
- return MIstatus::success;
- }
- // Next
- ++it;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Nothing to examine as we just want to consume the argument or option
-// (ignore
-// it).
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes ok, false = not ok.
-// Throws: None.
-//--
-bool CMICmdArgValConsume::IsOk() const { return true; }
diff --git a/tools/lldb-mi/MICmdArgValConsume.h b/tools/lldb-mi/MICmdArgValConsume.h
deleted file mode 100644
index 62207f04b679..000000000000
--- a/tools/lldb-mi/MICmdArgValConsume.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- MICmdArgValConsume.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument. This type having recognised its argument name just
-// consumes
-// that argument or option (ignores it). This is the so the validation
-// process can then ask if all arguments or options have been
-// recognised
-// other an error will occurred "argument not recognised". For example
-// this can be used to consume the "--" text which is not an argument
-// in
-// itself. Normally the GetValue() function (in base class) would
-// return
-// a value for the argument but is not the case for *this argument type
-// object.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValConsume : public CMICmdArgValBaseTemplate<CMIUtilString> {
- // Methods:
-public:
- /* ctor */ CMICmdArgValConsume();
- /* ctor */ CMICmdArgValConsume(const CMIUtilString &vrArgName,
- const bool vbMandatory);
- //
- bool IsOk() const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValConsume() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vwArgContext) override;
-};
diff --git a/tools/lldb-mi/MICmdArgValFile.cpp b/tools/lldb-mi/MICmdArgValFile.cpp
deleted file mode 100644
index 7171b0fa8f18..000000000000
--- a/tools/lldb-mi/MICmdArgValFile.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-//===-- MICmdArgValFile.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValFile constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValFile::CMICmdArgValFile() {}
-
-//++
-// Details: CMICmdArgValFile constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValFile::CMICmdArgValFile(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd) {}
-
-//++
-// Details: CMICmdArgValFile destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValFile::~CMICmdArgValFile() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (R) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- // The GDB/MI spec suggests there is only parameter
-
- if (vwArgContext.GetNumberArgsPresent() == 1) {
- const CMIUtilString &rFile(vwArgContext.GetArgsLeftToParse());
- if (IsFilePath(rFile)) {
- m_bFound = true;
- m_bValid = true;
- m_argValue = rFile.Trim('"');
- vwArgContext.RemoveArg(rFile);
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // In reality there are more than one option, if so the file option
- // is the last one (don't handle that here - find the best looking one)
- const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rTxt(*it);
- if (IsFilePath(rTxt)) {
- m_bFound = true;
-
- if (vwArgContext.RemoveArg(rTxt)) {
- m_bValid = true;
- m_argValue = rTxt.Trim('"');
- return MIstatus::success;
- } else
- return MIstatus::success;
- }
-
- // Next
- ++it;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Given some text extract the file name path from it. If a space is
-// found in
-// path done return the path surrounded in quotes.
-// Type: Method.
-// Args: vrTxt - (R) The text to extract the file name path from.
-// Return: CMIUtilString - File name and or path.
-// Throws: None.
-//--
-CMIUtilString
-CMICmdArgValFile::GetFileNamePath(const CMIUtilString &vrTxt) const {
- CMIUtilString fileNamePath(vrTxt);
-
- // Look for a space in the path
- const char cSpace = ' ';
- const size_t nPos = fileNamePath.find(cSpace);
- if (nPos != std::string::npos)
- fileNamePath = CMIUtilString::Format("\"%s\"", fileNamePath.c_str());
-
- return fileNamePath;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid file name path.
-// Type: Method.
-// Args: vrFileNamePath - (R) File's name and directory path.
-// Return: bool - True = yes valid file path, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValFile::IsFilePath(const CMIUtilString &vrFileNamePath) const {
- if (vrFileNamePath.empty())
- return false;
-
- const bool bHavePosSlash = (vrFileNamePath.find('/') != std::string::npos);
- const bool bHaveBckSlash = (vrFileNamePath.find('\\') != std::string::npos);
-
- // Look for --someLongOption
- size_t nPos = vrFileNamePath.find("--");
- const bool bLong = (nPos == 0);
- if (bLong)
- return false;
-
- // Look for -f type short parameters
- nPos = vrFileNamePath.find('-');
- const bool bShort = (nPos == 0);
- if (bShort)
- return false;
-
- // Look for i1 i2 i3....
- nPos = vrFileNamePath.find('i');
- const bool bFoundI1 = ((nPos == 0) && (::isdigit(vrFileNamePath[1])));
- if (bFoundI1)
- return false;
-
- const bool bValidChars = IsValidChars(vrFileNamePath);
- return bValidChars || bHavePosSlash || bHaveBckSlash;
-}
-
-//++
-// Details: Determine if the path contains valid characters for a file path.
-// Letters can be
-// either upper or lower case.
-// Type: Method.
-// Args: vrText - (R) The text data to examine.
-// Return: bool - True = yes valid, false = one or more chars is valid.
-// Throws: None.
-//--
-bool CMICmdArgValFile::IsValidChars(const CMIUtilString &vrText) const {
- static CMIUtilString s_strSpecialCharacters(".'\"`@#$%^&*()_+-={}[]| ");
- const char *pPtr = vrText.c_str();
- for (MIuint i = 0; i < vrText.length(); i++, pPtr++) {
- const char c = *pPtr;
- if (::isalnum((int)c) == 0) {
- if (s_strSpecialCharacters.find(c) == CMIUtilString::npos)
- return false;
- }
- }
-
- return true;
-}
diff --git a/tools/lldb-mi/MICmdArgValFile.h b/tools/lldb-mi/MICmdArgValFile.h
deleted file mode 100644
index 8030cb783aab..000000000000
--- a/tools/lldb-mi/MICmdArgValFile.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- MICmdArgValFile.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it .
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValFile : public CMICmdArgValBaseTemplate<CMIUtilString> {
- // Methods:
-public:
- /* ctor */ CMICmdArgValFile();
- /* ctor */ CMICmdArgValFile(const CMIUtilString &vrArgName,
- const bool vbMandatory, const bool vbHandleByCmd);
- //
- bool IsFilePath(const CMIUtilString &vrFileNamePath) const;
- CMIUtilString GetFileNamePath(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValFile() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vwArgContext) override;
-
- // Methods:
-private:
- bool IsValidChars(const CMIUtilString &vrText) const;
-};
diff --git a/tools/lldb-mi/MICmdArgValListBase.cpp b/tools/lldb-mi/MICmdArgValListBase.cpp
deleted file mode 100644
index bd175f3afe64..000000000000
--- a/tools/lldb-mi/MICmdArgValListBase.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-//===-- MICmdArgValListBase.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValListBase.h"
-#include "MICmdArgContext.h"
-#include "MICmdArgValConsume.h"
-#include "MICmdArgValFile.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-
-//++
-// Details: CMICmdArgValListBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListBase::CMICmdArgValListBase()
- : m_eArgType(eArgValType_invalid) {}
-
-//++
-// Details: CMICmdArgValListBase constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListBase::CMICmdArgValListBase(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_eArgType(eArgValType_invalid) {}
-
-//++
-// Details: CMICmdArgValListBase constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// veType - (R) The type of argument to look for and create
-// argument object of a certain type.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListBase::CMICmdArgValListBase(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_eArgType(veType) {}
-
-//++
-// Details: CMICmdArgValListBase destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListBase::~CMICmdArgValListBase() {
- // Tidy up
- Destroy();
-}
-
-//++
-// Details: Tear down resources used by *this object.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdArgValListBase::Destroy() {
- // Tidy up
- VecArgObjPtr_t::const_iterator it = m_argValue.begin();
- while (it != m_argValue.end()) {
- CMICmdArgValBase *pArgObj = *it;
- delete pArgObj;
-
- // Next
- ++it;
- }
- m_argValue.clear();
-}
-
-//++
-// Details: Create an CMICmdArgValBase derived object matching the type
-// specified
-// and put the option or argument's value inside it.
-// Type: Method.
-// Args: vrTxt - (R) Text version the option or argument.
-// veType - (R) The type of argument or option object to create.
-// Return: CMICmdArgValBase * - Option object holding the value.
-// - NULL = Functional failed.
-// Throws: None.
-//--
-CMICmdArgValBase *
-CMICmdArgValListBase::CreationObj(const CMIUtilString &vrTxt,
- const ArgValType_e veType) const {
- CMICmdArgValBase *pOptionObj = nullptr;
- switch (veType) {
- case eArgValType_File:
- pOptionObj = new CMICmdArgValFile();
- break;
- case eArgValType_Consume:
- pOptionObj = new CMICmdArgValConsume();
- break;
- case eArgValType_Number:
- pOptionObj = new CMICmdArgValNumber();
- break;
- case eArgValType_OptionLong:
- pOptionObj = new CMICmdArgValOptionLong();
- break;
- case eArgValType_OptionShort:
- pOptionObj = new CMICmdArgValOptionShort();
- break;
- case eArgValType_String:
- pOptionObj = new CMICmdArgValString();
- break;
- case eArgValType_StringQuoted:
- pOptionObj = new CMICmdArgValString(true, false, false);
- break;
- case eArgValType_StringQuotedNumber:
- pOptionObj = new CMICmdArgValString(true, true, false);
- break;
- case eArgValType_StringQuotedNumberPath:
- pOptionObj = new CMICmdArgValString(true, true, true);
- break;
- case eArgValType_StringAnything:
- pOptionObj = new CMICmdArgValString(true);
- break;
- case eArgValType_ThreadGrp:
- pOptionObj = new CMICmdArgValThreadGrp();
- break;
- default:
- return nullptr;
- }
-
- CMICmdArgContext argCntxt(vrTxt);
- if (!pOptionObj->Validate(argCntxt))
- return nullptr;
-
- return pOptionObj;
-}
-
-//++
-// Details: Validate the option or argument is the correct type.
-// Type: Method.
-// Args: vrTxt - (R) Text version the option or argument.
-// veType - (R) The type of value to expect.
-// Return: bool - True = Yes expected type present, False = no.
-// Throws: None.
-//--
-bool CMICmdArgValListBase::IsExpectedCorrectType(
- const CMIUtilString &vrTxt, const ArgValType_e veType) const {
- bool bValid = false;
- switch (veType) {
- case eArgValType_File:
- bValid = CMICmdArgValFile().IsFilePath(vrTxt);
- break;
- case eArgValType_Consume:
- bValid = CMICmdArgValConsume().IsOk();
- break;
- case eArgValType_Number:
- bValid = CMICmdArgValNumber().IsArgNumber(vrTxt);
- break;
- case eArgValType_OptionLong:
- bValid = CMICmdArgValOptionLong().IsArgLongOption(vrTxt);
- break;
- case eArgValType_OptionShort:
- bValid = CMICmdArgValOptionShort().IsArgShortOption(vrTxt);
- break;
- case eArgValType_String:
- bValid = CMICmdArgValString().IsStringArg(vrTxt);
- break;
- case eArgValType_StringQuoted:
- bValid = CMICmdArgValString(true, false, false).IsStringArg(vrTxt);
- break;
- case eArgValType_StringQuotedNumber:
- bValid = CMICmdArgValString(true, true, false).IsStringArg(vrTxt);
- break;
- case eArgValType_StringQuotedNumberPath:
- bValid = CMICmdArgValString(true, true, true).IsStringArg(vrTxt);
- break;
- case eArgValType_StringAnything:
- bValid = CMICmdArgValString(true).IsStringArg(vrTxt);
- break;
- case eArgValType_ThreadGrp:
- bValid = CMICmdArgValThreadGrp().IsArgThreadGrp(vrTxt);
- break;
- default:
- return false;
- }
-
- return bValid;
-}
diff --git a/tools/lldb-mi/MICmdArgValListBase.h b/tools/lldb-mi/MICmdArgValListBase.h
deleted file mode 100644
index 4437ae19a87c..000000000000
--- a/tools/lldb-mi/MICmdArgValListBase.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- MICmdArgValListBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <vector>
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument with addition options class.
-// For example --recurse 1 2 4 [group ...]. Arguments object that
-// require a list of options associated with them derive from the
-// CMICmdArgValListBase class. Additional options are also extracted
-// from
-// the command arguments text string.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// options and so extract a values from it .
-// The CMICmdArgValBase objects are added to the derived argument
-// class's
-// container. The option arguments belong to that derived class and
-// will
-// be deleted that object goes out of scope.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValListBase
- : public CMICmdArgValBaseTemplate<std::vector<CMICmdArgValBase *>> {
- // Typedef:
-public:
- typedef std::vector<CMICmdArgValBase *> VecArgObjPtr_t;
-
- // Enums:
-public:
- //++
- // Details: CMICmdArgValListBase needs to know what type of argument to look
- // for in
- // the command options text. It also needs to create argument objects
- // of
- // a specific type.
- //--
- enum ArgValType_e {
- eArgValType_File = 0,
- eArgValType_Consume,
- eArgValType_Number,
- eArgValType_OptionLong,
- eArgValType_OptionShort,
- eArgValType_String,
- eArgValType_StringQuoted,
- eArgValType_StringQuotedNumber,
- eArgValType_StringQuotedNumberPath,
- eArgValType_StringAnything, // Accept any words for a string 'type' even if
- // they look like --longOptions for example
- eArgValType_ThreadGrp,
- eArgValType_count, // Always the last one
- eArgValType_invalid
- };
-
- // Methods:
-public:
- /* ctor */ CMICmdArgValListBase();
- /* ctor */ CMICmdArgValListBase(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd);
- /* ctor */ CMICmdArgValListBase(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType);
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValListBase() override;
-
- // Methods:
-protected:
- bool IsExpectedCorrectType(const CMIUtilString &vrTxt,
- const ArgValType_e veType) const;
- CMICmdArgValBase *CreationObj(const CMIUtilString &vrTxt,
- const ArgValType_e veType) const;
-
- // Attributes:
-protected:
- ArgValType_e m_eArgType;
-
- // Methods:
-private:
- void Destroy();
-};
diff --git a/tools/lldb-mi/MICmdArgValListOfN.cpp b/tools/lldb-mi/MICmdArgValListOfN.cpp
deleted file mode 100644
index b53424543b2b..000000000000
--- a/tools/lldb-mi/MICmdArgValListOfN.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//===-- MICmdArgValListOfN.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgContext.h"
-#include "MICmdArgValFile.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-
-//++
-// Details: CMICmdArgValListOfN constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListOfN::CMICmdArgValListOfN() {}
-
-//++
-// Details: CMICmdArgValListOfN constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// veType - (R) The type of argument to look for and create
-// argument object of a certain type.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListOfN::CMICmdArgValListOfN(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType)
- : CMICmdArgValListBase(vrArgName, vbMandatory, vbHandleByCmd, veType) {}
-
-//++
-// Details: CMICmdArgValListOfN destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValListOfN::~CMICmdArgValListOfN() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// list of
-// arguments based on the argument object type to look for.
-// Type: Overridden.
-// Args: vwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValListOfN::Validate(CMICmdArgContext &vwArgContext) {
- if (m_eArgType >= eArgValType_count) {
- m_eArgType = eArgValType_invalid;
- return MIstatus::failure;
- }
-
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
- if (IsListOfN(rArg) && CreateList(rArg)) {
- m_bFound = true;
- m_bValid = true;
- vwArgContext.RemoveArg(rArg);
- return MIstatus::success;
- } else
- return MIstatus::failure;
-}
-
-//++
-// Details: Create list of argument objects each holding a value extract from
-// the command
-// options line.
-// Type: Method.
-// Args: vrTxt - (R) Some options text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValListOfN::CreateList(const CMIUtilString &vrTxt) {
- CMIUtilString::VecString_t vecOptions;
- if ((m_eArgType == eArgValType_StringQuoted) ||
- (m_eArgType == eArgValType_StringQuotedNumber) ||
- (m_eArgType == eArgValType_StringQuotedNumberPath) ||
- (m_eArgType == eArgValType_StringAnything)) {
- if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0)
- return MIstatus::failure;
- } else if (vrTxt.Split(" ", vecOptions) == 0)
- return MIstatus::failure;
-
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rOption = *it;
- CMICmdArgValBase *pOption = CreationObj(rOption, m_eArgType);
- if (pOption != nullptr)
- m_argValue.push_back(pOption);
- else
- return MIstatus::failure;
-
- // Next
- ++it;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValListOfN::IsListOfN(const CMIUtilString &vrTxt) const {
- CMIUtilString::VecString_t vecOptions;
- if ((m_eArgType == eArgValType_StringQuoted) ||
- (m_eArgType == eArgValType_StringQuotedNumber) ||
- (m_eArgType == eArgValType_StringQuotedNumberPath) ||
- (m_eArgType == eArgValType_StringAnything)) {
- if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0)
- return false;
- } else if (vrTxt.Split(" ", vecOptions) == 0)
- return false;
-
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rOption = *it;
- if (!IsExpectedCorrectType(rOption, m_eArgType))
- break;
-
- // Next
- ++it;
- }
-
- return true;
-}
-
-//++
-// Details: Retrieve the list of CMICmdArgValBase derived option objects found
-// following
-// *this long option argument. For example "list-thread-groups [
-// --recurse 1 ]"
-// where 1 is the list of expected option to follow.
-// Type: Method.
-// Args: None.
-// Return: CMICmdArgValListBase::VecArgObjPtr_t & - List of options.
-// Throws: None.
-//--
-const CMICmdArgValListBase::VecArgObjPtr_t &
-CMICmdArgValListOfN::GetExpectedOptions() const {
- return m_argValue;
-}
diff --git a/tools/lldb-mi/MICmdArgValListOfN.h b/tools/lldb-mi/MICmdArgValListOfN.h
deleted file mode 100644
index 74e8c16f7d6e..000000000000
--- a/tools/lldb-mi/MICmdArgValListOfN.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===-- MICmdArgValListOfN.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <vector>
-
-// In-house headers:
-#include "MICmdArgValListBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it .
-// The CMICmdArgValBase objects added to *this ListOfN container belong
-// to this container and will be deleted when *this object goes out of
-// scope.
-// To parse arguments like 'thread-id ...' i.e. 1 10 12 13 ...
-// If vbMandatory argument is true it takes on the (...)+ specification
-// otherwise assumed to be (...)* specification.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValListOfN : public CMICmdArgValListBase {
- // Methods:
-public:
- /* ctor */ CMICmdArgValListOfN();
- /* ctor */ CMICmdArgValListOfN(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType);
- //
- const VecArgObjPtr_t &GetExpectedOptions() const;
- template <class T1, typename T2>
- bool GetExpectedOption(T2 &vrwValue,
- const VecArgObjPtr_t::size_type vnAt = 0) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValListOfN() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vArgContext) override;
-
- // Methods:
-private:
- bool IsListOfN(const CMIUtilString &vrTxt) const;
- bool CreateList(const CMIUtilString &vrTxt);
-};
-
-//++
-// Details: Retrieve the first argument or option value from the list of 1 or
-// more options
-// parsed from the command's options string.
-// Type: Template method.
-// Args: vrwValue - (W) Templated type return value.
-// vnAt - (R) Value at the specific position.
-// T1 - The argument value's class type of the data hold in
-// the list of options.
-// T2 - The type pf the variable which holds the value wanted.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed. List of object was empty.
-// Throws: None.
-//--
-template <class T1, typename T2>
-bool CMICmdArgValListOfN::GetExpectedOption(
- T2 &vrwValue, const VecArgObjPtr_t::size_type vnAt) const {
- const VecArgObjPtr_t &rVecOptions(GetExpectedOptions());
- if (rVecOptions.size() <= vnAt)
- return MIstatus::failure;
-
- VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin() + vnAt;
- if (it2 != rVecOptions.end()) {
- const T1 *pOption = static_cast<T1 *>(*it2);
- vrwValue = pOption->GetValue();
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
diff --git a/tools/lldb-mi/MICmdArgValNumber.cpp b/tools/lldb-mi/MICmdArgValNumber.cpp
deleted file mode 100644
index ad2df79bf3d9..000000000000
--- a/tools/lldb-mi/MICmdArgValNumber.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- MICmdArgValNumber.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValNumber.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValNumber constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValNumber::CMICmdArgValNumber()
- : m_nNumberFormatMask(CMICmdArgValNumber::eArgValNumberFormat_Decimal),
- m_nNumber(0) {}
-
-//++
-// Details: CMICmdArgValNumber constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false =
-// optional argument.
-// vbHandleByCmd - (R) True = Command processes *this option,
-// false = not handled.
-// vnNumberFormatMask - (R) Mask of the number formats. (Dflt =
-// CMICmdArgValNumber::eArgValNumberFormat_Decimal)
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValNumber::CMICmdArgValNumber(
- const CMIUtilString &vrArgName, const bool vbMandatory,
- const bool vbHandleByCmd,
- const MIuint
- vnNumberFormatMask /* = CMICmdArgValNumber::eArgValNumberFormat_Decimal*/)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_nNumberFormatMask(vnNumberFormatMask), m_nNumber(0) {}
-
-//++
-// Details: CMICmdArgValNumber destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValNumber::~CMICmdArgValNumber() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValNumber::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- if (vwArgContext.GetNumberArgsPresent() == 1) {
- const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
- if (IsArgNumber(rArg) && ExtractNumber(rArg)) {
- m_bFound = true;
- m_bValid = true;
- m_argValue = GetNumber();
- vwArgContext.RemoveArg(rArg);
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // More than one option...
- const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rArg(*it);
- if (IsArgNumber(rArg) && ExtractNumber(rArg)) {
- m_bFound = true;
-
- if (vwArgContext.RemoveArg(rArg)) {
- m_bValid = true;
- m_argValue = GetNumber();
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // Next
- ++it;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValNumber::IsArgNumber(const CMIUtilString &vrTxt) const {
- const bool bFormatDecimal(m_nNumberFormatMask &
- CMICmdArgValNumber::eArgValNumberFormat_Decimal);
- const bool bFormatHexadecimal(
- m_nNumberFormatMask &
- CMICmdArgValNumber::eArgValNumberFormat_Hexadecimal);
-
- // Look for --someLongOption
- if (std::string::npos != vrTxt.find("--"))
- return false;
-
- if (bFormatDecimal && vrTxt.IsNumber())
- return true;
-
- if (bFormatHexadecimal && vrTxt.IsHexadecimalNumber())
- return true;
-
- return false;
-}
-
-//++
-// Details: Extract the thread group number from the thread group argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValNumber::ExtractNumber(const CMIUtilString &vrTxt) {
- MIint64 nNumber = 0;
- bool bOk = vrTxt.ExtractNumber(nNumber);
- if (bOk) {
- m_nNumber = static_cast<MIint64>(nNumber);
- }
-
- return bOk;
-}
-
-//++
-// Details: Retrieve the thread group ID found in the argument.
-// Type: Method.
-// Args: None.
-// Return: MIuint - Thread group ID.
-// Throws: None.
-//--
-MIint64 CMICmdArgValNumber::GetNumber() const { return m_nNumber; }
diff --git a/tools/lldb-mi/MICmdArgValNumber.h b/tools/lldb-mi/MICmdArgValNumber.h
deleted file mode 100644
index 23c888e5d806..000000000000
--- a/tools/lldb-mi/MICmdArgValNumber.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MICmdArgValNumber.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it .
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValNumber : public CMICmdArgValBaseTemplate<MIint64> {
- // Enums:
-public:
- //++
- // Details: CMICmdArgValNumber needs to know what format of argument to look
- // for in
- // the command options text.
- //--
- enum ArgValNumberFormat_e {
- eArgValNumberFormat_Decimal = (1u << 0),
- eArgValNumberFormat_Hexadecimal = (1u << 1),
- eArgValNumberFormat_Auto =
- ((eArgValNumberFormat_Hexadecimal << 1) -
- 1u) ///< Indicates to try and lookup everything up during a query.
- };
-
- // Methods:
-public:
- /* ctor */ CMICmdArgValNumber();
- /* ctor */ CMICmdArgValNumber(
- const CMIUtilString &vrArgName, const bool vbMandatory,
- const bool vbHandleByCmd,
- const MIuint vnNumberFormatMask = eArgValNumberFormat_Decimal);
- //
- bool IsArgNumber(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValNumber() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vwArgContext) override;
-
- // Methods:
-private:
- bool ExtractNumber(const CMIUtilString &vrTxt);
- MIint64 GetNumber() const;
-
- // Attributes:
-private:
- MIuint m_nNumberFormatMask;
- MIint64 m_nNumber;
-};
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.cpp b/tools/lldb-mi/MICmdArgValOptionLong.cpp
deleted file mode 100644
index 3dc9d40f4b56..000000000000
--- a/tools/lldb-mi/MICmdArgValOptionLong.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-//===-- MICmdArgValOptionLong.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValOptionLong constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionLong::CMICmdArgValOptionLong()
- : m_nExpectingNOptions(0), m_eExpectingOptionType(eArgValType_invalid) {}
-
-//++
-// Details: CMICmdArgValOptionLong constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionLong::CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValListBase(vrArgName, vbMandatory, vbHandleByCmd),
- m_nExpectingNOptions(0), m_eExpectingOptionType(eArgValType_invalid) {}
-
-//++
-// Details: CMICmdArgValOptionLong constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false =
-// optional argument.
-// vbHandleByCmd - (R) True = Command processes *this option,
-// false = not handled.
-// veType - (R) The type of argument to look for and
-// create argument object of a certain type.
-// vnExpectingNOptions - (R) The number of options expected to read
-// following *this argument.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionLong::CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType,
- const MIuint vnExpectingNOptions)
- : CMICmdArgValListBase(vrArgName, vbMandatory, vbHandleByCmd),
- m_nExpectingNOptions(vnExpectingNOptions),
- m_eExpectingOptionType(veType) {}
-
-//++
-// Details: CMICmdArgValOptionLong destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionLong::~CMICmdArgValOptionLong() {
- // Tidy up
- Destroy();
-}
-
-//++
-// Details: Tear down resources used by *this object.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdArgValOptionLong::Destroy() {
- // Tidy up
- VecArgObjPtr_t::const_iterator it = m_vecArgsExpected.begin();
- while (it != m_vecArgsExpected.end()) {
- CMICmdArgValBase *pOptionObj = *it;
- delete pOptionObj;
-
- // Next
- ++it;
- }
- m_vecArgsExpected.clear();
-}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// long
-// argument *this argument type is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValOptionLong::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- if (vwArgContext.GetNumberArgsPresent() == 1) {
- const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
- if (IsArgLongOption(rArg) && ArgNameMatch(rArg)) {
- m_bFound = true;
-
- if (!vwArgContext.RemoveArg(rArg))
- return MIstatus::failure;
-
- if (m_nExpectingNOptions == 0) {
- m_bValid = true;
- return MIstatus::success;
- }
-
- m_bIsMissingOptions = true;
- return MIstatus::failure;
- } else
- return MIstatus::failure;
- }
-
- // More than one option...
- MIuint nArgIndex = 0;
- const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rArg(*it);
- if (IsArgOptionCorrect(rArg) && ArgNameMatch(rArg)) {
- m_bFound = true;
-
- if (!vwArgContext.RemoveArg(rArg))
- return MIstatus::failure;
-
- if (m_nExpectingNOptions != 0) {
- if (ExtractExpectedOptions(vwArgContext, nArgIndex)) {
- m_bValid = true;
- return MIstatus::success;
- }
-
- m_bIsMissingOptions = true;
- return MIstatus::failure;
- } else {
- m_bValid = true;
- return MIstatus::success;
- }
- }
-
- // Next
- ++it;
- ++nArgIndex;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Parse the text following *this argument and extract the options the
-// values of
-// CMICmdArgValListBase::m_eArgType forming argument objects for each
-// of those
-// options extracted.
-// Type: Method.
-// Args: vrwTxt - (RW) The command's argument options string.
-// nArgIndex - (R) The Nth arg position in argument context from
-// the left.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValOptionLong::ExtractExpectedOptions(CMICmdArgContext &vrwTxt,
- const MIuint nArgIndex) {
- CMIUtilString::VecString_t vecOptions = vrwTxt.GetArgs();
- if (vecOptions.size() == 0)
- return MIstatus::failure;
-
- MIuint nArgIndexCnt = 0;
- MIuint nTypeCnt = 0;
- MIuint nTypeCnt2 = 0;
- MIuint nFoundNOptionsCnt = 0;
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- // Move to the Nth argument position from left before do validation/checking
- if (nArgIndexCnt++ == nArgIndex) {
- nTypeCnt++;
- const CMIUtilString &rOption(*it);
- if (IsExpectedCorrectType(rOption, m_eExpectingOptionType)) {
- nTypeCnt2++;
- CMICmdArgValBase *pOptionObj =
- CreationObj(rOption, m_eExpectingOptionType);
- if ((pOptionObj != nullptr) &&
- vrwTxt.RemoveArgAtPos(rOption, nArgIndex)) {
- nFoundNOptionsCnt++;
- m_vecArgsExpected.push_back(pOptionObj);
- }
- }
-
- // Is the sequence 'options' of same type broken. Expecting the same type
- // until the
- // next argument.
- if (nTypeCnt != nTypeCnt2)
- return MIstatus::failure;
-
- if (nFoundNOptionsCnt == m_nExpectingNOptions)
- return MIstatus::success;
- }
-
- // Next
- ++it;
- }
- if (nFoundNOptionsCnt != m_nExpectingNOptions)
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid long type option
-// argument.
-// Long type argument looks like --someLongOption.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionLong::IsArgLongOption(const CMIUtilString &vrTxt) const {
- const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
- const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
- if (bHavePosSlash || bHaveBckSlash)
- return false;
-
- const size_t nPos = vrTxt.find("--");
- if (nPos != 0)
- return false;
-
- if (vrTxt.length() < 3)
- return false;
-
- const CMIUtilString strArg = vrTxt.substr(2);
- return !strArg.IsNumber();
-}
-
-//++
-// Details: Examine the string and determine if it is a valid long type option
-// argument.
-// Long type argument looks like --someLongOption.
-// Type: Overideable.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionLong::IsArgOptionCorrect(
- const CMIUtilString &vrTxt) const {
- return IsArgLongOption(vrTxt);
-}
-
-//++
-// Details: Does the argument name of the argument being parsed ATM match the
-// name of
-// *this argument object.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes arg name matched, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionLong::ArgNameMatch(const CMIUtilString &vrTxt) const {
- const CMIUtilString strArg = vrTxt.substr(2);
- return (strArg == GetName());
-}
-
-//++
-// Details: Retrieve the list of CMICmdArgValBase derived option objects found
-// following
-// *this long option argument. For example "list-thread-groups [
-// --recurse 1 ]"
-// where 1 is the list of expected option to follow.
-// Type: Method.
-// Args: None.
-// Return: CMICmdArgValListBase::VecArgObjPtr_t & - List of options.
-// Throws: None.
-//--
-const CMICmdArgValListBase::VecArgObjPtr_t &
-CMICmdArgValOptionLong::GetExpectedOptions() const {
- return m_vecArgsExpected;
-}
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.h b/tools/lldb-mi/MICmdArgValOptionLong.h
deleted file mode 100644
index 240829733680..000000000000
--- a/tools/lldb-mi/MICmdArgValOptionLong.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- MICmdArgValOptionLong.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValListBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-class CMIUtilString;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it.
-// If *this argument has expected options following it the option
-// objects
-// created to hold each of those option's values belong to *this
-// argument
-// object and so are deleted when *this object goes out of scope.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValOptionLong : public CMICmdArgValListBase {
- // Methods:
-public:
- /* ctor */ CMICmdArgValOptionLong();
- /* ctor */ CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd);
- /* ctor */ CMICmdArgValOptionLong(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType,
- const MIuint vnExpectingNOptions);
- //
- bool IsArgLongOption(const CMIUtilString &vrTxt) const;
- const VecArgObjPtr_t &GetExpectedOptions() const;
- template <class T1, typename T2> bool GetExpectedOption(T2 &vrwValue) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValOptionLong() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vArgContext) override;
-
- // Methods:
-protected:
- bool ExtractExpectedOptions(CMICmdArgContext &vrwTxt, const MIuint nArgIndex);
-
- // Overrideable:
-protected:
- virtual bool IsArgOptionCorrect(const CMIUtilString &vrTxt) const;
- virtual bool ArgNameMatch(const CMIUtilString &vrTxt) const;
-
- // Methods:
-private:
- void Destroy();
-
- // Attributes:
-private:
- MIuint m_nExpectingNOptions; // The number of options expected to read
- // following *this argument
- VecArgObjPtr_t m_vecArgsExpected; // The option objects holding the value
- // extracted following *this argument
- ArgValType_e m_eExpectingOptionType; // The type of options expected to read
- // following *this argument
-};
-
-//++
-// Details: Retrieve the first argument or option value from the list of 1 or
-// more options
-// parsed from the command's options string.
-// Type: Template method.
-// Args: vrwValue - (W) Templated type return value.
-// T1 - The argument value's class type of the data hold in
-// the list of options.
-// T2 - The type pf the variable which holds the value wanted.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed. List of object was empty.
-// Throws: None.
-//--
-template <class T1, typename T2>
-bool CMICmdArgValOptionLong::GetExpectedOption(T2 &vrwValue) const {
- const VecArgObjPtr_t &rVecOptions(GetExpectedOptions());
- VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin();
- if (it2 != rVecOptions.end()) {
- const T1 *pOption = static_cast<T1 *>(*it2);
- vrwValue = pOption->GetValue();
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.cpp b/tools/lldb-mi/MICmdArgValOptionShort.cpp
deleted file mode 100644
index 7b7116cd5f18..000000000000
--- a/tools/lldb-mi/MICmdArgValOptionShort.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- MICmdArgValOptionShort.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValOptionShort constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionShort::CMICmdArgValOptionShort() {}
-
-//++
-// Details: CMICmdArgValOptionShort constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionShort::CMICmdArgValOptionShort(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValOptionLong(vrArgName, vbMandatory, vbHandleByCmd) {}
-
-//++
-// Details: CMICmdArgValOptionLong constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false =
-// optional argument.
-// vbHandleByCmd - (R) True = Command processes *this option,
-// false = not handled.
-// veType - (R) The type of argument to look for and
-// create argument object of a certain type.
-// vnExpectingNOptions - (R) The number of options expected to read
-// following *this argument.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionShort::CMICmdArgValOptionShort(
- const CMIUtilString &vrArgName, const bool vbMandatory,
- const bool vbHandleByCmd, const ArgValType_e veType,
- const MIuint vnExpectingNOptions)
- : CMICmdArgValOptionLong(vrArgName, vbMandatory, vbHandleByCmd, veType,
- vnExpectingNOptions) {}
-
-//++
-// Details: CMICmdArgValOptionShort destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValOptionShort::~CMICmdArgValOptionShort() {}
-
-//++
-// Details: Examine the string and determine if it is a valid short type option
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionShort::IsArgShortOption(
- const CMIUtilString &vrTxt) const {
- // Look for --someLongOption
- MIint nPos = vrTxt.find("--");
- if (nPos == 0)
- return false;
-
- // Look for -f short option
- nPos = vrTxt.find('-');
- if (nPos != 0)
- return false;
-
- if (vrTxt.length() > 2)
- return false;
-
- return true;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid short type option
-// argument.
-// Long type argument looks like -f some short option.
-// Type: Overridden.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionShort::IsArgOptionCorrect(
- const CMIUtilString &vrTxt) const {
- return IsArgShortOption(vrTxt);
-}
-
-//++
-// Details: Does the argument name of the argument being parsed ATM match the
-// name of
-// *this argument object.
-// Type: Overridden.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes arg name matched, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValOptionShort::ArgNameMatch(const CMIUtilString &vrTxt) const {
- const CMIUtilString strArg = vrTxt.substr(1);
- return (strArg == GetName());
-}
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.h b/tools/lldb-mi/MICmdArgValOptionShort.h
deleted file mode 100644
index fd39c9e73a57..000000000000
--- a/tools/lldb-mi/MICmdArgValOptionShort.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- MICmdArgValOptionShort.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValOptionLong.h"
-
-// Declarations:
-class CMICmdArgContext;
-class CMIUtilString;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValOptionLong
-// class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it.
-// If *this argument has expected options following it the option
-// objects
-// created to hold each of those option's values belong to *this
-// argument
-// object and so are deleted when *this object goes out of scope.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValOptionShort : public CMICmdArgValOptionLong {
- // Methods:
-public:
- /* ctor */ CMICmdArgValOptionShort();
- /* ctor */ CMICmdArgValOptionShort(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd);
- /* ctor */ CMICmdArgValOptionShort(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const ArgValType_e veType,
- const MIuint vnExpectingNOptions);
- //
- bool IsArgShortOption(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValOptionShort() override;
-
- // Overridden:
-private:
- // From CMICmdArgValOptionLong
- bool IsArgOptionCorrect(const CMIUtilString &vrTxt) const override;
- bool ArgNameMatch(const CMIUtilString &vrTxt) const override;
-};
diff --git a/tools/lldb-mi/MICmdArgValPrintValues.cpp b/tools/lldb-mi/MICmdArgValPrintValues.cpp
deleted file mode 100644
index a2ce45247375..000000000000
--- a/tools/lldb-mi/MICmdArgValPrintValues.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- MICmdArgValPrintValues.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValPrintValues.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValPrintValues constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValPrintValues::CMICmdArgValPrintValues() : m_nPrintValues(0) {}
-
-//++
-// Details: CMICmdArgValPrintValues constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValPrintValues::CMICmdArgValPrintValues(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_nPrintValues(0) {}
-
-//++
-// Details: CMICmdArgValPrintValues destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValPrintValues::~CMICmdArgValPrintValues() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValPrintValues::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- const CMIUtilString strArg(vwArgContext.GetArgs()[0]);
- if (IsArgPrintValues(strArg) && ExtractPrintValues(strArg)) {
- m_bFound = true;
- m_bValid = true;
- m_argValue = GetPrintValues();
- vwArgContext.RemoveArg(strArg);
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValPrintValues::IsArgPrintValues(
- const CMIUtilString &vrTxt) const {
- return (CMIUtilString::Compare(vrTxt, "0") ||
- CMIUtilString::Compare(vrTxt, "--no-values") ||
- CMIUtilString::Compare(vrTxt, "1") ||
- CMIUtilString::Compare(vrTxt, "--all-values") ||
- CMIUtilString::Compare(vrTxt, "2") ||
- CMIUtilString::Compare(vrTxt, "--simple-values"));
-}
-
-//++
-// Details: Extract the print-values from the print-values argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValPrintValues::ExtractPrintValues(const CMIUtilString &vrTxt) {
- if (CMIUtilString::Compare(vrTxt, "0") ||
- CMIUtilString::Compare(vrTxt, "--no-values"))
- m_nPrintValues = 0;
- else if (CMIUtilString::Compare(vrTxt, "1") ||
- CMIUtilString::Compare(vrTxt, "--all-values"))
- m_nPrintValues = 1;
- else if (CMIUtilString::Compare(vrTxt, "2") ||
- CMIUtilString::Compare(vrTxt, "--simple-values"))
- m_nPrintValues = 2;
- else
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the print-values found in the argument.
-// Type: Method.
-// Args: None.
-// Return: MIuint - The print-values.
-// Throws: None.
-//--
-MIuint CMICmdArgValPrintValues::GetPrintValues() const {
- return m_nPrintValues;
-}
diff --git a/tools/lldb-mi/MICmdArgValPrintValues.h b/tools/lldb-mi/MICmdArgValPrintValues.h
deleted file mode 100644
index 3fa8142c1ae5..000000000000
--- a/tools/lldb-mi/MICmdArgValPrintValues.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- MICmdArgValPrintValues.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it. The print-values looks
-// like:
-// 0 or --no-values
-// 1 or --all-values
-// 2 or --simple-values
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValPrintValues : public CMICmdArgValBaseTemplate<MIuint> {
- // Methods:
-public:
- /* ctor */ CMICmdArgValPrintValues();
- /* ctor */ CMICmdArgValPrintValues(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd);
- //
- bool IsArgPrintValues(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValPrintValues() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vArgContext) override;
-
- // Methods:
-private:
- bool ExtractPrintValues(const CMIUtilString &vrTxt);
- MIuint GetPrintValues() const;
-
- // Attributes:
-private:
- MIuint m_nPrintValues;
-};
diff --git a/tools/lldb-mi/MICmdArgValString.cpp b/tools/lldb-mi/MICmdArgValString.cpp
deleted file mode 100644
index bd105bc289b3..000000000000
--- a/tools/lldb-mi/MICmdArgValString.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-//===-- MICmdArgValString.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValString.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValString constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::CMICmdArgValString()
- : m_bHandleQuotedString(false), m_bAcceptNumbers(false),
- m_bHandleDirPaths(false), m_bHandleAnything(false) {}
-
-//++
-// Details: CMICmdArgValString constructor.
-// Type: Method.
-// Args: vbAnything - (R) True = Parse a string and accept anything, false =
-// do not accept anything.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
- : m_bHandleQuotedString(vbAnything), m_bAcceptNumbers(false),
- m_bHandleDirPaths(false), m_bHandleAnything(vbAnything) {}
-
-//++
-// Details: CMICmdArgValString constructor.
-// Type: Method.
-// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes
-// spaces are not delimiters, false = only text up to
-// next delimiting space character.
-// vbAcceptNumbers - (R) True = Parse a string and accept as a
-// number if number, false = numbers not recognised
-// as string types.
-// vbHandleDirPaths - (R) True = Parse a string and accept as a file
-// path if a path, false = file paths are not
-// recognised as string types.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::CMICmdArgValString(const bool vbHandleQuotes,
- const bool vbAcceptNumbers,
- const bool vbHandleDirPaths)
- : m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
- m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
-
-//++
-// Details: CMICmdArgValString constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// vbHandleQuotes - (R) True = Parse a string surrounded by quotes
-// spaces are not delimiters, false = only text up to
-// next delimiting space character. (Dflt = false)
-// vbAcceptNumbers - (R) True = Parse a string and accept as a number
-// if number, false = numbers not recognised as
-// string types. (Dflt = false)
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const bool vbHandleQuotes /* = false */,
- const bool vbAcceptNumbers /* = false */)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
- m_bHandleDirPaths(false), m_bHandleAnything(false) {}
-
-//++
-// Details: CMICmdArgValString constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// vbHandleQuotes - (R) True = Parse a string surrounded by quotes
-// spaces are not delimiters, false = only text up to
-// next delimiting space character.
-// vbAcceptNumbers - (R) True = Parse a string and accept as a number
-// if number, false = numbers not recognised as
-// vbHandleDirPaths - (R) True = Parse a string and accept as a file
-// path if a path, false = file paths are not
-// string types.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::CMICmdArgValString(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const bool vbHandleQuotes,
- const bool vbAcceptNumbers,
- const bool vbHandleDirPaths)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_bHandleQuotedString(vbHandleQuotes), m_bAcceptNumbers(vbAcceptNumbers),
- m_bHandleDirPaths(vbHandleDirPaths), m_bHandleAnything(false) {}
-
-//++
-// Details: CMICmdArgValString destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValString::~CMICmdArgValString() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vrwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext) {
- if (vrwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- if (m_bHandleQuotedString)
- return ValidateQuotedText(vrwArgContext);
-
- return ValidateSingleText(vrwArgContext);
-}
-
-//++
-// Details: Parse the command's argument options string and try to extract only
-// the next
-// word delimited by the next space.
-// Type: Method.
-// Args: vrwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext) {
- const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rArg(*it);
- if (IsStringArg(rArg)) {
- m_bFound = true;
-
- if (vrwArgContext.RemoveArg(rArg)) {
- m_bValid = true;
- m_argValue = rArg.StripSlashes();
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // Next
- ++it;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Parse the command's argument options string and try to extract all
-// the words
-// between quotes then delimited by the next space.
-// Type: Method.
-// Args: vrwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext) {
- const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
- if (vecOptions.size() == 0)
- return MIstatus::failure;
-
- const CMIUtilString &rArg(vecOptions[0]);
- if (!IsStringArg(rArg))
- return MIstatus::failure;
-
- m_bFound = true;
-
- if (vrwArgContext.RemoveArg(rArg)) {
- m_bValid = true;
- const char cQuote = '"';
- m_argValue = rArg.Trim(cQuote).StripSlashes();
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValString::IsStringArg(const CMIUtilString &vrTxt) const {
- if (m_bHandleQuotedString)
- return (IsStringArgQuotedText(vrTxt) ||
- IsStringArgQuotedTextEmbedded(vrTxt) ||
- IsStringArgQuotedQuotedTextEmbedded(vrTxt) ||
- IsStringArgSingleText(
- vrTxt)); // Still test for this as could just be one word still
-
- return IsStringArgSingleText(vrTxt);
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument or
-// option value. If the string looks like a long option, short option,
-// a thread
-// group ID or just a number it is rejected as a string type value.
-// There is an
-// option to allow the string to accept a number as a string type.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid argument value, false = something else.
-// Throws: None.
-//--
-bool CMICmdArgValString::IsStringArgSingleText(
- const CMIUtilString &vrTxt) const {
- if (!m_bHandleDirPaths) {
- // Look for directory file paths, if found reject
- const bool bHavePosSlash = (vrTxt.find('/') != std::string::npos);
- const bool bHaveBckSlash = (vrTxt.find('\\') != std::string::npos);
- if (bHavePosSlash || bHaveBckSlash)
- return false;
- }
-
- // Look for --someLongOption, if found reject
- if (0 == vrTxt.find("--"))
- return false;
-
- // Look for -f type short options, if found reject
- if ((0 == vrTxt.find('-')) && (vrTxt.length() == 2))
- return false;
-
- // Look for thread group i1 i2 i3...., if found reject
- if ((vrTxt.find('i') == 0) && ::isdigit(vrTxt[1]))
- return false;
-
- // Look for numbers, if found reject
- if (!m_bAcceptNumbers && vrTxt.IsNumber())
- return false;
-
- return true;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Take into account quotes surrounding the text. Note this function
-// falls
-// through to IsStringArgSingleText() should the criteria match fail.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValString::IsStringArgQuotedText(
- const CMIUtilString &vrTxt) const {
- // Accept anything as string word
- if (m_bHandleAnything)
- return true;
-
- // CODETAG_QUOTEDTEXT_SIMILAR_CODE
- const char cQuote = '"';
- const size_t nPos = vrTxt.find(cQuote);
- if (nPos == std::string::npos)
- return false;
-
- // Is one and only quote at end of the string
- if (nPos == (vrTxt.length() - 1))
- return false;
-
- // Quote must be the first character in the string or be preceded by a space
- // Also check for embedded string formating quote
- const char cBckSlash = '\\';
- const char cSpace = ' ';
- if ((nPos > 1) && (vrTxt[nPos - 1] == cBckSlash) &&
- (vrTxt[nPos - 2] != cSpace)) {
- return false;
- }
- if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
- return false;
-
- // Need to find the other quote
- const size_t nPos2 = vrTxt.rfind(cQuote);
- if (nPos2 == std::string::npos)
- return false;
-
- // Make sure not same quote, need two quotes
- if (nPos == nPos2)
- return MIstatus::failure;
-
- return true;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Take into account quotes surrounding the text. Take into account
-// string format
-// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
-// function falls
-// through to IsStringArgQuotedText() should the criteria match fail.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValString::IsStringArgQuotedTextEmbedded(
- const CMIUtilString &vrTxt) const {
- // CODETAG_QUOTEDTEXT_SIMILAR_CODE
- const char cBckSlash = '\\';
- const size_t nPos = vrTxt.find(cBckSlash);
- if (nPos == std::string::npos)
- return false;
-
- // Slash must be the first character in the string or be preceded by a space
- const char cSpace = ' ';
- if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
- return false;
-
- // Need to find the other matching slash
- const size_t nPos2 = vrTxt.rfind(cBckSlash);
- if (nPos2 == std::string::npos)
- return false;
-
- // Make sure not same back slash, need two slashes
- if (nPos == nPos2)
- return MIstatus::failure;
-
- return false;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Take into account quotes surrounding the text. Take into account
-// string format
-// embedded quotes surrounding the text i.e. "\\\"%5d\\\"". Note this
-// function falls
-// through to IsStringArgQuotedTextEmbedded() should the criteria match
-// fail.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(
- const CMIUtilString &vrTxt) const {
- const size_t nPos = vrTxt.find("\"\\\"");
- if (nPos == std::string::npos)
- return false;
-
- const size_t nPos2 = vrTxt.rfind("\\\"\"");
- if (nPos2 == std::string::npos)
- return false;
-
- const size_t nLen = vrTxt.length();
- return !((nLen > 5) && ((nPos + 2) == (nPos2 - 2)));
-}
diff --git a/tools/lldb-mi/MICmdArgValString.h b/tools/lldb-mi/MICmdArgValString.h
deleted file mode 100644
index 77041c2d0c9f..000000000000
--- a/tools/lldb-mi/MICmdArgValString.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- MICmdArgValString.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it .
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValString : public CMICmdArgValBaseTemplate<CMIUtilString> {
- // Methods:
-public:
- /* ctor */ CMICmdArgValString();
- /* ctor */ CMICmdArgValString(const bool vbAnything);
- /* ctor */ CMICmdArgValString(const bool vbHandleQuotes,
- const bool vbAcceptNumbers,
- const bool vbHandleDirPaths);
- /* ctor */ CMICmdArgValString(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const bool vbHandleQuotes = false,
- const bool vbAcceptNumbers = false);
- /* ctor */ CMICmdArgValString(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd,
- const bool vbHandleQuotes,
- const bool vbAcceptNumbers,
- const bool vbHandleDirPaths);
- //
- bool IsStringArg(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValString() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vrwArgContext) override;
-
- // Methods:
-private:
- bool ValidateSingleText(CMICmdArgContext &vrwArgContext);
- bool ValidateQuotedText(CMICmdArgContext &vrwArgContext);
- bool ValidateQuotedTextEmbedded(CMICmdArgContext &vrwArgContext);
- bool ValidateQuotedQuotedTextEmbedded(CMICmdArgContext &vrwArgContext);
- bool IsStringArgSingleText(const CMIUtilString &vrTxt) const;
- bool IsStringArgQuotedText(const CMIUtilString &vrTxt) const;
- bool IsStringArgQuotedTextEmbedded(const CMIUtilString &vrTxt) const;
- bool IsStringArgQuotedQuotedTextEmbedded(const CMIUtilString &vrTxt) const;
-
- // Attribute:
-private:
- bool m_bHandleQuotedString; // True = Parse a string surrounded by quotes
- // spaces are not delimiters, false = only text up
- // to next
- // delimiting space character
- bool m_bAcceptNumbers; // True = Parse a string and accept as a number if
- // number, false = numbers not recognised as string
- // types
- bool m_bHandleDirPaths; // True = Parse a string and accept directory file
- // style string if present, false = directory file
- // path not
- // accepted
- bool m_bHandleAnything; // True = Parse a string and accept anything if
- // present, false = validate for criteria matches
-};
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.cpp b/tools/lldb-mi/MICmdArgValThreadGrp.cpp
deleted file mode 100644
index 201d516525fd..000000000000
--- a/tools/lldb-mi/MICmdArgValThreadGrp.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- MICmdArgValThreadGrp.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdArgContext.h"
-
-//++
-// Details: CMICmdArgValThreadGrp constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValThreadGrp::CMICmdArgValThreadGrp() : m_nThreadGrp(0) {}
-
-//++
-// Details: CMICmdArgValThreadGrp constructor.
-// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional
-// argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false =
-// not handled.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValThreadGrp::CMICmdArgValThreadGrp(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd)
- : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd),
- m_nThreadGrp(0) {}
-
-//++
-// Details: CMICmdArgValThreadGrp destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdArgValThreadGrp::~CMICmdArgValThreadGrp() {}
-
-//++
-// Details: Parse the command's argument options string and try to extract the
-// value *this
-// argument is looking for.
-// Type: Overridden.
-// Args: vwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValThreadGrp::Validate(CMICmdArgContext &vwArgContext) {
- if (vwArgContext.IsEmpty())
- return m_bMandatory ? MIstatus::failure : MIstatus::success;
-
- if (vwArgContext.GetNumberArgsPresent() == 1) {
- const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
- if (IsArgThreadGrp(rArg) && ExtractNumber(rArg)) {
- m_bFound = true;
- m_bValid = true;
- m_argValue = GetNumber();
- vwArgContext.RemoveArg(rArg);
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // More than one option...
- const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
- CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
- while (it != vecOptions.end()) {
- const CMIUtilString &rArg(*it);
- if (IsArgThreadGrp(rArg) && ExtractNumber(rArg)) {
- m_bFound = true;
-
- if (vwArgContext.RemoveArg(rArg)) {
- m_bValid = true;
- m_argValue = GetNumber();
- return MIstatus::success;
- } else
- return MIstatus::failure;
- }
-
- // Next
- ++it;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Examine the string and determine if it is a valid string type
-// argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: bool - True = yes valid arg, false = no.
-// Throws: None.
-//--
-bool CMICmdArgValThreadGrp::IsArgThreadGrp(const CMIUtilString &vrTxt) const {
- // Look for i1 i2 i3....
- const MIint nPos = vrTxt.find('i');
- if (nPos != 0)
- return false;
-
- const CMIUtilString strNum = vrTxt.substr(1);
- return strNum.IsNumber();
-}
-
-//++
-// Details: Extract the thread group number from the thread group argument.
-// Type: Method.
-// Args: vrTxt - (R) Some text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdArgValThreadGrp::ExtractNumber(const CMIUtilString &vrTxt) {
- const CMIUtilString strNum = vrTxt.substr(1);
- MIint64 nNumber = 0;
- bool bOk = strNum.ExtractNumber(nNumber);
- if (bOk) {
- m_nThreadGrp = static_cast<MIuint>(nNumber);
- }
-
- return bOk;
-}
-
-//++
-// Details: Retrieve the thread group ID found in the argument.
-// Type: Method.
-// Args: None.
-// Return: MIuint - Thread group ID.
-// Throws: None.
-//--
-MIuint CMICmdArgValThreadGrp::GetNumber() const { return m_nThreadGrp; }
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.h b/tools/lldb-mi/MICmdArgValThreadGrp.h
deleted file mode 100644
index 12d3a1e90244..000000000000
--- a/tools/lldb-mi/MICmdArgValThreadGrp.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- MICmdArgValThreadGrp.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdArgValBase.h"
-
-// Declarations:
-class CMICmdArgContext;
-
-//++
-//============================================================================
-// Details: MI common code class. Command argument class. Arguments object
-// needing specialization derived from the CMICmdArgValBase class.
-// An argument knows what type of argument it is and how it is to
-// interpret the options (context) string to find and validate a
-// matching
-// argument and so extract a value from it. Thread group looks like
-// "i1" in the options text.
-// Based on the Interpreter pattern.
-//--
-class CMICmdArgValThreadGrp : public CMICmdArgValBaseTemplate<MIuint> {
- // Methods:
-public:
- /* ctor */ CMICmdArgValThreadGrp();
- /* ctor */ CMICmdArgValThreadGrp(const CMIUtilString &vrArgName,
- const bool vbMandatory,
- const bool vbHandleByCmd);
- //
- bool IsArgThreadGrp(const CMIUtilString &vrTxt) const;
-
- // Overridden:
-public:
- // From CMICmdArgValBase
- /* dtor */ ~CMICmdArgValThreadGrp() override;
- // From CMICmdArgSet::IArg
- bool Validate(CMICmdArgContext &vArgContext) override;
-
- // Methods:
-private:
- bool ExtractNumber(const CMIUtilString &vrTxt);
- MIuint GetNumber() const;
-
- // Attributes:
-private:
- MIuint m_nThreadGrp;
-};
diff --git a/tools/lldb-mi/MICmdBase.cpp b/tools/lldb-mi/MICmdBase.cpp
deleted file mode 100644
index df36cfe86420..000000000000
--- a/tools/lldb-mi/MICmdBase.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-//===-- MICmdBase.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmdArgValConsume.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdBase::CMICmdBase()
- : m_pSelfCreatorFn(nullptr),
- m_rLLDBDebugSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()),
- m_bHasResultRecordExtra(false), m_constStrArgThreadGroup("thread-group"),
- m_constStrArgThread("thread"), m_constStrArgFrame("frame"),
- m_constStrArgConsume("--"), m_ThreadGrpArgMandatory(false),
- m_ThreadArgMandatory(false), m_FrameArgMandatory(false) {}
-
-//++
-// Details: CMICmdBase destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdBase::~CMICmdBase() {}
-
-//++
-// Details: The invoker requires this function.
-// Type: Overridden.
-// Args: None.
-// Return: SMICmdData & - *this command's present status/data/information.
-// Throws: None.
-//--
-const SMICmdData &CMICmdBase::GetCmdData() const { return m_cmdData; }
-
-//++
-// Details: The invoker requires this function.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - *this command's current error description.
-// Empty string indicates command status ok.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdBase::GetErrorDescription() const {
- return m_strCurrentErrDescription;
-}
-
-//++
-// Details: The CMICmdFactory requires this function. Retrieve the command and
-// argument
-// options description string.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Command description.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdBase::GetMiCmd() const { return m_strMiCmd; }
-
-//++
-// Details: Help parse the arguments that are common to all commands.
-// Args: None.
-// Return: None
-// Throws: None.
-//--
-void CMICmdBase::AddCommonArgs() {
- m_setCmdArgs.Add(new CMICmdArgValOptionLong(
- m_constStrArgThreadGroup, m_ThreadGrpArgMandatory, true,
- CMICmdArgValListBase::eArgValType_ThreadGrp, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionLong(
- m_constStrArgThread, m_ThreadArgMandatory, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionLong(m_constStrArgFrame, m_FrameArgMandatory, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(new CMICmdArgValConsume(m_constStrArgConsume, false));
-}
-
-//++
-// Details: The invoker requires this function. A command must be given working
-// data and
-// provide data about its status or provide information to other
-// objects.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdBase::SetCmdData(const SMICmdData &vCmdData) {
- m_cmdData = vCmdData;
-}
-
-//++
-// Details: The command factory requires this function. The factory calls this
-// function
-// so it can obtain *this command's creation function.
-// Type: Overridden.
-// Args: None.
-// Return: CMICmdFactory::CmdCreatorFnPtr - Function pointer.
-// Throws: None.
-//--
-CMICmdFactory::CmdCreatorFnPtr CMICmdBase::GetCmdCreatorFn() const {
- return m_pSelfCreatorFn;
-}
-
-//++
-// Details: If a command is an event type (has callbacks registered with
-// SBListener) it
-// needs to inform the Invoker that it has finished its work so that
-// the
-// Invoker can tidy up and call the commands Acknowledge function (yes
-// the
-// command itself could call the Acknowledge itself but not doing that
-// way).
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdBase::CmdFinishedTellInvoker() const {
- CMICmdInvoker::Instance().CmdExecuteFinished(const_cast<CMICmdBase &>(*this));
-}
-
-//++
-// Details: Returns the final version of the MI result record built up in the
-// command's
-// Acknowledge function. The one line text of MI result.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - MI text version of the MI result record.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdBase::GetMIResultRecord() const {
- return m_miResultRecord.GetString();
-}
-
-//++
-// Details: Retrieve from the command additional MI result to its 1 line
-// response.
-// Because of using LLDB additional 'fake'/hack output is sometimes
-// required to
-// help the driver client operate i.e. Eclipse.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - MI text version of the MI result record.
-// Throws: None.
-//--
-const CMIUtilString &CMICmdBase::GetMIResultRecordExtra() const {
- return m_miResultRecordExtra;
-}
-
-//++
-// Details: Hss *this command got additional MI result to its 1 line response.
-// Because of using LLDB additional 'fake'/hack output is sometimes
-// required to
-// help the driver client operate i.e. Eclipse.
-// Type: Overridden.
-// Args: None.
-// Return: bool - True = Yes have additional MI output, false = no nothing
-// extra.
-// Throws: None.
-//--
-bool CMICmdBase::HasMIResultRecordExtra() const {
- return m_bHasResultRecordExtra;
-}
-
-//++
-// Details: Short cut function to enter error information into the command's
-// metadata
-// object and set the command's error status.
-// Type: Method.
-// Args: rErrMsg - (R) Status description.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdBase::SetError(const CMIUtilString &rErrMsg) {
- m_cmdData.bCmdValid = false;
- m_cmdData.strErrorDescription = rErrMsg;
- m_cmdData.bCmdExecutedSuccessfully = false;
-
- const CMICmnMIValueResult valueResult("msg", CMICmnMIValueConst(rErrMsg));
- const CMICmnMIResultRecord miResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- valueResult);
- m_miResultRecord = miResultRecord;
- m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
-}
-
-//++
-// Details: Short cut function to check MI command's execute status and
-// set an error in case of failure.
-// Type: Method.
-// Args: error - (R) Error description object.
-// successHandler - (R) function describing actions to execute
-// in case of success state of passed SBError object.
-// errorHandler - (R) function describing actions to execute
-// in case of fail status of passed SBError object.
-// Return: bool.
-// Throws: None.
-//--
-bool CMICmdBase::HandleSBError(const lldb::SBError &error,
- const std::function<bool()> &successHandler,
- const std::function<void()> &errorHandler) {
- if (error.Success())
- return successHandler();
-
- SetError(error.GetCString());
- errorHandler();
- return MIstatus::failure;
-}
-
-//++
-// Details: Short cut function to check MI command's execute status and
-// call specified handler function for success case.
-// Type: Method.
-// Args: error - (R) Error description object.
-// successHandler - (R) function describing actions to execute
-// in case of success state of passed SBError object.
-// Return: bool.
-// Throws: None.
-//--
-bool CMICmdBase::HandleSBErrorWithSuccess(
- const lldb::SBError &error,
- const std::function<bool()> &successHandler) {
- return HandleSBError(error, successHandler);
-}
-
-//++
-// Details: Short cut function to check MI command's execute status and
-// call specified handler function for error case.
-// Type: Method.
-// Args: error - (R) Error description object.
-// errorHandler - (R) function describing actions to execute
-// in case of fail status of passed SBError object.
-// Return: bool.
-// Throws: None.
-//--
-bool CMICmdBase::HandleSBErrorWithFailure(
- const lldb::SBError &error,
- const std::function<void()> &errorHandler) {
- return HandleSBError(error, [] { return MIstatus::success; }, errorHandler);
-}
-
-//++
-// Details: Ask a command to provide its unique identifier.
-// Type: Method.
-// Args: A unique identifier for this command class.
-// Return: None.
-// Throws: None.
-//--
-MIuint CMICmdBase::GetGUID() {
- MIuint64 vptr = reinterpret_cast<MIuint64>(this);
- MIuint id = (vptr)&0xFFFFFFFF;
- id ^= (vptr >> 32) & 0xFFFFFFFF;
-
- return id;
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdBase::ParseArgs() {
- // Do nothing - override to implement
-
- return MIstatus::success;
-}
-
-//++
-// Details: Having previously given CMICmdArgSet m_setCmdArgs all the argument
-// or option
-// definitions for the command to handle proceed to parse and validate
-// the
-// command's options text for those arguments and extract the values
-// for each if
-// any.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdBase::ParseValidateCmdOptions() {
- CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
- if (m_setCmdArgs.Validate(m_cmdData.strMiCmd, argCntxt))
- return MIstatus::success;
-
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ARGS),
- m_cmdData.strMiCmd.c_str(),
- m_setCmdArgs.GetErrorDescription().c_str()));
-
- return MIstatus::failure;
-}
-
-//++
-// Details: If the MI Driver is not operating via a client i.e. Eclipse but say
-// operating
-// on a executable passed in as a argument to the drive then what
-// should the driver
-// do on a command failing? Either continue operating or exit the
-// application.
-// Override this function where a command failure cannot allow the
-// driver to
-// continue operating.
-// Type: Overrideable.
-// Args: None.
-// Return: bool - True = Fatal if command fails, false = can continue if
-// command fails.
-// Throws: None.
-//--
-bool CMICmdBase::GetExitAppOnCommandFailure() const { return false; }
diff --git a/tools/lldb-mi/MICmdBase.h b/tools/lldb-mi/MICmdBase.h
deleted file mode 100644
index 4e32ed6a5262..000000000000
--- a/tools/lldb-mi/MICmdBase.h
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- MICmdBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-#include <functional>
-
-#include "lldb/API/SBError.h"
-
-#include "MICmdArgSet.h"
-#include "MICmdData.h"
-#include "MICmdFactory.h"
-#include "MICmdInvoker.h"
-#include "MICmnBase.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnResources.h"
-#include "MIUtilString.h"
-
-// Declarations:
-class CMICmnLLDBDebugSessionInfo;
-
-//++
-//============================================================================
-// Details: MI command base class. MI commands derive from this base class.
-// The Command Factory creates command objects and passes them to the
-// Command Invoker. The Invoker takes ownership of any commands created
-// which means it is the only object to delete them when a command is
-// finished working. Commands do not delete themselves.
-// There are two types of command implicitly defined by the state of
-// the m_bWaitForEventFromSBDebugger flag. There is the event type
-// command which registers (command fn) callbacks with the SBListener
-// does some work then wakes up again when called back, does more work
-// perhaps, ends, then the Invoker calls the command's Acknowledge
-// function. The other type of command is one that just does some work,
-// ends, then the Invoker calls the command's Acknowledge function. No
-// events set up.
-// A command's Execute(), Acknowledge() and event callback functions
-// are
-// carried out in the main thread.
-// A command may use the argument derived object classes
-// (CMICmdArgValBase)
-// to factor handling and parsing of different types of arguments
-// presented to a command. A command will produce an error should it
-// be presented with arguments or options it does not understand.
-//--
-class CMICmdBase : public CMICmnBase,
- public CMICmdInvoker::ICmd,
- public CMICmdFactory::ICmd {
- // Methods:
-public:
- CMICmdBase();
-
- // Overridden:
- // From CMICmdInvoker::ICmd
- const SMICmdData &GetCmdData() const override;
- const CMIUtilString &GetErrorDescription() const override;
- void SetCmdData(const SMICmdData &vCmdData) override;
- void CmdFinishedTellInvoker() const override;
- const CMIUtilString &GetMIResultRecord() const override;
- const CMIUtilString &GetMIResultRecordExtra() const override;
- bool HasMIResultRecordExtra() const override;
- bool ParseArgs() override;
- // From CMICmdFactory::ICmd
- const CMIUtilString &GetMiCmd() const override;
- CMICmdFactory::CmdCreatorFnPtr GetCmdCreatorFn() const override;
-
- virtual MIuint GetGUID();
- void AddCommonArgs();
-
- // Overrideable:
- ~CMICmdBase() override;
- virtual bool GetExitAppOnCommandFailure() const;
-
- // Methods:
-protected:
- void SetError(const CMIUtilString &rErrMsg);
- bool HandleSBError(const lldb::SBError &error,
- const std::function<bool()> &successHandler =
- [] { return MIstatus::success; },
- const std::function<void()> &errorHandler = [] {});
- bool HandleSBErrorWithSuccess(const lldb::SBError &error,
- const std::function<bool()> &successHandler);
- bool HandleSBErrorWithFailure(const lldb::SBError &error,
- const std::function<void()> &errorHandler);
- template <class T> T *GetOption(const CMIUtilString &vStrOptionName);
- bool ParseValidateCmdOptions();
-
- // Attributes:
- CMICmdFactory::CmdCreatorFnPtr m_pSelfCreatorFn;
- CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge
- // function failure
- SMICmdData m_cmdData; // Holds information/status of *this command. Used by
- // other MI code to report or determine state of a
- // command.
- bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait,
- // false = command calls Acknowledge()
- // straight after Execute()
- // no waiting
- CMIUtilString
- m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert'
- CMICmnMIResultRecord m_miResultRecord; // This is completed in the
- // Acknowledge() function and returned
- // to the Command Invoker to proceed
- // stdout output. Each command forms 1 response to its input.
- CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge()
- // function and returned to the Command
- // Invoker to proceed
- // stdout output. Hack command produce more response text to help the client
- // because of using LLDB
- CMICmnLLDBDebugSessionInfo &m_rLLDBDebugSessionInfo; // Access to command
- // sharing information or
- // data across any and
- // all command based
- // derived classes.
- bool m_bHasResultRecordExtra; // True = Yes command produced additional MI
- // output to its 1 line response, false = no
- // extra MI output
- // formed.
- CMICmdArgSet m_setCmdArgs; // The list of arguments *this command needs to
- // parse from the options string to carry out work.
- const CMIUtilString m_constStrArgThreadGroup;
- const CMIUtilString m_constStrArgThread;
- const CMIUtilString m_constStrArgFrame;
- const CMIUtilString m_constStrArgConsume;
-
- // These 3 members can be used by the derived classes to make any of
- // "thread", "frame" or "thread-group" mandatory.
- bool m_ThreadGrpArgMandatory;
- bool m_ThreadArgMandatory;
- bool m_FrameArgMandatory;
-};
-
-//++
-// Details: Retrieve the command argument or option object pointer so that it
-// can be
-// examined. If the option found and valid get the value (number,
-// string or list
-// - see CMICmdArgValBase class) from it to use with the command's
-// decision
-// making. If the argument is not found the command's error description
-// is set
-// describing the error condition.
-// Type: Template method.
-// Args: vStrOptionName - (R) The text name of the argument or option to
-// search for in
-// the list of the command's possible arguments
-// or options.
-// Return: T * - CMICmdArgValBase derived object.
-// - nullptr = function has failed, unable to retrieve the
-// option/arg object.
-// Throws: None.
-//--
-template <class T>
-T *CMICmdBase::GetOption(const CMIUtilString &vStrOptionName) {
- CMICmdArgValBase *pPtrBase = nullptr;
- if (!m_setCmdArgs.GetArg(vStrOptionName, pPtrBase)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- vStrOptionName.c_str()));
- return nullptr;
- }
-
- return static_cast<T *>(pPtrBase);
-}
-
-//++
-// Details: Retrieve the command argument or option object pointer using
-// template function
-// CMICmdBase::GetOption(). Should the argument (by name) not be found
-// the
-// command will exit with a failure (set in GetOption()).
-// Type: Preprocessor macro.
-// Args: a - (R) The actual variable's name.
-// b - (R) The type of variable (appended to CMICmdArgVal i.e.
-// CMICmdArgValString).
-// c - (R) The text name of the argument or option to search for in
-// the list of
-// the command's possible arguments or options.
-// Return: T * - CMICmdArgValBase derived object.
-// - nullptr = function has failed, unable to retrieve the
-// option/arg object.
-// Throws: None.
-//--
-#define CMICMDBASE_GETOPTION(a, b, c) \
- CMICmdArgVal##b *a = CMICmdBase::GetOption<CMICmdArgVal##b>(c); \
- if (a == nullptr) \
- return MIstatus::failure;
-// This comment is to stop compile warning for #define
diff --git a/tools/lldb-mi/MICmdCmd.cpp b/tools/lldb-mi/MICmdCmd.cpp
deleted file mode 100644
index 081cff6fa51f..000000000000
--- a/tools/lldb-mi/MICmdCmd.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//===-- MICmdCmd.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdEnablePrettyPrinting implementation.
-// CMICmdCmdSource implementation.
-//
-
-// In-house headers:
-#include "MICmdCmd.h"
-
-//++
-// Details: CMICmdCmdEnablePrettyPrinting constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdEnablePrettyPrinting::CMICmdCmdEnablePrettyPrinting() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "enable-pretty-printing";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdEnablePrettyPrinting::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdEnablePrettyPrinting destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdEnablePrettyPrinting::~CMICmdCmdEnablePrettyPrinting() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdEnablePrettyPrinting::Execute() {
- // Do nothing
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdEnablePrettyPrinting::Acknowledge() {
- const CMICmnMIValueConst miValueConst("0");
- const CMICmnMIValueResult miValueResult("supported", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdEnablePrettyPrinting::CreateSelf() {
- return new CMICmdCmdEnablePrettyPrinting();
-}
-
-
-//++
-// Details: CMICmdCmdSource constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSource::CMICmdCmdSource() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "source";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdSource::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdSource destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSource::~CMICmdCmdSource() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSource::Execute() {
- // Do nothing
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSource::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdSource::CreateSelf() { return new CMICmdCmdSource(); }
diff --git a/tools/lldb-mi/MICmdCmd.h b/tools/lldb-mi/MICmdCmd.h
deleted file mode 100644
index aeaaa4b01db6..000000000000
--- a/tools/lldb-mi/MICmdCmd.h
+++ /dev/null
@@ -1,90 +0,0 @@
-//===-- MICmdCmd.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdEnablePrettyPrinting interface.
-// CMICmdCmdSource interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-/*
-MI commands implemented are:
- See MICmdCommands.cpp
-*/
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBBreakpoint.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include <vector>
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "enable-pretty-printing".
-// Enables Python base pretty printing.
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Variable-Objects.html
-//--
-class CMICmdCmdEnablePrettyPrinting : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdEnablePrettyPrinting();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdEnablePrettyPrinting() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "source".
-//--
-class CMICmdCmdSource : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdSource();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdSource() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp
deleted file mode 100644
index 1cd0bacf51d5..000000000000
--- a/tools/lldb-mi/MICmdCmdBreak.cpp
+++ /dev/null
@@ -1,1024 +0,0 @@
-//===-- MICmdCmdBreak.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdBreakInsert implementation.
-// CMICmdCmdBreakDelete implementation.
-// CMICmdCmdBreakDisable implementation.
-// CMICmdCmdBreakEnable implementation.
-// CMICmdCmdBreakAfter implementation.
-// CMICmdCmdBreakCondition implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBBreakpointLocation.h"
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdBreak.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnStreamStdout.h"
-
-//++
-// Details: CMICmdCmdBreakInsert constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakInsert::CMICmdCmdBreakInsert()
- : m_bBrkPtIsTemp(false), m_bBrkPtIsPending(false), m_nBrkPtIgnoreCount(0),
- m_bBrkPtEnabled(false), m_bBrkPtCondition(false), m_bBrkPtThreadId(false),
- m_nBrkPtThreadId(0), m_constStrArgNamedTempBrkPt("t"),
- m_constStrArgNamedHWBrkPt("h"), m_constStrArgNamedPendinfBrkPt("f"),
- m_constStrArgNamedDisableBrkPt("d"), m_constStrArgNamedTracePt("a"),
- m_constStrArgNamedConditionalBrkPt("c"), m_constStrArgNamedInoreCnt("i"),
- m_constStrArgNamedRestrictBrkPtToThreadId("p"),
- m_constStrArgNamedLocation("location") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-insert";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakInsert destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakInsert::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgNamedTempBrkPt, false, true));
- // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- // m_constStrArgNamedHWBrkPt, false, false));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgNamedPendinfBrkPt, false, true,
- CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedDisableBrkPt,
- false, false));
- // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- // m_constStrArgNamedTracePt, false, false));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgNamedConditionalBrkPt, false, true,
- CMICmdArgValListBase::eArgValType_StringQuoted, 1));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgNamedInoreCnt, false, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgNamedRestrictBrkPtToThreadId, false, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedLocation, false,
- true, false, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Helper function for CMICmdCmdBreakInsert::Execute().
-//
-// Given a string, return the position of the ':' separator in 'file:func'
-// or 'file:line', if any. If not found, return npos. For example, return
-// 5 for 'foo.c:std::string'.
-//--
-static size_t findFileSeparatorPos(const std::string &x) {
- // Full paths in windows can have ':' after a drive letter, so we
- // search backwards, taking care to skip C++ namespace tokens '::'.
- size_t n = x.rfind(':');
- while (n != std::string::npos && n > 1 && x[n - 1] == ':') {
- n = x.rfind(':', n - 2);
- }
- return n;
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakInsert::Execute() {
- CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
- CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgThreadGroup);
- CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
- CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
- CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort,
- m_constStrArgNamedPendinfBrkPt);
- CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort,
- m_constStrArgNamedDisableBrkPt);
- CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort,
- m_constStrArgNamedConditionalBrkPt);
- CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort,
- m_constStrArgNamedRestrictBrkPtToThreadId);
-
- // Ask LLDB for the target to check if we have valid or dummy one.
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
-
- m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
- m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
- m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
- if (m_bHaveArgOptionThreadGrp) {
- MIuint nThreadGrp = 0;
- pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(
- nThreadGrp);
- m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
- }
-
- if (sbTarget == rSessionInfo.GetDebugger().GetDummyTarget())
- m_bBrkPtIsPending = true;
- else {
- m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
- if (!m_bBrkPtIsPending) {
- CMIUtilString pending;
- if (m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending", pending)) {
- m_bBrkPtIsPending = pending == "on";
- }
- }
- }
-
- if (pArgLocation->GetFound())
- m_brkName = pArgLocation->GetValue();
- else if (m_bBrkPtIsPending) {
- pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- m_brkName);
- }
- if (pArgIgnoreCnt->GetFound()) {
- pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(
- m_nBrkPtIgnoreCount);
- }
- m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
- if (m_bBrkPtCondition) {
- pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- m_brkPtCondition);
- }
- m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
- if (m_bBrkPtCondition) {
- pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(
- m_nBrkPtThreadId);
- }
-
- // Determine if break on a file line or at a function
- BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
- CMIUtilString fileName;
- MIuint nFileLine = 0;
- CMIUtilString strFileFn;
- CMIUtilString rStrLineOrFn;
- // Is the string in the form 'file:func' or 'file:line'?
- // If so, find the position of the ':' separator.
- const size_t nPosColon = findFileSeparatorPos(m_brkName);
- if (nPosColon != std::string::npos) {
- // Extract file name and line number from it
- fileName = m_brkName.substr(0, nPosColon);
- rStrLineOrFn =
- m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);
-
- if (rStrLineOrFn.empty())
- eBrkPtType = eBreakPoint_ByName;
- else {
- MIint64 nValue = 0;
- if (rStrLineOrFn.ExtractNumber(nValue)) {
- nFileLine = static_cast<MIuint>(nValue);
- eBrkPtType = eBreakPoint_ByFileLine;
- } else {
- strFileFn = rStrLineOrFn;
- eBrkPtType = eBreakPoint_ByFileFn;
- }
- }
- }
-
- // Determine if break defined as an address
- lldb::addr_t nAddress = 0;
- if (eBrkPtType == eBreakPoint_NotDefineYet) {
- MIint64 nValue = 0;
- if (m_brkName.ExtractNumber(nValue)) {
- nAddress = static_cast<lldb::addr_t>(nValue);
- eBrkPtType = eBreakPoint_ByAddress;
- }
- }
-
- // Break defined as an function
- if (eBrkPtType == eBreakPoint_NotDefineYet) {
- eBrkPtType = eBreakPoint_ByName;
- }
-
- // Ask LLDB to create a breakpoint
- bool bOk = MIstatus::success;
- switch (eBrkPtType) {
- case eBreakPoint_ByAddress:
- m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
- break;
- case eBreakPoint_ByFileFn: {
- lldb::SBFileSpecList module; // search in all modules
- lldb::SBFileSpecList compUnit;
- compUnit.Append(lldb::SBFileSpec(fileName.c_str()));
- m_brkPt =
- sbTarget.BreakpointCreateByName(strFileFn.c_str(), module, compUnit);
- break;
- }
- case eBreakPoint_ByFileLine:
- m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
- break;
- case eBreakPoint_ByName:
- m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
- break;
- case eBreakPoint_count:
- case eBreakPoint_NotDefineYet:
- case eBreakPoint_Invalid:
- bOk = MIstatus::failure;
- break;
- }
-
- if (bOk) {
- if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0)) {
- sbTarget.BreakpointDelete(m_brkPt.GetID());
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
- return MIstatus::failure;
- }
-
- m_brkPt.SetEnabled(m_bBrkPtEnabled);
- m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
- if (m_bBrkPtCondition)
- m_brkPt.SetCondition(m_brkPtCondition.c_str());
- if (m_bBrkPtThreadId)
- m_brkPt.SetThreadID(m_nBrkPtThreadId);
- }
-
- // CODETAG_LLDB_BREAKPOINT_CREATION
- // This is in the main thread
- // Record break point information to be by LLDB event handler function
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
- return MIstatus::failure;
- sBrkPtInfo.m_id = m_brkPt.GetID();
- sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
- sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
- sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
- sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
- sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
- sBrkPtInfo.m_strOrigLoc = m_brkName;
- sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
- sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
- sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
- sBrkPtInfo.m_strCondition = m_brkPtCondition;
- sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
- sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
-
- bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
- if (!bOk) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_brkName.c_str()));
- return MIstatus::failure;
- }
-
- // CODETAG_LLDB_BRKPT_ID_MAX
- if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(),
- rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakInsert::Acknowledge() {
- // Get breakpoint information
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.RecordBrkPtInfoGet(m_brkPt.GetID(), sBrkPtInfo))
- return MIstatus::failure;
-
- // MI print
- // "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
- // PRIx64
- // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
- CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
- return MIstatus::failure;
-
- const CMICmnMIValueResult miValueResultD("bkpt", miValueTuple);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResultD);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakInsert::CreateSelf() {
- return new CMICmdCmdBreakInsert();
-}
-
-
-//++
-// Details: CMICmdCmdBreakDelete constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakDelete::CMICmdCmdBreakDelete()
- : m_constStrArgNamedBrkPt("breakpoint") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-delete";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakDelete destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDelete::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
- CMICmdArgValListBase::eArgValType_Number));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDelete::Execute() {
- CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
-
- // ATM we only handle one break point ID
- MIuint64 nBrk = UINT64_MAX;
- if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgNamedBrkPt.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(
- static_cast<lldb::break_id_t>(nBrk));
- if (!bBrkPt) {
- const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- strBrkNum.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDelete::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakDelete::CreateSelf() {
- return new CMICmdCmdBreakDelete();
-}
-
-
-//++
-// Details: CMICmdCmdBreakDisable constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakDisable::CMICmdCmdBreakDisable()
- : m_constStrArgNamedBrkPt("breakpoint"), m_bBrkPtDisabledOk(false),
- m_nBrkPtId(0) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-disable";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakDisable destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDisable::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
- CMICmdArgValListBase::eArgValType_Number));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDisable::Execute() {
- CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
-
- // ATM we only handle one break point ID
- MIuint64 nBrk = UINT64_MAX;
- if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgNamedBrkPt.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
- static_cast<lldb::break_id_t>(nBrk));
- if (brkPt.IsValid()) {
- m_bBrkPtDisabledOk = true;
- brkPt.SetEnabled(false);
- m_nBrkPtId = nBrk;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakDisable::Acknowledge() {
- if (m_bBrkPtDisabledOk) {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakDisable::CreateSelf() {
- return new CMICmdCmdBreakDisable();
-}
-
-
-//++
-// Details: CMICmdCmdBreakEnable constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakEnable::CMICmdCmdBreakEnable()
- : m_constStrArgNamedBrkPt("breakpoint"), m_bBrkPtEnabledOk(false),
- m_nBrkPtId(0) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-enable";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakEnable destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakEnable::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true,
- CMICmdArgValListBase::eArgValType_Number));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakEnable::Execute() {
- CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
-
- // ATM we only handle one break point ID
- MIuint64 nBrk = UINT64_MAX;
- if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgNamedBrkPt.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
- static_cast<lldb::break_id_t>(nBrk));
- if (brkPt.IsValid()) {
- m_bBrkPtEnabledOk = true;
- brkPt.SetEnabled(true);
- m_nBrkPtId = nBrk;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakEnable::Acknowledge() {
- if (m_bBrkPtEnabledOk) {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakEnable::CreateSelf() {
- return new CMICmdCmdBreakEnable();
-}
-
-
-//++
-// Details: CMICmdCmdBreakAfter constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakAfter::CMICmdCmdBreakAfter()
- : m_constStrArgNamedNumber("number"), m_constStrArgNamedCount("count"),
- m_nBrkPtId(0), m_nBrkPtCount(0) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-after";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakAfter destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakAfter::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedCount, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakAfter::Execute() {
- CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
- CMICMDBASE_GETOPTION(pArgCount, Number, m_constStrArgNamedCount);
-
- m_nBrkPtId = pArgNumber->GetValue();
- m_nBrkPtCount = pArgCount->GetValue();
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
- static_cast<lldb::break_id_t>(m_nBrkPtId));
- if (brkPt.IsValid()) {
- brkPt.SetIgnoreCount(m_nBrkPtCount);
-
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
- return MIstatus::failure;
- }
- sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
- rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
- } else {
- const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- strBrkPtId.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakAfter::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakAfter::CreateSelf() {
- return new CMICmdCmdBreakAfter();
-}
-
-
-//++
-// Details: CMICmdCmdBreakCondition constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakCondition::CMICmdCmdBreakCondition()
- : m_constStrArgNamedNumber("number"), m_constStrArgNamedExpr("expr"),
- m_constStrArgNamedExprNoQuotes(
- "expression not surround by quotes") // Not specified in MI spec, we
- // need to handle expressions not
- // surrounded by quotes
- ,
- m_nBrkPtId(0) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "break-condition";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdBreakCondition destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakCondition::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgNamedExpr, true, true, true, true));
- m_setCmdArgs.Add(new CMICmdArgValListOfN(
- m_constStrArgNamedExprNoQuotes, false, false,
- CMICmdArgValListBase::eArgValType_StringQuotedNumber));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakCondition::Execute() {
- CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
- CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgNamedExpr);
-
- m_nBrkPtId = pArgNumber->GetValue();
- m_strBrkPtExpr = pArgExpr->GetValue();
- m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(
- static_cast<lldb::break_id_t>(m_nBrkPtId));
- if (brkPt.IsValid()) {
- brkPt.SetCondition(m_strBrkPtExpr.c_str());
-
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo)) {
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
- return MIstatus::failure;
- }
- sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
- rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
- } else {
- const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
- m_cmdData.strMiCmd.c_str(),
- strBrkPtId.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdBreakCondition::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdBreakCondition::CreateSelf() {
- return new CMICmdCmdBreakCondition();
-}
-
-//++
-// Details: A breakpoint expression can be passed to *this command as:
-// a single string i.e. '2' -> ok.
-// a quoted string i.e. "a > 100" -> ok
-// a non quoted string i.e. 'a > 100' -> not ok
-// CMICmdArgValString only extracts the first space separated string,
-// the "a".
-// This function using the optional argument type CMICmdArgValListOfN
-// collects
-// the rest of the expression so that is may be added to the 'a' part
-// to form a
-// complete expression string i.e. "a > 100".
-// If the expression value was guaranteed to be surrounded by quotes
-// them this
-// function would not be necessary.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Rest of the breakpoint expression.
-// Throws: None.
-//--
-CMIUtilString
-CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes() {
- CMIUtilString strExpression;
-
- CMICmdArgValListOfN *pArgExprNoQuotes =
- CMICmdBase::GetOption<CMICmdArgValListOfN>(
- m_constStrArgNamedExprNoQuotes);
- if (pArgExprNoQuotes != nullptr) {
- const CMICmdArgValListBase::VecArgObjPtr_t &rVecExprParts(
- pArgExprNoQuotes->GetExpectedOptions());
- if (!rVecExprParts.empty()) {
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it =
- rVecExprParts.begin();
- while (it != rVecExprParts.end()) {
- const CMICmdArgValString *pPartExpr =
- static_cast<CMICmdArgValString *>(*it);
- const CMIUtilString &rPartExpr = pPartExpr->GetValue();
- strExpression += " ";
- strExpression += rPartExpr;
-
- // Next
- ++it;
- }
- strExpression = strExpression.Trim();
- }
- }
-
- return strExpression;
-}
diff --git a/tools/lldb-mi/MICmdCmdBreak.h b/tools/lldb-mi/MICmdCmdBreak.h
deleted file mode 100644
index 00c5aa236eac..000000000000
--- a/tools/lldb-mi/MICmdCmdBreak.h
+++ /dev/null
@@ -1,262 +0,0 @@
-//===-- MICmdCmdBreak.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdBreakInsert interface.
-// CMICmdCmdBreakDelete interface.
-// CMICmdCmdBreakDisable interface.
-// CMICmdCmdBreakEnable interface.
-// CMICmdCmdBreakAfter interface.
-// CMICmdCmdBreakCondition interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBBreakpoint.h"
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-insert".
-// This command does not follow the MI documentation exactly.
-//--
-class CMICmdCmdBreakInsert : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakInsert();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakInsert() override;
-
- // Enumerations:
-private:
- //++ ===================================================================
- // Details: The type of break point give in the MI command text.
- //--
- enum BreakPoint_e {
- eBreakPoint_Invalid = 0,
- eBreakPoint_ByFileLine,
- eBreakPoint_ByFileFn,
- eBreakPoint_ByName,
- eBreakPoint_ByAddress,
- eBreakPoint_count,
- eBreakPoint_NotDefineYet
- };
-
- // Attributes:
-private:
- bool m_bBrkPtIsTemp;
- bool m_bHaveArgOptionThreadGrp;
- CMIUtilString m_brkName;
- CMIUtilString m_strArgOptionThreadGrp;
- lldb::SBBreakpoint m_brkPt;
- bool m_bBrkPtIsPending;
- MIuint m_nBrkPtIgnoreCount;
- bool m_bBrkPtEnabled;
- bool m_bBrkPtCondition;
- CMIUtilString m_brkPtCondition;
- bool m_bBrkPtThreadId;
- MIuint m_nBrkPtThreadId;
- const CMIUtilString m_constStrArgNamedTempBrkPt;
- const CMIUtilString m_constStrArgNamedHWBrkPt; // Not handled by *this command
- const CMIUtilString m_constStrArgNamedPendinfBrkPt;
- const CMIUtilString m_constStrArgNamedDisableBrkPt;
- const CMIUtilString m_constStrArgNamedTracePt; // Not handled by *this command
- const CMIUtilString m_constStrArgNamedConditionalBrkPt;
- const CMIUtilString m_constStrArgNamedInoreCnt;
- const CMIUtilString m_constStrArgNamedRestrictBrkPtToThreadId;
- const CMIUtilString m_constStrArgNamedLocation;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-delete".
-//--
-class CMICmdCmdBreakDelete : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakDelete();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakDelete() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedBrkPt;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-disable".
-//--
-class CMICmdCmdBreakDisable : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakDisable();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakDisable() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedBrkPt;
- bool m_bBrkPtDisabledOk;
- MIuint m_nBrkPtId;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-enable".
-//--
-class CMICmdCmdBreakEnable : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakEnable();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakEnable() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedBrkPt;
- bool m_bBrkPtEnabledOk;
- MIuint m_nBrkPtId;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-after".
-//--
-class CMICmdCmdBreakAfter : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakAfter();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakAfter() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedNumber;
- const CMIUtilString m_constStrArgNamedCount;
- MIuint m_nBrkPtId;
- MIuint m_nBrkPtCount;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "break-condition".
-//--
-class CMICmdCmdBreakCondition : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdBreakCondition();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdBreakCondition() override;
-
- // Methods:
-private:
- CMIUtilString GetRestOfExpressionNotSurroundedInQuotes();
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedNumber;
- const CMIUtilString m_constStrArgNamedExpr;
- const CMIUtilString m_constStrArgNamedExprNoQuotes; // Not specified in MI
- // spec, we need to handle
- // expressions not
- // surrounded by quotes
- MIuint m_nBrkPtId;
- CMIUtilString m_strBrkPtExpr;
-};
diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp
deleted file mode 100644
index e0a165765199..000000000000
--- a/tools/lldb-mi/MICmdCmdData.cpp
+++ /dev/null
@@ -1,1673 +0,0 @@
-//===-- MICmdCmdData.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdDataEvaluateExpression implementation.
-// CMICmdCmdDataDisassemble implementation.
-// CMICmdCmdDataReadMemoryBytes implementation.
-// CMICmdCmdDataReadMemory implementation.
-// CMICmdCmdDataListRegisterNames implementation.
-// CMICmdCmdDataListRegisterValues implementation.
-// CMICmdCmdDataListRegisterChanged implementation.
-// CMICmdCmdDataWriteMemoryBytes implementation.
-// CMICmdCmdDataWriteMemory implementation.
-// CMICmdCmdDataInfoLine implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBInstruction.h"
-#include "lldb/API/SBInstructionList.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBThread.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include <inttypes.h>
-#include <string>
-
-// In-house headers:
-#include "MICmdArgValConsume.h"
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdData.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugSessionInfoVarObj.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLLDBProxySBValue.h"
-#include "MICmnLLDBUtilSBValue.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "Platform.h"
-
-namespace {
-CMIUtilString IntToHexAddrStr(uint32_t number) {
- return CMIUtilString("0x" + llvm::Twine::utohexstr(number).str());
-}
-} // namespace
-
-//++
-// Details: CMICmdCmdDataEvaluateExpression constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression()
- : m_bExpressionValid(true), m_bEvaluatedExpression(true), m_strValue("??"),
- m_bFoundInvalidChar(false), m_cExpressionInvalidChar(0x00),
- m_constStrArgExpr("expr") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-evaluate-expression";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataEvaluateExpression destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataEvaluateExpression::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgExpr, true, true, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataEvaluateExpression::Execute() {
- CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgExpr);
-
- const CMIUtilString &rExpression(pArgExpr->GetValue());
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- m_bExpressionValid = (thread.GetNumFrames() > 0);
- if (!m_bExpressionValid)
- return MIstatus::success;
-
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
- m_Error = value.GetError();
- if (!value.IsValid() || m_Error.Fail())
- value = frame.FindVariable(rExpression.c_str());
- const CMICmnLLDBUtilSBValue utilValue(value, true);
- if (!utilValue.IsValid() || utilValue.IsValueUnknown()) {
- m_bEvaluatedExpression = false;
- return MIstatus::success;
- }
- if (!utilValue.HasName()) {
- if (HaveInvalidCharacterInExpression(rExpression,
- m_cExpressionInvalidChar)) {
- m_bFoundInvalidChar = true;
- return MIstatus::success;
- }
-
- m_strValue = rExpression;
- return MIstatus::success;
- }
- if (rExpression.IsQuoted()) {
- m_strValue = rExpression.Trim('\"');
- return MIstatus::success;
- }
- m_strValue = utilValue.GetValue(true).Escape().AddSlashes();
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataEvaluateExpression::Acknowledge() {
- if (m_bExpressionValid) {
- if (m_bEvaluatedExpression) {
- if (m_bFoundInvalidChar) {
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- "Invalid character '%c' in expression", m_cExpressionInvalidChar));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst(m_strValue);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
- CMIUtilString mi_error_msg = "Could not evaluate expression";
- if (const char *err_msg = m_Error.GetCString())
- mi_error_msg = err_msg;
- const CMICmnMIValueConst miValueConst(mi_error_msg.Escape(true));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst("Invalid expression");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataEvaluateExpression::CreateSelf() {
- return new CMICmdCmdDataEvaluateExpression();
-}
-
-//++
-// Details: Examine the expression string to see if it contains invalid
-// characters.
-// Type: Method.
-// Args: vrExpr - (R) Expression string given to *this command.
-// vrwInvalidChar - (W) True = Invalid character found, false =
-// nothing found.
-// Return: bool - True = Invalid character found, false = nothing found.
-// Throws: None.
-//--
-bool CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(
- const CMIUtilString &vrExpr, char &vrwInvalidChar) {
- static const std::string strInvalidCharacters(";#\\");
- const size_t nInvalidCharacterOffset =
- vrExpr.find_first_of(strInvalidCharacters);
- const bool bFoundInvalidCharInExpression =
- (nInvalidCharacterOffset != CMIUtilString::npos);
- vrwInvalidChar =
- bFoundInvalidCharInExpression ? vrExpr[nInvalidCharacterOffset] : 0x00;
- return bFoundInvalidCharInExpression;
-}
-
-
-//++
-// Details: CMICmdCmdDataDisassemble constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble()
- : m_constStrArgAddrStart("s"), m_constStrArgAddrEnd("e"),
- m_constStrArgMode("mode"), m_miValueList(true) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-disassemble";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataDisassemble destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataDisassemble::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgAddrStart, true, true,
- CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgAddrEnd, true, true,
- CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgMode, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataDisassemble::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgAddrStart, OptionShort, m_constStrArgAddrStart);
- CMICMDBASE_GETOPTION(pArgAddrEnd, OptionShort, m_constStrArgAddrEnd);
- CMICMDBASE_GETOPTION(pArgMode, Number, m_constStrArgMode);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- CMIUtilString strAddrStart;
- if (!pArgAddrStart->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- strAddrStart)) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID),
- m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str()));
- return MIstatus::failure;
- }
- MIint64 nAddrStart = 0;
- if (!strAddrStart.ExtractNumber(nAddrStart)) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID),
- m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str()));
- return MIstatus::failure;
- }
-
- CMIUtilString strAddrEnd;
- if (!pArgAddrEnd->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- strAddrEnd)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgAddrEnd.c_str()));
- return MIstatus::failure;
- }
- MIint64 nAddrEnd = 0;
- if (!strAddrEnd.ExtractNumber(nAddrEnd)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgAddrEnd.c_str()));
- return MIstatus::failure;
- }
- const MIuint nDisasmMode = pArgMode->GetValue();
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
- lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
- lldb::SBInstructionList instructions = sbTarget.ReadInstructions(
- lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
- const MIuint nInstructions = instructions.GetSize();
- // Calculate the offset of first instruction so that we can generate offset
- // starting at 0
- lldb::addr_t start_offset = 0;
- if (nInstructions > 0)
- start_offset =
- instructions.GetInstructionAtIndex(0).GetAddress().GetOffset();
-
- for (size_t i = 0; i < nInstructions; i++) {
- const char *pUnknown = "??";
- lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
- const char *pStrMnemonic = instrt.GetMnemonic(sbTarget);
- pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
- const char *pStrComment = instrt.GetComment(sbTarget);
- CMIUtilString strComment;
- if (pStrComment != nullptr && *pStrComment != '\0')
- strComment = CMIUtilString::Format("; %s", pStrComment);
- lldb::SBAddress address = instrt.GetAddress();
- lldb::addr_t addr = address.GetLoadAddress(sbTarget);
- const char *pFnName = address.GetFunction().GetName();
- pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
- lldb::addr_t addrOffSet = address.GetOffset() - start_offset;
- const char *pStrOperands = instrt.GetOperands(sbTarget);
- pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
- const size_t instrtSize = instrt.GetByteSize();
-
- // MI "{address=\"0x%016" PRIx64
- // "\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("0x%016" PRIx64, addr));
- const CMICmnMIValueResult miValueResult("address", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(pFnName);
- const CMICmnMIValueResult miValueResult2("func-name", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(
- CMIUtilString::Format("%lld", addrOffSet));
- const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
- miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4(
- CMIUtilString::Format("%d", instrtSize));
- const CMICmnMIValueResult miValueResult4("size", miValueConst4);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueConst miValueConst5(
- CMIUtilString::Format("%s %s%s", pStrMnemonic, pStrOperands,
- strComment.Escape(true).c_str()));
- const CMICmnMIValueResult miValueResult5("inst", miValueConst5);
- miValueTuple.Add(miValueResult5);
-
- if (nDisasmMode == 1) {
- lldb::SBLineEntry lineEntry = address.GetLineEntry();
- const MIuint nLine = lineEntry.GetLine();
- const char *pFileName = lineEntry.GetFileSpec().GetFilename();
- pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
- // Get a full path to the file.
- char pathBuffer[PATH_MAX];
- lineEntry.GetFileSpec().GetPath(pathBuffer, PATH_MAX);
-
- // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ],
- // fullname=\"%s\"}"
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%u", nLine));
- const CMICmnMIValueResult miValueResult("line", miValueConst);
- CMICmnMIValueTuple miValueTuple2(miValueResult);
- const CMICmnMIValueConst miValueConst2(pFileName);
- const CMICmnMIValueResult miValueResult2("file", miValueConst2);
- miValueTuple2.Add(miValueResult2);
- const CMICmnMIValueList miValueList(miValueTuple);
- const CMICmnMIValueResult miValueResult3("line_asm_insn", miValueList);
- miValueTuple2.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst5(pathBuffer);
- const CMICmnMIValueResult miValueResult5("fullname", miValueConst5);
- miValueTuple2.Add(miValueResult5);
- const CMICmnMIValueResult miValueResult4("src_and_asm_line",
- miValueTuple2);
- m_miValueList.Add(miValueResult4);
- } else {
- m_miValueList.Add(miValueTuple);
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataDisassemble::Acknowledge() {
- const CMICmnMIValueResult miValueResult("asm_insns", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataDisassemble::CreateSelf() {
- return new CMICmdCmdDataDisassemble();
-}
-
-
-//++
-// Details: CMICmdCmdDataReadMemoryBytes constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes()
- : m_constStrArgByteOffset("o"), m_constStrArgAddrExpr("address"),
- m_constStrArgNumBytes("count"), m_pBufferMemory(nullptr), m_nAddrStart(0),
- m_nAddrNumBytesToRead(0) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-read-memory-bytes";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataReadMemoryBytes destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes() {
- if (m_pBufferMemory != nullptr) {
- delete[] m_pBufferMemory;
- m_pBufferMemory = nullptr;
- }
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataReadMemoryBytes::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgAddrExpr, true, true, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataReadMemoryBytes::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
- CMICMDBASE_GETOPTION(pArgAddrOffset, OptionShort, m_constStrArgByteOffset);
- CMICMDBASE_GETOPTION(pArgAddrExpr, String, m_constStrArgAddrExpr);
- CMICMDBASE_GETOPTION(pArgNumBytes, Number, m_constStrArgNumBytes);
-
- // get the --thread option value
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- // get the --frame option value
- MIuint64 nFrame = UINT64_MAX;
- if (pArgFrame->GetFound() &&
- !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgFrame.c_str()));
- return MIstatus::failure;
- }
-
- // get the -o option value
- MIuint64 nAddrOffset = 0;
- if (pArgAddrOffset->GetFound() &&
- !pArgAddrOffset->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
- nAddrOffset)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgByteOffset.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- if (!thread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
- : thread.GetSelectedFrame();
- if (!frame.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FRAME_INVALID),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- const CMIUtilString &rAddrExpr = pArgAddrExpr->GetValue();
- lldb::SBValue addrExprValue = frame.EvaluateExpression(rAddrExpr.c_str());
- lldb::SBError error = addrExprValue.GetError();
- if (error.Fail()) {
- SetError(error.GetCString());
- return MIstatus::failure;
- } else if (!addrExprValue.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID),
- rAddrExpr.c_str()));
- return MIstatus::failure;
- }
-
- MIuint64 nAddrStart = 0;
- if (!CMICmnLLDBProxySBValue::GetValueAsUnsigned(addrExprValue, nAddrStart)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID),
- rAddrExpr.c_str()));
- return MIstatus::failure;
- }
-
- nAddrStart += nAddrOffset;
- const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
-
- m_pBufferMemory = new unsigned char[nAddrNumBytes];
- if (m_pBufferMemory == nullptr) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE),
- m_cmdData.strMiCmd.c_str(), nAddrNumBytes));
- return MIstatus::failure;
- }
-
- const MIuint64 nReadBytes =
- sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart),
- (void *)m_pBufferMemory, nAddrNumBytes, error);
- if (nReadBytes != nAddrNumBytes) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK),
- m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart));
- return MIstatus::failure;
- }
- if (error.Fail()) {
- lldb::SBStream err;
- const bool bOk = error.GetDescription(err);
- MIunused(bOk);
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES),
- m_cmdData.strMiCmd.c_str(), nAddrNumBytes,
- nAddrStart, err.GetData()));
- return MIstatus::failure;
- }
-
- m_nAddrStart = nAddrStart;
- m_nAddrNumBytesToRead = nAddrNumBytes;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataReadMemoryBytes::Acknowledge() {
- // MI: memory=[{begin=\"0x%016" PRIx64 "\",offset=\"0x%016" PRIx64"
- // \",end=\"0x%016" PRIx64 "\",contents=\" \" }]"
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("0x%016" PRIx64, m_nAddrStart));
- const CMICmnMIValueResult miValueResult("begin", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const MIuint64 nAddrOffset = 0;
- const CMICmnMIValueConst miValueConst2(
- CMIUtilString::Format("0x%016" PRIx64, nAddrOffset));
- const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(CMIUtilString::Format(
- "0x%016" PRIx64, m_nAddrStart + m_nAddrNumBytesToRead));
- const CMICmnMIValueResult miValueResult3("end", miValueConst3);
- miValueTuple.Add(miValueResult3);
-
- // MI: contents=\" \"
- CMIUtilString strContent;
- strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
- for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++) {
- strContent += CMIUtilString::Format("%02hhx", m_pBufferMemory[i]);
- }
- const CMICmnMIValueConst miValueConst4(strContent);
- const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueList miValueList(miValueTuple);
- const CMICmnMIValueResult miValueResult5("memory", miValueList);
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult5);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataReadMemoryBytes::CreateSelf() {
- return new CMICmdCmdDataReadMemoryBytes();
-}
-
-
-//++
-// Details: CMICmdCmdDataReadMemory constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-read-memory";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataReadMemory destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataReadMemory::Execute() {
- // Do nothing - command deprecated use "data-read-memory-bytes" command
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataReadMemory::Acknowledge() {
- // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which
- // causes this command not to be called
- const CMICmnMIValueConst miValueConst(
- MIRSRC(IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataReadMemory::CreateSelf() {
- return new CMICmdCmdDataReadMemory();
-}
-
-
-//++
-// Details: CMICmdCmdDataListRegisterNames constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames()
- : m_constStrArgRegNo("regno"), m_miValueList(true) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-list-register-names";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataReadMemoryBytes destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterNames::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgRegNo, false, false,
- CMICmdArgValListBase::eArgValType_Number));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterNames::Execute() {
- CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(
- pArgRegNo->GetExpectedOptions());
- if (!rVecRegNo.empty()) {
- // List of required registers
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
- while (it != rVecRegNo.end()) {
- const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
- const MIuint nRegIndex = pRegNo->GetValue();
- lldb::SBValue regValue = GetRegister(nRegIndex);
- if (regValue.IsValid()) {
- const CMICmnMIValueConst miValueConst(
- CMICmnLLDBUtilSBValue(regValue).GetName());
- m_miValueList.Add(miValueConst);
- }
-
- // Next
- ++it;
- }
- } else {
- // List of all registers
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValueList registers = frame.GetRegisters();
- const MIuint nRegisters = registers.GetSize();
- for (MIuint i = 0; i < nRegisters; i++) {
- lldb::SBValue value = registers.GetValueAtIndex(i);
- const MIuint nRegChildren = value.GetNumChildren();
- for (MIuint j = 0; j < nRegChildren; j++) {
- lldb::SBValue regValue = value.GetChildAtIndex(j);
- if (regValue.IsValid()) {
- const CMICmnMIValueConst miValueConst(
- CMICmnLLDBUtilSBValue(regValue).GetName());
- m_miValueList.Add(miValueConst);
- }
- }
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterNames::Acknowledge() {
- const CMICmnMIValueResult miValueResult("register-names", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataListRegisterNames::CreateSelf() {
- return new CMICmdCmdDataListRegisterNames();
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBValue - LLDB SBValue object.
-// Throws: None.
-//--
-lldb::SBValue
-CMICmdCmdDataListRegisterNames::GetRegister(const MIuint vRegisterIndex) const {
- lldb::SBThread thread =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValueList registers = frame.GetRegisters();
- const MIuint nRegisters = registers.GetSize();
- MIuint nRegisterIndex(vRegisterIndex);
- for (MIuint i = 0; i < nRegisters; i++) {
- lldb::SBValue value = registers.GetValueAtIndex(i);
- const MIuint nRegChildren = value.GetNumChildren();
- if (nRegisterIndex >= nRegChildren) {
- nRegisterIndex -= nRegChildren;
- continue;
- }
-
- lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
- if (value2.IsValid()) {
- return value2;
- }
- }
-
- return lldb::SBValue();
-}
-
-
-//++
-// Details: CMICmdCmdDataListRegisterValues constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues()
- : m_constStrArgSkip("skip-unavailable"), m_constStrArgFormat("fmt"),
- m_constStrArgRegNo("regno"), m_miValueList(true) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-list-register-values";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataListRegisterValues destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterValues::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionLong(m_constStrArgThread, false, false,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionLong(m_constStrArgSkip, false, false));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormat, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgRegNo, false, true,
- CMICmdArgValListBase::eArgValType_Number));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterValues::Execute() {
- CMICMDBASE_GETOPTION(pArgFormat, String, m_constStrArgFormat);
- CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
-
- const CMIUtilString &rStrFormat(pArgFormat->GetValue());
- if (rStrFormat.length() != 1) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE),
- m_cmdData.strMiCmd.c_str(),
- rStrFormat.c_str()));
- return MIstatus::failure;
- }
- const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat =
- CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(rStrFormat[0]);
- if (eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE),
- m_cmdData.strMiCmd.c_str(),
- rStrFormat.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(
- pArgRegNo->GetExpectedOptions());
- if (!rVecRegNo.empty()) {
- // List of required registers
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
- while (it != rVecRegNo.end()) {
- const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
- const MIuint nRegIndex = pRegNo->GetValue();
- lldb::SBValue regValue = GetRegister(nRegIndex);
- if (regValue.IsValid()) {
- AddToOutput(nRegIndex, regValue, eFormat);
- }
-
- // Next
- ++it;
- }
- } else {
- // No register numbers are provided. Output all registers.
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValueList registers = frame.GetRegisters();
- const MIuint nRegisters = registers.GetSize();
- MIuint nRegIndex = 0;
- for (MIuint i = 0; i < nRegisters; i++) {
- lldb::SBValue value = registers.GetValueAtIndex(i);
- const MIuint nRegChildren = value.GetNumChildren();
- for (MIuint j = 0; j < nRegChildren; j++) {
- lldb::SBValue regValue = value.GetChildAtIndex(j);
- if (regValue.IsValid()) {
- AddToOutput(nRegIndex, regValue, eFormat);
- }
-
- // Next
- ++nRegIndex;
- }
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterValues::Acknowledge() {
- const CMICmnMIValueResult miValueResult("register-values", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataListRegisterValues::CreateSelf() {
- return new CMICmdCmdDataListRegisterValues();
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBValue - LLDB SBValue object.
-// Throws: None.
-//--
-lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister(
- const MIuint vRegisterIndex) const {
- lldb::SBThread thread =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValueList registers = frame.GetRegisters();
- const MIuint nRegisters = registers.GetSize();
- MIuint nRegisterIndex(vRegisterIndex);
- for (MIuint i = 0; i < nRegisters; i++) {
- lldb::SBValue value = registers.GetValueAtIndex(i);
- const MIuint nRegChildren = value.GetNumChildren();
- if (nRegisterIndex >= nRegChildren) {
- nRegisterIndex -= nRegChildren;
- continue;
- }
-
- lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
- if (value2.IsValid()) {
- return value2;
- }
- }
-
- return lldb::SBValue();
-}
-
-//++
-// Details: Adds the register value to the output list.
-// Type: Method.
-// Args: Value of the register, its index and output format.
-// Return: None
-// Throws: None.
-//--
-void CMICmdCmdDataListRegisterValues::AddToOutput(
- const MIuint vnIndex, const lldb::SBValue &vrValue,
- CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat) {
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", vnIndex));
- const CMICmnMIValueResult miValueResult("number", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMIUtilString strRegValue(
- CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(vrValue,
- veVarFormat));
- const CMICmnMIValueConst miValueConst2(strRegValue);
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- m_miValueList.Add(miValueTuple);
-}
-
-
-//++
-// Details: CMICmdCmdDataListRegisterChanged constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-list-changed-registers";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataListRegisterChanged destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterChanged::Execute() {
- // Do nothing
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataListRegisterChanged::Acknowledge() {
- const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataListRegisterChanged::CreateSelf() {
- return new CMICmdCmdDataListRegisterChanged();
-}
-
-
-//++
-// Details: CMICmdCmdDataWriteMemoryBytes constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes()
- : m_constStrArgAddr("address"), m_constStrArgContents("contents"),
- m_constStrArgCount("count") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-write-memory-bytes";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataWriteMemoryBytes destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemoryBytes::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgAddr, true, true, false, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgContents, true, true, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgCount, false, true, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemoryBytes::Execute() {
- // Do nothing - not reproduceable (yet) in Eclipse
- // CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
- // CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
- // CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
- // CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
- //
- // Numbers extracts as string types as they could be hex numbers
- // '&' is not recognised and so has to be removed
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemoryBytes::Acknowledge() {
- const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataWriteMemoryBytes::CreateSelf() {
- return new CMICmdCmdDataWriteMemoryBytes();
-}
-
-
-//++
-// Details: CMICmdCmdDataWriteMemory constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory()
- : m_constStrArgOffset("o"), m_constStrArgAddr("address"),
- m_constStrArgD("d"), m_constStrArgNumber("a number"),
- m_constStrArgContents("contents"), m_nAddr(0), m_nCount(0),
- m_pBufferMemory(nullptr) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-write-memory";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataWriteMemory destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory() {
- if (m_pBufferMemory != nullptr) {
- delete[] m_pBufferMemory;
- m_pBufferMemory = nullptr;
- }
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemory::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgOffset, false, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgAddr, true, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgD, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgContents, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemory::Execute() {
- CMICMDBASE_GETOPTION(pArgOffset, OptionShort, m_constStrArgOffset);
- CMICMDBASE_GETOPTION(pArgAddr, Number, m_constStrArgAddr);
- CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNumber);
- CMICMDBASE_GETOPTION(pArgContents, Number, m_constStrArgContents);
-
- MIuint nAddrOffset = 0;
- if (pArgOffset->GetFound() &&
- !pArgOffset->GetExpectedOption<CMICmdArgValNumber, MIuint>(nAddrOffset)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgAddr.c_str()));
- return MIstatus::failure;
- }
- m_nAddr = pArgAddr->GetValue();
- m_nCount = pArgNumber->GetValue();
- const MIuint64 nValue = pArgContents->GetValue();
-
- m_pBufferMemory = new unsigned char[m_nCount];
- if (m_pBufferMemory == nullptr) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE),
- m_cmdData.strMiCmd.c_str(), m_nCount));
- return MIstatus::failure;
- }
- *m_pBufferMemory = static_cast<char>(nValue);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBError error;
- lldb::addr_t addr = static_cast<lldb::addr_t>(m_nAddr + nAddrOffset);
- const size_t nBytesWritten = sbProcess.WriteMemory(
- addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
- if (nBytesWritten != static_cast<size_t>(m_nCount)) {
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK),
- m_cmdData.strMiCmd.c_str(), m_nCount, addr));
- return MIstatus::failure;
- }
- if (error.Fail()) {
- lldb::SBStream err;
- const bool bOk = error.GetDescription(err);
- MIunused(bOk);
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES),
- m_cmdData.strMiCmd.c_str(), m_nCount, addr,
- err.GetData()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataWriteMemory::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataWriteMemory::CreateSelf() {
- return new CMICmdCmdDataWriteMemory();
-}
-
-
-//++
-// Details: CMICmdCmdDataInfoLine constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataInfoLine::CMICmdCmdDataInfoLine()
- : m_constStrArgLocation("location"),
- m_resultRecord(m_cmdData.strMiCmdToken,
- CMICmnMIResultRecord::eResultClass_Done) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "data-info-line";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdDataInfoLine::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdDataInfoLine destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdDataInfoLine::~CMICmdCmdDataInfoLine() = default;
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataInfoLine::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgLocation, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataInfoLine::Execute() {
- CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgLocation);
-
- lldb::SBLineEntry line;
- bool found_line = false;
- const CMIUtilString &strLocation(pArgLocation->GetValue());
- lldb::SBTarget target = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
-
- if (strLocation.at(0) == '*') {
- // Parse argument:
- // *0x12345
- // ^^^^^^^^^ -- address
- lldb::addr_t address = 0x0;
- if (llvm::StringRef(strLocation.substr(1)).getAsInteger(0, address)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SOME_ERROR),
- m_cmdData.strMiCmd.c_str(),
- "Failed to parse address."));
- return MIstatus::failure;
- }
- line = target.ResolveFileAddress(address).GetLineEntry();
- // Check that found line is valid.
- if (line.GetLine())
- found_line = true;
- } else {
- const size_t nLineStartPos = strLocation.rfind(':');
- if ((nLineStartPos == std::string::npos) || (nLineStartPos == 0) ||
- (nLineStartPos == strLocation.length() - 1)) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_INVALID_LOCATION_FORMAT),
- m_cmdData.strMiCmd.c_str(), strLocation.c_str()));
- return MIstatus::failure;
- }
- // Parse argument:
- // hello.cpp:5
- // ^^^^^^^^^ -- file
- // ^ -- line
- const CMIUtilString &strFile(strLocation.substr(0, nLineStartPos));
- uint32_t numLine = 0;
- llvm::StringRef(strLocation.substr(nLineStartPos + 1))
- .getAsInteger(0, numLine);
- lldb::SBSymbolContextList sc_cu_list =
- target.FindCompileUnits(lldb::SBFileSpec(strFile.c_str(), false));
- for (uint32_t i = 0, e = sc_cu_list.GetSize(); i < e; ++i) {
- const lldb::SBCompileUnit &cu =
- sc_cu_list.GetContextAtIndex(i).GetCompileUnit();
- // Break if we have already found requested line.
- if (found_line)
- break;
- for (uint32_t j = 0, e = cu.GetNumLineEntries(); j < e; ++j) {
- const lldb::SBLineEntry &curLine = cu.GetLineEntryAtIndex(j);
- if (curLine.GetLine() == numLine) {
- line = curLine;
- found_line = true;
- break;
- }
- }
- }
- }
- if (!found_line) {
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_SOME_ERROR), m_cmdData.strMiCmd.c_str(),
- "The LineEntry is absent or has an unknown format."));
- return MIstatus::failure;
- }
- // Start address.
- m_resultRecord.Add(CMICmnMIValueResult(
- "start", CMICmnMIValueConst(IntToHexAddrStr(
- line.GetStartAddress().GetFileAddress()))));
- // End address.
- m_resultRecord.Add(CMICmnMIValueResult(
- "end", CMICmnMIValueConst(IntToHexAddrStr(
- line.GetEndAddress().GetFileAddress()))));
- // File.
- std::unique_ptr<char[]> upPath(new char[PATH_MAX]);
- line.GetFileSpec().GetPath(upPath.get(), PATH_MAX);
- m_resultRecord.Add(CMICmnMIValueResult(
- "file", CMICmnMIValueConst(CMIUtilString(upPath.get()))));
- // Line.
- m_resultRecord.Add(CMICmnMIValueResult(
- "line", CMICmnMIValueConst(std::to_string(line.GetLine()))));
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdDataInfoLine::Acknowledge() {
- m_miResultRecord = m_resultRecord;
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdDataInfoLine::CreateSelf() {
- return new CMICmdCmdDataInfoLine();
-}
diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h
deleted file mode 100644
index 19c5319faab3..000000000000
--- a/tools/lldb-mi/MICmdCmdData.h
+++ /dev/null
@@ -1,381 +0,0 @@
-//===-- MICmdCmdData.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdDataEvaluateExpression interface.
-// CMICmdCmdDataDisassemble interface.
-// CMICmdCmdDataReadMemoryBytes interface.
-// CMICmdCmdDataReadMemory interface.
-// CMICmdCmdDataListRegisterNames interface.
-// CMICmdCmdDataListRegisterValues interface.
-// CMICmdCmdDataListRegisterChanged interface.
-// CMICmdCmdDataWriteMemoryBytes interface.
-// CMICmdCmdDataWriteMemory interface.
-// CMICmdCmdDataInfoLine interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-//
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBError.h"
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnLLDBDebugSessionInfoVarObj.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-#include "MICmnMIResultRecord.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-evaluate-expression".
-//--
-class CMICmdCmdDataEvaluateExpression : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataEvaluateExpression();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataEvaluateExpression() override;
-
- // Methods:
-private:
- bool HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr,
- char &vrwInvalidChar);
-
- // Attributes:
-private:
- bool m_bExpressionValid; // True = yes is valid, false = not valid
- bool m_bEvaluatedExpression; // True = yes is expression evaluated, false =
- // failed
- lldb::SBError m_Error; // Status object, which is examined when
- // m_bEvaluatedExpression is false
- CMIUtilString m_strValue;
- CMICmnMIValueTuple m_miValueTuple;
- bool m_bFoundInvalidChar; // True = yes found unexpected character in the
- // expression, false = all ok
- char m_cExpressionInvalidChar;
- const CMIUtilString m_constStrArgExpr;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-disassemble".
-//--
-class CMICmdCmdDataDisassemble : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataDisassemble();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataDisassemble() override;
-
- // Attributes:
-private:
- const CMIUtilString
- m_constStrArgAddrStart; // MI spec non mandatory, *this command mandatory
- const CMIUtilString
- m_constStrArgAddrEnd; // MI spec non mandatory, *this command mandatory
- const CMIUtilString m_constStrArgMode;
- CMICmnMIValueList m_miValueList;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-read-memory-bytes".
-//--
-class CMICmdCmdDataReadMemoryBytes : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataReadMemoryBytes();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataReadMemoryBytes() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgByteOffset;
- const CMIUtilString m_constStrArgAddrExpr;
- const CMIUtilString m_constStrArgNumBytes;
- unsigned char *m_pBufferMemory;
- MIuint64 m_nAddrStart;
- MIuint64 m_nAddrNumBytesToRead;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-read-memory".
-//--
-class CMICmdCmdDataReadMemory : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataReadMemory();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataReadMemory() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-list-register-names".
-//--
-class CMICmdCmdDataListRegisterNames : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataListRegisterNames();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataListRegisterNames() override;
-
- // Methods:
-private:
- lldb::SBValue GetRegister(const MIuint vRegisterIndex) const;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgRegNo; // Not handled by *this command
- CMICmnMIValueList m_miValueList;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-list-register-values".
-//--
-class CMICmdCmdDataListRegisterValues : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataListRegisterValues();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataListRegisterValues() override;
-
- // Methods:
-private:
- lldb::SBValue GetRegister(const MIuint vRegisterIndex) const;
- void AddToOutput(const MIuint vnIndex, const lldb::SBValue &vrValue,
- CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat);
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgSkip; // Not handled by *this command
- const CMIUtilString m_constStrArgFormat;
- const CMIUtilString m_constStrArgRegNo;
- CMICmnMIValueList m_miValueList;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-list-changed-registers".
-//--
-class CMICmdCmdDataListRegisterChanged : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataListRegisterChanged();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataListRegisterChanged() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-read-memory-bytes".
-//--
-class CMICmdCmdDataWriteMemoryBytes : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataWriteMemoryBytes();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataWriteMemoryBytes() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgAddr;
- const CMIUtilString m_constStrArgContents;
- const CMIUtilString m_constStrArgCount;
- CMIUtilString m_strContents;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-read-memory".
-// Not specified in MI spec but Eclipse gives *this command.
-//--
-class CMICmdCmdDataWriteMemory : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataWriteMemory();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataWriteMemory() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgOffset; // Not specified in MI spec but
- // Eclipse gives this option.
- const CMIUtilString m_constStrArgAddr; // Not specified in MI spec but Eclipse
- // gives this option.
- const CMIUtilString
- m_constStrArgD; // Not specified in MI spec but Eclipse gives this option.
- const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but
- // Eclipse gives this option.
- const CMIUtilString m_constStrArgContents; // Not specified in MI spec but
- // Eclipse gives this option.
- MIuint64 m_nAddr;
- CMIUtilString m_strContents;
- MIuint64 m_nCount;
- unsigned char *m_pBufferMemory;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "data-info-line".
-// See MIExtensions.txt for details.
-//--
-class CMICmdCmdDataInfoLine : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdDataInfoLine();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdDataInfoLine() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgLocation;
- CMICmnMIResultRecord m_resultRecord;
-};
diff --git a/tools/lldb-mi/MICmdCmdEnviro.cpp b/tools/lldb-mi/MICmdCmdEnviro.cpp
deleted file mode 100644
index e7a92f3c9e89..000000000000
--- a/tools/lldb-mi/MICmdCmdEnviro.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//===-- MICmdCmdEnviro.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdEnvironmentCd implementation.
-
-// In-house headers:
-#include "MICmdCmdEnviro.h"
-#include "MICmdArgValFile.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdCmdEnvironmentCd constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdEnvironmentCd::CMICmdCmdEnvironmentCd()
- : m_constStrArgNamePathDir("pathdir") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "environment-cd";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdEnvironmentCd::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdEnvironmentCd destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdEnvironmentCd::~CMICmdCmdEnvironmentCd() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdEnvironmentCd::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNamePathDir, true, true));
- CMICmdArgContext argCntxt(m_cmdData.strMiCmdOption);
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdEnvironmentCd::Execute() {
- CMICMDBASE_GETOPTION(pArgPathDir, File, m_constStrArgNamePathDir);
- const CMIUtilString &strWkDir(pArgPathDir->GetValue());
- CMICmnLLDBDebugger &rDbg(CMICmnLLDBDebugger::Instance());
- lldb::SBDebugger &rLldbDbg = rDbg.GetTheDebugger();
- bool bOk = rLldbDbg.SetCurrentPlatformSDKRoot(strWkDir.c_str());
- if (bOk) {
- const CMIUtilString &rStrKeyWkDir(
- m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir);
- if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeyWkDir,
- strWkDir)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(),
- rStrKeyWkDir.c_str()));
- bOk = MIstatus::failure;
- }
- } else
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
- m_cmdData.strMiCmd.c_str(),
- "SetCurrentPlatformSDKRoot()"));
-
- lldb::SBTarget sbTarget = m_rLLDBDebugSessionInfo.GetTarget();
- if (sbTarget.IsValid()) {
- lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
- sbLaunchInfo.SetWorkingDirectory(strWkDir.c_str());
- sbTarget.SetLaunchInfo(sbLaunchInfo);
- }
-
- return bOk;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdEnvironmentCd::Acknowledge() {
- const CMIUtilString &rStrKeyWkDir(
- m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir);
- CMIUtilString strWkDir;
- const bool bOk = m_rLLDBDebugSessionInfo.SharedDataRetrieve<CMIUtilString>(
- rStrKeyWkDir, strWkDir);
- if (bOk) {
- const CMICmnMIValueConst miValueConst(strWkDir);
- const CMICmnMIValueResult miValueResult("path", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SHARED_DATA_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- rStrKeyWkDir.c_str()));
- return MIstatus::failure;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdEnvironmentCd::CreateSelf() {
- return new CMICmdCmdEnvironmentCd();
-}
diff --git a/tools/lldb-mi/MICmdCmdEnviro.h b/tools/lldb-mi/MICmdCmdEnviro.h
deleted file mode 100644
index 461ccd83a8f5..000000000000
--- a/tools/lldb-mi/MICmdCmdEnviro.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//===-- MICmdCmdEnviro.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdEnvironmentCd interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "environment-cd".
-//--
-class CMICmdCmdEnvironmentCd : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdEnvironmentCd();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdEnvironmentCd() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamePathDir;
-};
diff --git a/tools/lldb-mi/MICmdCmdExec.cpp b/tools/lldb-mi/MICmdCmdExec.cpp
deleted file mode 100644
index ffdf171aef08..000000000000
--- a/tools/lldb-mi/MICmdCmdExec.cpp
+++ /dev/null
@@ -1,1115 +0,0 @@
-//===-- MICmdCmdExec.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdExecRun implementation.
-// CMICmdCmdExecContinue implementation.
-// CMICmdCmdExecNext implementation.
-// CMICmdCmdExecStep implementation.
-// CMICmdCmdExecNextInstruction implementation.
-// CMICmdCmdExecStepInstruction implementation.
-// CMICmdCmdExecFinish implementation.
-// CMICmdCmdExecInterrupt implementation.
-// CMICmdCmdExecArguments implementation.
-// CMICmdCmdExecAbort implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBThread.h"
-#include "lldb/lldb-enumerations.h"
-
-// In-house headers:
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdExec.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriver.h"
-
-//++
-// Details: CMICmdCmdExecRun constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecRun::CMICmdCmdExecRun() : m_constStrArgStart("start") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-run";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecRun::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecRun destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecRun::~CMICmdCmdExecRun() {}
-
-//++
-// Details: The invoker requires this function. It parses the command line
-// options'
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecRun::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValOptionLong(
- m_constStrArgStart, false, true,
- CMICmdArgValListBase::eArgValType_OptionLong, 0));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecRun::Execute() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- {
- // Check we have a valid target.
- // Note: target created via 'file-exec-and-symbols' command.
- lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
- if (!sbTarget.IsValid() ||
- sbTarget == rSessionInfo.GetDebugger().GetDummyTarget()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
- }
-
- lldb::SBError error;
- lldb::SBStream errMsg;
- lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo();
- launchInfo.SetListener(rSessionInfo.GetListener());
-
- // Run to first instruction or main() requested?
- CMICMDBASE_GETOPTION(pArgStart, OptionLong, m_constStrArgStart);
- if (pArgStart->GetFound()) {
- launchInfo.SetLaunchFlags(launchInfo.GetLaunchFlags() |
- lldb::eLaunchFlagStopAtEntry);
- }
-
- lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error);
- if (!process.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str(),
- errMsg.GetData()));
- return MIstatus::failure;
- }
-
- const auto successHandler = [this] {
- if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) {
- const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
- m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
- return MIstatus::failure;
- }
- return MIstatus::success;
- };
-
- return HandleSBErrorWithSuccess(error, successHandler);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Called only if Execute() set status as successful on completion.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecRun::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
- // Give the client '=thread-group-started,id="i1" pid="xyz"'
- m_bHasResultRecordExtra = true;
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("id", miValueConst2);
- const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
- const CMICmnMIValueConst miValueConst(strPid);
- const CMICmnMIValueResult miValueResult("pid", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
- miOutOfBand.Add(miValueResult);
- m_miResultRecordExtra = miOutOfBand.GetString();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecRun::CreateSelf() { return new CMICmdCmdExecRun(); }
-
-
-//++
-// Details: CMICmdCmdExecContinue constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecContinue::CMICmdCmdExecContinue() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-continue";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecContinue::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecContinue destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecContinue::~CMICmdCmdExecContinue() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecContinue::Execute() {
- const auto successHandler = [this] {
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) {
- const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
- SetError(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
- m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
- return MIstatus::failure;
- }
- return MIstatus::success;
- };
-
- return HandleSBErrorWithSuccess(
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Continue(),
- successHandler);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecContinue::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecContinue::CreateSelf() {
- return new CMICmdCmdExecContinue();
-}
-
-
-//++
-// Details: CMICmdCmdExecNext constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecNext::CMICmdCmdExecNext() : m_constStrArgNumber("number") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-next";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecNext::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecNext destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecNext::~CMICmdCmdExecNext() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNext::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNext::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBError error;
- if (nThreadId != UINT64_MAX) {
- lldb::SBThread sbThread = rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
- if (!sbThread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- sbThread.StepOver(lldb::eOnlyDuringStepping, error);
- } else
- rSessionInfo.GetProcess().GetSelectedThread().StepOver(
- lldb::eOnlyDuringStepping, error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNext::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecNext::CreateSelf() { return new CMICmdCmdExecNext(); }
-
-
-//++
-// Details: CMICmdCmdExecStep constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecStep::CMICmdCmdExecStep() : m_constStrArgNumber("number") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-step";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecStep::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecStep destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecStep::~CMICmdCmdExecStep() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStep::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStep::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBError error;
- if (nThreadId != UINT64_MAX) {
- lldb::SBThread sbThread =
- rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
- if (!sbThread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- sbThread.StepInto(nullptr, LLDB_INVALID_LINE_NUMBER, error);
- } else
- rSessionInfo.GetProcess().GetSelectedThread().StepInto(
- nullptr, LLDB_INVALID_LINE_NUMBER, error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStep::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecStep::CreateSelf() { return new CMICmdCmdExecStep(); }
-
-
-//++
-// Details: CMICmdCmdExecNextInstruction constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction()
- : m_constStrArgNumber("number") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-next-instruction";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecNextInstruction::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecNextInstruction destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecNextInstruction::~CMICmdCmdExecNextInstruction() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNextInstruction::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNextInstruction::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBError error;
- if (nThreadId != UINT64_MAX) {
- lldb::SBThread sbThread =
- rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
- if (!sbThread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- sbThread.StepInstruction(true, error);
- } else
- rSessionInfo.GetProcess().GetSelectedThread().StepInstruction(
- true, error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecNextInstruction::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecNextInstruction::CreateSelf() {
- return new CMICmdCmdExecNextInstruction();
-}
-
-
-//++
-// Details: CMICmdCmdExecStepInstruction constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction()
- : m_constStrArgNumber("number") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-step-instruction";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecStepInstruction::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecStepInstruction destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecStepInstruction::~CMICmdCmdExecStepInstruction() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStepInstruction::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStepInstruction::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBError error;
- if (nThreadId != UINT64_MAX) {
- lldb::SBThread sbThread =
- rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
- if (!sbThread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- sbThread.StepInstruction(false, error);
- } else
- rSessionInfo.GetProcess().GetSelectedThread().StepInstruction(
- false, error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecStepInstruction::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecStepInstruction::CreateSelf() {
- return new CMICmdCmdExecStepInstruction();
-}
-
-
-//++
-// Details: CMICmdCmdExecFinish constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecFinish::CMICmdCmdExecFinish() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-finish";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecFinish::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecFinish destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecFinish::~CMICmdCmdExecFinish() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecFinish::ParseArgs() { return ParseValidateCmdOptions(); }
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecFinish::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBError error;
- if (nThreadId != UINT64_MAX) {
- lldb::SBThread sbThread =
- rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
- if (!sbThread.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- sbThread.StepOut(error);
- } else
- rSessionInfo.GetProcess().GetSelectedThread().StepOut(error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecFinish::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecFinish::CreateSelf() {
- return new CMICmdCmdExecFinish();
-}
-
-
-//++
-// Details: CMICmdCmdExecInterrupt constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-interrupt";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecInterrupt::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecInterrupt destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecInterrupt::~CMICmdCmdExecInterrupt() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecInterrupt::Execute() {
- const auto successHandler = [this] {
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) {
- const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
- m_cmdData.strMiCmd.c_str(),
- rErrMsg.c_str()));
- return MIstatus::failure;
- }
- return MIstatus::success;
- };
-
- return HandleSBErrorWithSuccess(
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Stop(),
- successHandler);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecInterrupt::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecInterrupt::CreateSelf() {
- return new CMICmdCmdExecInterrupt();
-}
-
-
-//++
-// Details: CMICmdCmdExecArguments constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecArguments::CMICmdCmdExecArguments()
- : m_constStrArgArguments("arguments") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-arguments";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecArguments::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecArguments destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecArguments::~CMICmdCmdExecArguments() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecArguments::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValListOfN(
- m_constStrArgArguments, false, true,
- CMICmdArgValListBase::eArgValType_StringAnything));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecArguments::Execute() {
- CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
- if (!sbTarget.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
- sbLaunchInfo.SetArguments(nullptr, false);
-
- CMIUtilString strArg;
- size_t nArgIndex = 0;
- while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- strArg, nArgIndex)) {
- const char *argv[2] = {strArg.c_str(), nullptr};
- sbLaunchInfo.SetArguments(argv, true);
- ++nArgIndex;
- }
-
- sbTarget.SetLaunchInfo(sbLaunchInfo);
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecArguments::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecArguments::CreateSelf() {
- return new CMICmdCmdExecArguments();
-}
-
-
-//++
-// Details: CMICmdCmdExecAbort constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecAbort::CMICmdCmdExecAbort() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "exec-abort";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdExecAbort::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdExecAbort destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdExecAbort::~CMICmdCmdExecAbort() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecAbort::Execute() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBError sbError = sbProcess.Destroy();
- if (sbError.Fail()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDBPROCESS_DESTROY),
- m_cmdData.strMiCmd.c_str(),
- sbError.GetCString()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdExecAbort::Acknowledge() {
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdExecAbort::CreateSelf() {
- return new CMICmdCmdExecAbort();
-}
diff --git a/tools/lldb-mi/MICmdCmdExec.h b/tools/lldb-mi/MICmdCmdExec.h
deleted file mode 100644
index 8533915e24f8..000000000000
--- a/tools/lldb-mi/MICmdCmdExec.h
+++ /dev/null
@@ -1,316 +0,0 @@
-//===-- MICmdCmdExec.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdExecRun interface.
-// CMICmdCmdExecContinue interface.
-// CMICmdCmdExecNext interface.
-// CMICmdCmdExecStep interface.
-// CMICmdCmdExecNextInstruction interface.
-// CMICmdCmdExecStepInstruction interface.
-// CMICmdCmdExecFinish interface.
-// CMICmdCmdExecInterrupt interface.
-// CMICmdCmdExecArguments interface.
-// CMICmdCmdExecAbort interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// Third party headers:
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-run".
-//--
-class CMICmdCmdExecRun : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecRun();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecRun() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgStart; // StopAtEntry - run to first
- // instruction or main() if specified
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-continue".
-//--
-class CMICmdCmdExecContinue : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecContinue();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecContinue() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-next".
-//--
-class CMICmdCmdExecNext : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecNext();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecNext() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but
- // Eclipse gives this option
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-step".
-//--
-class CMICmdCmdExecStep : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecStep();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecStep() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but
- // Eclipse gives this option
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-next-instruction".
-//--
-class CMICmdCmdExecNextInstruction : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecNextInstruction();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecNextInstruction() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but
- // Eclipse gives this option
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-step-instruction".
-//--
-class CMICmdCmdExecStepInstruction : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecStepInstruction();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecStepInstruction() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but
- // Eclipse gives this option
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-finish".
-//--
-class CMICmdCmdExecFinish : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecFinish();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecFinish() override;
-};
-
-// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-interrupt".
-// Gotchas: Using Eclipse this command is injected into the command system when
-// a
-// SIGINT signal is received while running an inferior program.
-//--
-class CMICmdCmdExecInterrupt : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecInterrupt();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecInterrupt() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-arguments".
-//--
-class CMICmdCmdExecArguments : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecArguments();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecArguments() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgArguments;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "exec-abort".
-//--
-class CMICmdCmdExecAbort : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdExecAbort();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdExecAbort() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdFile.cpp b/tools/lldb-mi/MICmdCmdFile.cpp
deleted file mode 100644
index 8b105eb1d58a..000000000000
--- a/tools/lldb-mi/MICmdCmdFile.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-//===-- MICmdCmdFile.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdFileExecAndSymbols implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBStream.h"
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdCmdFile.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIResultRecord.h"
-#include "MIUtilFileStd.h"
-
-//++
-// Details: CMICmdCmdFileExecAndSymbols constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdFileExecAndSymbols::CMICmdCmdFileExecAndSymbols()
- : m_constStrArgNameFile("file"), m_constStrArgNamedPlatformName("p"),
- m_constStrArgNamedRemotePath("r") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "file-exec-and-symbols";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdFileExecAndSymbols::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdFileExecAndSymbols destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdFileExecAndSymbols::~CMICmdCmdFileExecAndSymbols() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdFileExecAndSymbols::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNameFile, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgNamedPlatformName, false, true,
- CMICmdArgValListBase::eArgValType_String, 1));
- m_setCmdArgs.Add(new CMICmdArgValOptionShort(
- m_constStrArgNamedRemotePath, false, true,
- CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -file-exec-and-symbols file
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-File-Commands.html#GDB_002fMI-File-Commands
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdFileExecAndSymbols::Execute() {
- CMICMDBASE_GETOPTION(pArgNamedFile, File, m_constStrArgNameFile);
- CMICMDBASE_GETOPTION(pArgPlatformName, OptionShort,
- m_constStrArgNamedPlatformName);
- CMICMDBASE_GETOPTION(pArgRemotePath, OptionShort,
- m_constStrArgNamedRemotePath);
- CMICmdArgValFile *pArgFile = static_cast<CMICmdArgValFile *>(pArgNamedFile);
- const CMIUtilString &strExeFilePath(pArgFile->GetValue());
- bool bPlatformName = pArgPlatformName->GetFound();
- CMIUtilString platformName;
- if (bPlatformName) {
- pArgPlatformName->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- platformName);
- }
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
- lldb::SBError error;
- const char *pTargetTriple = nullptr; // Let LLDB discover the triple required
- const char *pTargetPlatformName = platformName.c_str();
- const bool bAddDepModules = false;
- lldb::SBTarget target =
- rDbgr.CreateTarget(strExeFilePath.c_str(), pTargetTriple,
- pTargetPlatformName, bAddDepModules, error);
- CMIUtilString strWkDir;
- const CMIUtilString &rStrKeyWkDir(rSessionInfo.m_constStrSharedDataKeyWkDir);
- if (!rSessionInfo.SharedDataRetrieve<CMIUtilString>(rStrKeyWkDir, strWkDir)) {
- strWkDir = CMIUtilFileStd::StripOffFileName(strExeFilePath);
- if (!rSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeyWkDir, strWkDir)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(),
- rStrKeyWkDir.c_str()));
- return MIstatus::failure;
- }
- }
- if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str())) {
-
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
- m_cmdData.strMiCmd.c_str(),
- "SetCurrentPlatformSDKRoot()"));
- return MIstatus::failure;
- }
- if (pArgRemotePath->GetFound()) {
- CMIUtilString remotePath;
- pArgRemotePath->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
- remotePath);
- lldb::SBModule module = target.FindModule(target.GetExecutable());
- if (module.IsValid()) {
- module.SetPlatformFileSpec(lldb::SBFileSpec(remotePath.c_str()));
- }
- }
- lldb::SBStream err;
- if (error.Fail()) {
- const bool bOk = error.GetDescription(err);
- MIunused(bOk);
- }
- if (!target.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET),
- m_cmdData.strMiCmd.c_str(),
- strExeFilePath.c_str(), err.GetData()));
- return MIstatus::failure;
- }
- if (error.Fail()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CREATE_TARGET),
- m_cmdData.strMiCmd.c_str(), err.GetData()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdFileExecAndSymbols::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdFileExecAndSymbols::CreateSelf() {
- return new CMICmdCmdFileExecAndSymbols();
-}
-
-//++
-// Details: If the MI Driver is not operating via a client i.e. Eclipse but say
-// operating
-// on a executable passed in as a argument to the drive then what
-// should the driver
-// do on a command failing? Either continue operating or exit the
-// application.
-// Override this function where a command failure cannot allow the
-// driver to
-// continue operating.
-// Type: Overridden.
-// Args: None.
-// Return: bool - True = Fatal if command fails, false = can continue if
-// command fails.
-// Throws: None.
-//--
-bool CMICmdCmdFileExecAndSymbols::GetExitAppOnCommandFailure() const {
- return true;
-}
diff --git a/tools/lldb-mi/MICmdCmdFile.h b/tools/lldb-mi/MICmdCmdFile.h
deleted file mode 100644
index 4607f748cba5..000000000000
--- a/tools/lldb-mi/MICmdCmdFile.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- MICmdCmdFile.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdFileExecAndSymbols interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "file-exec-and-symbols".
-// This command does not follow the MI documentation exactly.
-// Gotchas: This command has additional flags that were not available in GDB MI.
-// See MIextensions.txt for details.
-//--
-class CMICmdCmdFileExecAndSymbols : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdFileExecAndSymbols();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdFileExecAndSymbols() override;
- bool GetExitAppOnCommandFailure() const override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNameFile;
- const CMIUtilString
- m_constStrArgNamedPlatformName; // Added to support iOS platform selection
- const CMIUtilString m_constStrArgNamedRemotePath; // Added to support iOS
- // device remote file
- // location
-};
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.cpp b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
deleted file mode 100644
index b351353ba1e9..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbInfo.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===-- MICmdCmdGdbInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbInfo implementation.
-
-// Third party headers:
-#include "lldb/API/SBCommandReturnObject.h"
-#include <inttypes.h>
-
-// In-house headers:
-#include "MICmdArgValString.h"
-#include "MICmdCmdGdbInfo.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnStreamStdout.h"
-
-// Instantiations:
-const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t
- CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = {
- {"sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary}};
-
-//++
-// Details: CMICmdCmdGdbInfo constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbInfo::CMICmdCmdGdbInfo()
- : m_constStrArgNamedPrint("print"), m_bPrintFnRecognised(true),
- m_bPrintFnSuccessful(false),
- m_strPrintFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "info";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdGdbInfo destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbInfo::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedPrint, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbInfo::Execute() {
- CMICMDBASE_GETOPTION(pArgPrint, String, m_constStrArgNamedPrint);
- const CMIUtilString &rPrintRequest(pArgPrint->GetValue());
-
- FnPrintPtr pPrintRequestFn = nullptr;
- if (!GetPrintFn(rPrintRequest, pPrintRequestFn)) {
- m_strPrintFnName = rPrintRequest;
- m_bPrintFnRecognised = false;
- return MIstatus::success;
- }
-
- m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbInfo::Acknowledge() {
- if (!m_bPrintFnRecognised) {
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strPrintFnName.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- if (m_bPrintFnSuccessful) {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strPrintFnError.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdGdbInfo::CreateSelf() { return new CMICmdCmdGdbInfo(); }
-
-//++
-// Details: Retrieve the print function's pointer for the matching print
-// request.
-// Type: Method.
-// Args: vrPrintFnName - (R) The info requested.
-// vrwpFn - (W) The print function's pointer of the function
-// to carry out
-// Return: bool - True = Print request is implemented, false = not found.
-// Throws: None.
-//--
-bool CMICmdCmdGdbInfo::GetPrintFn(const CMIUtilString &vrPrintFnName,
- FnPrintPtr &vrwpFn) const {
- vrwpFn = nullptr;
-
- const MapPrintFnNameToPrintFn_t::const_iterator it =
- ms_mapPrintFnNameToPrintFn.find(vrPrintFnName);
- if (it != ms_mapPrintFnNameToPrintFn.end()) {
- vrwpFn = (*it).second;
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: Carry out work to complete the request to prepare and send back
-// information
-// asked for.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbInfo::PrintFnSharedLibrary() {
- bool bOk = CMICmnStreamStdout::TextToStdout(
- "~\"From To Syms Read Shared Object Library\"");
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
- const MIuint nModules = sbTarget.GetNumModules();
- for (MIuint i = 0; bOk && (i < nModules); i++) {
- lldb::SBModule module = sbTarget.GetModuleAtIndex(i);
- if (module.IsValid()) {
- const CMIUtilString strModuleFilePath(
- module.GetFileSpec().GetDirectory());
- const CMIUtilString strModuleFileName(module.GetFileSpec().GetFilename());
- const CMIUtilString strModuleFullPath(CMIUtilString::Format(
- "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str()));
- const CMIUtilString strHasSymbols =
- (module.GetNumSymbols() > 0) ? "Yes" : "No";
- lldb::addr_t addrLoadS = 0xffffffffffffffff;
- lldb::addr_t addrLoadSize = 0;
- bool bHaveAddrLoad = false;
- const MIuint nSections = module.GetNumSections();
- for (MIuint j = 0; j < nSections; j++) {
- lldb::SBSection section = module.GetSectionAtIndex(j);
- lldb::addr_t addrLoad = section.GetLoadAddress(sbTarget);
- if (addrLoad != (lldb::addr_t)-1) {
- if (!bHaveAddrLoad) {
- bHaveAddrLoad = true;
- addrLoadS = addrLoad;
- }
-
- addrLoadSize += section.GetByteSize();
- }
- }
- bOk = bOk &&
- CMICmnStreamStdout::TextToStdout(CMIUtilString::Format(
- "~\"0x%016" PRIx64 "\t0x%016" PRIx64 "\t%s\t\t%s\"", addrLoadS,
- addrLoadS + addrLoadSize, strHasSymbols.c_str(),
- strModuleFullPath.c_str()));
- }
- }
-
- return bOk;
-}
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.h b/tools/lldb-mi/MICmdCmdGdbInfo.h
deleted file mode 100644
index 8ad69c49f59c..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbInfo.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- MICmdCmdGdbInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbInfo interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// Third party headers:
-#include <map>
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements GDB command "info".
-// The design of matching the info request to a request action (or
-// command) is very simple. The request function which carries out
-// the task of information gathering and printing to stdout is part of
-// *this class. Should the request function become more complicated
-// then
-// that request should really reside in a command type class. Then this
-// class instantiates a request info command for a matching request.
-// The
-// design/code of *this class then does not then become bloated. Use a
-// lightweight version of the current MI command system.
-//--
-class CMICmdCmdGdbInfo : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdGdbInfo();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdGdbInfo() override;
-
- // Typedefs:
-private:
- typedef bool (CMICmdCmdGdbInfo::*FnPrintPtr)();
- typedef std::map<CMIUtilString, FnPrintPtr> MapPrintFnNameToPrintFn_t;
-
- // Methods:
-private:
- bool GetPrintFn(const CMIUtilString &vrPrintFnName, FnPrintPtr &vrwpFn) const;
- bool PrintFnSharedLibrary();
-
- // Attributes:
-private:
- const static MapPrintFnNameToPrintFn_t ms_mapPrintFnNameToPrintFn;
- //
- const CMIUtilString m_constStrArgNamedPrint;
- bool m_bPrintFnRecognised; // True = This command has a function with a name
- // that matches the Print argument, false = not
- // found
- bool m_bPrintFnSuccessful; // True = The print function completed its task ok,
- // false = function failed for some reason
- CMIUtilString m_strPrintFnName;
- CMIUtilString m_strPrintFnError;
-};
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.cpp b/tools/lldb-mi/MICmdCmdGdbSet.cpp
deleted file mode 100644
index 162e3d5a345d..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbSet.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-//===-- MICmdCmdGdbSet.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbSet implementation.
-
-// In-house headers:
-#include "MICmdCmdGdbSet.h"
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValString.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-// Instantiations:
-const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t
- CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr = {
- {"target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync},
- {"print", &CMICmdCmdGdbSet::OptionFnPrint},
- // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, //
- // Example code if need to implement GDB set other options
- {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix},
- {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath},
- {"disassembly-flavor", &CMICmdCmdGdbSet::OptionFnDisassemblyFlavor},
- {"fallback", &CMICmdCmdGdbSet::OptionFnFallback},
- {"breakpoint", &CMICmdCmdGdbSet::OptionFnBreakpoint}};
-
-//++
-// Details: CMICmdCmdGdbSet constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbSet::CMICmdCmdGdbSet()
- : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
- m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
- m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "gdb-set";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdGdbSet destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbSet::~CMICmdCmdGdbSet() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValListOfN(
- m_constStrArgNamedGdbOption, true, true,
- CMICmdArgValListBase::eArgValType_StringAnything));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command is executed in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::Execute() {
- CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
- const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
- pArgGdbOption->GetExpectedOptions());
-
- // Get the gdb-set option to carry out. This option will be used as an action
- // which should be done. Further arguments will be used as parameters for it.
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
- const CMICmdArgValString *pOption =
- static_cast<const CMICmdArgValString *>(*it);
- const CMIUtilString strOption(pOption->GetValue());
- ++it;
-
- // Retrieve the parameter(s) for the option
- CMIUtilString::VecString_t vecWords;
- while (it != rVecWords.end()) {
- const CMICmdArgValString *pWord =
- static_cast<const CMICmdArgValString *>(*it);
- vecWords.push_back(pWord->GetValue());
-
- // Next
- ++it;
- }
-
- FnGdbOptionPtr pPrintRequestFn = nullptr;
- if (!GetOptionFn(strOption, pPrintRequestFn)) {
- // For unimplemented option handlers, fallback on a generic handler
- // ToDo: Remove this when ALL options have been implemented
- if (!GetOptionFn("fallback", pPrintRequestFn)) {
- m_bGdbOptionRecognised = false;
- m_strGdbOptionName = "fallback"; // This would be the strOption name
- return MIstatus::success;
- }
- }
-
- m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
- if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute() method.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::Acknowledge() {
- // Print error if option isn't recognized:
- // ^error,msg="The request '%s' was not recognized, not implemented"
- if (!m_bGdbOptionRecognised) {
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
- m_strGdbOptionName.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // ^done,value="%s"
- if (m_bGdbOptionFnSuccessful) {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // Print error if request failed:
- // ^error,msg="The request '%s' failed.
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdGdbSet::CreateSelf() { return new CMICmdCmdGdbSet(); }
-
-//++
-// Details: Retrieve the print function's pointer for the matching print
-// request.
-// Type: Method.
-// Args: vrPrintFnName - (R) The info requested.
-// vrwpFn - (W) The print function's pointer of the function
-// to carry out
-// Return: bool - True = Print request is implemented, false = not found.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::GetOptionFn(const CMIUtilString &vrPrintFnName,
- FnGdbOptionPtr &vrwpFn) const {
- vrwpFn = nullptr;
-
- const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
- ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
- if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
- vrwpFn = (*it).second;
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option 'target-async' to
-// prepare
-// and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnTargetAsync(
- const CMIUtilString::VecString_t &vrWords) {
- bool bAsyncMode = false;
- bool bOk = true;
-
- if (vrWords.size() > 1)
- // Too many arguments.
- bOk = false;
- else if (vrWords.size() == 0)
- // If no arguments, default is "on".
- bAsyncMode = true;
- else if (CMIUtilString::Compare(vrWords[0], "on"))
- bAsyncMode = true;
- else if (CMIUtilString::Compare(vrWords[0], "off"))
- bAsyncMode = false;
- else
- // Unrecognized argument.
- bOk = false;
-
- if (!bOk) {
- // Report error.
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC);
- return MIstatus::failure;
- }
-
- // Turn async mode on/off.
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- rSessionInfo.GetDebugger().SetAsync(bAsyncMode);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option
-// 'print-char-array-as-string' to
-// prepare and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) {
- const bool bAllArgs(vrWords.size() == 2);
- const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") ||
- CMIUtilString::Compare(vrWords[1], "1")));
- const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") ||
- CMIUtilString::Compare(vrWords[1], "0")));
- if (!bAllArgs || (!bArgOn && !bArgOff)) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS);
- return MIstatus::failure;
- }
-
- const CMIUtilString strOption(vrWords[0]);
- CMIUtilString strOptionKey;
- if (CMIUtilString::Compare(strOption, "char-array-as-string"))
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
- else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
- else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
- else {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
- return MIstatus::failure;
- }
-
- const bool bOptionValue(bArgOn);
- if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey,
- bOptionValue)) {
- m_bGbbOptionFnHasError = false;
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(),
- strOptionKey.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option 'solib-search-path' to
-// prepare
-// and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnSolibSearchPath(
- const CMIUtilString::VecString_t &vrWords) {
- // Check we have at least one argument
- if (vrWords.size() < 1) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
- return MIstatus::failure;
- }
- const CMIUtilString &rStrValSolibPath(vrWords[0]);
-
- // Add 'solib-search-path' to the shared data list
- const CMIUtilString &rStrKeySolibPath(
- m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath);
- if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeySolibPath,
- rStrValSolibPath)) {
- m_bGbbOptionFnHasError = false;
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(),
- rStrKeySolibPath.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option 'output-radix' to
-// prepare
-// and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnOutputRadix(
- const CMIUtilString::VecString_t &vrWords) {
- // Check we have at least one argument
- if (vrWords.size() < 1) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
- return MIstatus::failure;
- }
- const CMIUtilString &rStrValOutputRadix(vrWords[0]);
-
- CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format =
- CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
- MIint64 radix;
- if (rStrValOutputRadix.ExtractNumber(radix)) {
- switch (radix) {
- case 8:
- format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal;
- break;
- case 10:
- format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural;
- break;
- case 16:
- format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex;
- break;
- default:
- format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
- break;
- }
- }
- if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) {
- m_bGbbOptionFnHasError = false;
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(), "Output Radix"));
- return MIstatus::failure;
- }
- CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option 'disassembly-flavor'
-// to prepare
-// and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnDisassemblyFlavor(
- const CMIUtilString::VecString_t &vrWords) {
- // Check we have at least one argument
- if (vrWords.size() < 1) {
- m_bGbbOptionFnHasError = true;
- // m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
- return MIstatus::failure;
- }
- const CMIUtilString &rStrValDisasmFlavor(vrWords[0]);
-
- lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
- lldb::SBError error = lldb::SBDebugger::SetInternalVariable(
- "target.x86-disassembly-flavor", rStrValDisasmFlavor.c_str(),
- rDbgr.GetInstanceName());
- if (error.Fail()) {
- m_strGdbOptionFnError = error.GetCString();
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option 'breakpoint' to
-// prepare
-// and send back information asked for.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnBreakpoint(
- const CMIUtilString::VecString_t &vrWords) {
- bool bPending = false;
- bool bOk = true;
-
- if (vrWords.size() != 2)
- // Wrong number of arguments.
- bOk = false;
- else if (CMIUtilString::Compare(vrWords[0], "pending") &&
- (CMIUtilString::Compare(vrWords[1], "on") ||
- CMIUtilString::Compare(vrWords[1], "1")))
- bPending = true;
- else if (CMIUtilString::Compare(vrWords[0], "pending") &&
- (CMIUtilString::Compare(vrWords[1], "off") ||
- CMIUtilString::Compare(vrWords[1], "0")))
- bPending = false;
- else
- // Unrecognized argument(s).
- bOk = false;
-
- if (!bOk) {
- // Report error.
- m_bGbbOptionFnHasError = false;
- SetError(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT));
- return MIstatus::failure;
- }
-
- CMIUtilString sPendingVal = bPending ? "on" : "off";
- CMIUtilString sKey = "breakpoint.pending";
- if (!m_rLLDBDebugSessionInfo.SharedDataAdd(sKey, sPendingVal)) {
- m_bGbbOptionFnHasError = false;
- SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
- m_cmdData.strMiCmd.c_str(), sKey.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB set option to prepare and send
-// back the
-// requested information.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbSet::OptionFnFallback(
- const CMIUtilString::VecString_t &vrWords) {
- MIunused(vrWords);
-
- // Do nothing - intentional. This is a fallback function to do nothing.
- // This allows the search for gdb-set options to always succeed when the
- // option is not
- // found (implemented).
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.h b/tools/lldb-mi/MICmdCmdGdbSet.h
deleted file mode 100644
index c88f9976ef65..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbSet.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- MICmdCmdGdbSet.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbSet interface.
-//
-// To implement new MI commands, derive a new command class from
-// the command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "gdb-set".
-// This command does not follow the MI documentation exactly. While
-// *this
-// command is implemented it does not do anything with the gdb-set
-// variable past in.
-// The design of matching the info request to a request action (or
-// command) is very simple. The request function which carries out
-// the task of information gathering and printing to stdout is part of
-// *this class. Should the request function become more complicated
-// then
-// that request should really reside in a command type class. Then this
-// class instantiates a request info command for a matching request.
-// The
-// design/code of *this class then does not then become bloated. Use a
-// lightweight version of the current MI command system.
-//--
-class CMICmdCmdGdbSet : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdGdbSet();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdGdbSet() override;
-
- // Typedefs:
-private:
- typedef bool (CMICmdCmdGdbSet::*FnGdbOptionPtr)(
- const CMIUtilString::VecString_t &vrWords);
- typedef std::map<CMIUtilString, FnGdbOptionPtr>
- MapGdbOptionNameToFnGdbOptionPtr_t;
-
- // Methods:
-private:
- bool GetOptionFn(const CMIUtilString &vrGdbOptionName,
- FnGdbOptionPtr &vrwpFn) const;
- bool OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnBreakpoint(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords);
-
- // Attributes:
-private:
- const static MapGdbOptionNameToFnGdbOptionPtr_t
- ms_mapGdbOptionNameToFnGdbOptionPtr;
- //
- const CMIUtilString m_constStrArgNamedGdbOption;
- bool m_bGdbOptionRecognised; // True = This command has a function with a name
- // that matches the Print argument, false = not
- // found
- bool m_bGdbOptionFnSuccessful; // True = The print function completed its task
- // ok, false = function failed for some reason
- bool m_bGbbOptionFnHasError; // True = The option function has an error
- // condition (not the command!), false = option
- // function ok.
- CMIUtilString m_strGdbOptionName;
- CMIUtilString m_strGdbOptionFnError;
-};
diff --git a/tools/lldb-mi/MICmdCmdGdbShow.cpp b/tools/lldb-mi/MICmdCmdGdbShow.cpp
deleted file mode 100644
index 9ebd36202b7d..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbShow.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-//===-- MICmdCmdGdbShow.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbShow implementation.
-
-// Third party headers:
-#include "lldb/API/SBCompileUnit.h"
-#include "lldb/API/SBFrame.h"
-#include "lldb/API/SBLanguageRuntime.h"
-#include "lldb/API/SBStringList.h"
-#include "lldb/API/SBThread.h"
-
-// In-house headers:
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValString.h"
-#include "MICmdCmdGdbShow.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-// Instantiations:
-const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t
- CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
- {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
- {"print", &CMICmdCmdGdbShow::OptionFnPrint},
- {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
- {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor},
- {"fallback", &CMICmdCmdGdbShow::OptionFnFallback},
- {"breakpoint", &CMICmdCmdGdbShow::OptionFnBreakpoint}};
-
-//++
-// Details: CMICmdCmdGdbShow constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbShow::CMICmdCmdGdbShow()
- : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
- m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
- m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "gdb-show";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdGdbShow destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbShow::~CMICmdCmdGdbShow() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValListOfN(
- m_constStrArgNamedGdbOption, true, true,
- CMICmdArgValListBase::eArgValType_StringAnything));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command is executed in this
-// function.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::Execute() {
- CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
- const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
- pArgGdbOption->GetExpectedOptions());
-
- // Get the gdb-show option to carry out. This option will be used as an action
- // which should be done. Further arguments will be used as parameters for it.
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
- const CMICmdArgValString *pOption =
- static_cast<const CMICmdArgValString *>(*it);
- const CMIUtilString strOption(pOption->GetValue());
- ++it;
-
- // Retrieve the parameter(s) for the option
- CMIUtilString::VecString_t vecWords;
- while (it != rVecWords.end()) {
- const CMICmdArgValString *pWord =
- static_cast<const CMICmdArgValString *>(*it);
- vecWords.push_back(pWord->GetValue());
-
- // Next
- ++it;
- }
-
- FnGdbOptionPtr pPrintRequestFn = nullptr;
- if (!GetOptionFn(strOption, pPrintRequestFn)) {
- // For unimplemented option handlers, fallback to a generic handler
- // ToDo: Remove this when ALL options have been implemented
- if (!GetOptionFn("fallback", pPrintRequestFn)) {
- m_bGdbOptionRecognised = false;
- m_strGdbOptionName = "fallback"; // This would be the strOption name
- return MIstatus::success;
- }
- }
-
- m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
- if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute() method.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::Acknowledge() {
- // Print error if option isn't recognized:
- // ^error,msg="The request '%s' was not recognized, not implemented"
- if (!m_bGdbOptionRecognised) {
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
- m_strGdbOptionName.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // ^done,value="%s"
- if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
- const CMICmnMIValueConst miValueConst(m_strValue);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- } else if (m_bGdbOptionFnSuccessful) {
- // Ignore empty value (for fallback)
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // Print error if request failed:
- // ^error,msg="The request '%s' failed.
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }
-
-//++
-// Details: Retrieve the print function's pointer for the matching print
-// request.
-// Type: Method.
-// Args: vrPrintFnName - (R) The info requested.
-// vrwpFn - (W) The print function's pointer of the function
-// to carry out
-// Return: bool - True = Print request is implemented, false = not found.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
- FnGdbOptionPtr &vrwpFn) const {
- vrwpFn = nullptr;
-
- const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
- ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
- if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
- vrwpFn = (*it).second;
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option 'target-async' to
-// prepare
-// and send back the requested information.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnTargetAsync(
- const CMIUtilString::VecString_t &vrWords) {
- MIunused(vrWords);
-
- // Get async mode
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
-
- m_strValue = bAsyncMode ? "on" : "off";
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option 'print' to prepare
-// and send
-// back the requested information.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnPrint(
- const CMIUtilString::VecString_t &vrWords) {
- const bool bAllArgs(vrWords.size() == 1);
- if (!bAllArgs) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
- return MIstatus::failure;
- }
-
- const CMIUtilString strOption(vrWords[0]);
- CMIUtilString strOptionKey;
- bool bOptionValueDefault = false;
- if (CMIUtilString::Compare(strOption, "char-array-as-string"))
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
- else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
- else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
- strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
- bOptionValueDefault = true;
- } else {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
- strOption.c_str());
- return MIstatus::failure;
- }
-
- bool bOptionValue = false;
- bOptionValue = bOptionValueDefault
- ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
- strOptionKey, bOptionValue) ||
- bOptionValue
- : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
- strOptionKey, bOptionValue) &&
- bOptionValue;
-
- m_strValue = bOptionValue ? "on" : "off";
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option 'language' to prepare
-// and send back the requested information.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnLanguage(
- const CMIUtilString::VecString_t &vrWords) {
- MIunused(vrWords);
-
- // Get current language
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
- const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
- lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
- const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();
-
- m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
-// and send back the requested information.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
- MIunused(vrWords);
-
- // Get current disassembly flavor
- lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
- m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
- rDbgr.GetInstanceName()).GetStringAtIndex(0);
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option 'breakpoint' to
-// prepare
-// and send back the requested information.
-// Type: Method.
-// Args: vrWords - (R) List of additional parameters used by this option.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnBreakpoint(
- const CMIUtilString::VecString_t &vrWords) {
- if (vrWords.size() != 1) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS);
- return MIstatus::failure;
- }
-
- const CMIUtilString strOption(vrWords[0]);
- if (!CMIUtilString::Compare(strOption, "pending")) {
- m_bGbbOptionFnHasError = true;
- m_strGdbOptionFnError = CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION),
- strOption.c_str());
- return MIstatus::failure;
- }
-
- if (!m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending",
- m_strValue)) {
- if (m_strValue.empty())
- m_strValue = "off";
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Carry out work to complete the GDB show option to prepare and send
-// back the
-// requested information.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbShow::OptionFnFallback(
- const CMIUtilString::VecString_t &vrWords) {
- MIunused(vrWords);
-
- // Do nothing - intentional. This is a fallback function to do nothing.
- // This allows the search for gdb-show options to always succeed when the
- // option is not
- // found (implemented).
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmdCmdGdbShow.h b/tools/lldb-mi/MICmdCmdGdbShow.h
deleted file mode 100644
index 9de034c617cd..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbShow.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- MICmdCmdGdbShow.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbShow interface.
-//
-// To implement new MI commands, derive a new command class from
-// the command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "gdb-show".
-// This command does not follow the MI documentation exactly. While
-// *this
-// command is implemented it does not do anything with the gdb-set
-// variable past in.
-// The design of matching the info request to a request action (or
-// command) is very simple. The request function which carries out
-// the task of information gathering and printing to stdout is part of
-// *this class. Should the request function become more complicated
-// then
-// that request should really reside in a command type class. Then this
-// class instantiates a request info command for a matching request.
-// The
-// design/code of *this class then does not then become bloated. Use a
-// lightweight version of the current MI command system.
-//--
-class CMICmdCmdGdbShow : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdGdbShow();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdGdbShow() override;
-
- // Typedefs:
-private:
- typedef bool (CMICmdCmdGdbShow::*FnGdbOptionPtr)(
- const CMIUtilString::VecString_t &vrWords);
- typedef std::map<CMIUtilString, FnGdbOptionPtr>
- MapGdbOptionNameToFnGdbOptionPtr_t;
-
- // Methods:
-private:
- bool GetOptionFn(const CMIUtilString &vrGdbOptionName,
- FnGdbOptionPtr &vrwpFn) const;
- bool OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnLanguage(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords);
- bool OptionFnBreakpoint(const CMIUtilString::VecString_t &vrWords);
-
- // Attributes:
-private:
- const static MapGdbOptionNameToFnGdbOptionPtr_t
- ms_mapGdbOptionNameToFnGdbOptionPtr;
-
- const CMIUtilString m_constStrArgNamedGdbOption;
- bool m_bGdbOptionRecognised; // True = This command has a function with a name
- // that matches the Print argument, false = not
- // found
- bool m_bGdbOptionFnSuccessful; // True = The print function completed its task
- // ok, false = function failed for some reason
- bool m_bGbbOptionFnHasError; // True = The option function has an error
- // condition (not the command!), false = option
- // function ok.
- CMIUtilString m_strGdbOptionName;
- CMIUtilString m_strGdbOptionFnError;
- CMIUtilString m_strValue;
-};
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.cpp b/tools/lldb-mi/MICmdCmdGdbThread.cpp
deleted file mode 100644
index 132cf2c68ef8..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbThread.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- MICmdCmdGdbThread.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbThread implementation.
-
-// In-house headers:
-#include "MICmdCmdGdbThread.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdCmdGdbThread constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbThread::CMICmdCmdGdbThread() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "thread";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdGdbThread::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdThread destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbThread::~CMICmdCmdGdbThread() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbThread::Execute() {
- // Do nothing
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbThread::Acknowledge() {
- const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdGdbThread::CreateSelf() {
- return new CMICmdCmdGdbThread();
-}
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.h b/tools/lldb-mi/MICmdCmdGdbThread.h
deleted file mode 100644
index 963001f01912..000000000000
--- a/tools/lldb-mi/MICmdCmdGdbThread.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- MICmdCmdGdbThread.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbThread interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements GDB command "thread".
-//--
-class CMICmdCmdGdbThread : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdGdbThread();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdGdbThread() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.cpp b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
deleted file mode 100644
index 5aa795999535..000000000000
--- a/tools/lldb-mi/MICmdCmdMiscellanous.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-//===-- MICmdCmdMiscellanous.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbExit implementation.
-// CMICmdCmdListThreadGroups implementation.
-// CMICmdCmdInterpreterExec implementation.
-// CMICmdCmdInferiorTtySet implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBThread.h"
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdMiscellanous.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnStreamStderr.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriverBase.h"
-
-//++
-// Details: CMICmdCmdGdbExit constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbExit::CMICmdCmdGdbExit() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "gdb-exit";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdGdbExit::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdGdbExit destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdGdbExit::~CMICmdCmdGdbExit() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbExit::Execute() {
- CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(true);
- const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Destroy();
- // Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdGdbExit::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Exit);
- m_miResultRecord = miRecordResult;
-
- // Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
- // because it is using LLDB debugger
- // Give the client '=thread-group-exited,id="i1"'
- m_bHasResultRecordExtra = true;
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("id", miValueConst2);
- const CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult2);
- m_miResultRecordExtra = miOutOfBand.GetString();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdGdbExit::CreateSelf() { return new CMICmdCmdGdbExit(); }
-
-
-//++
-// Details: CMICmdCmdListThreadGroups constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdListThreadGroups::CMICmdCmdListThreadGroups()
- : m_bIsI1(false), m_bHaveArgOption(false), m_bHaveArgRecurse(false),
- m_constStrArgNamedAvailable("available"),
- m_constStrArgNamedRecurse("recurse"), m_constStrArgNamedGroup("group"),
- m_constStrArgNamedThreadGroup("i1") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "list-thread-groups";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdListThreadGroups::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdListThreadGroups destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdListThreadGroups::~CMICmdCmdListThreadGroups() {
- m_vecMIValueTuple.clear();
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdListThreadGroups::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionLong(m_constStrArgNamedAvailable, false, true));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionLong(m_constStrArgNamedRecurse, false, true,
- CMICmdArgValListBase::eArgValType_Number, 1));
- m_setCmdArgs.Add(
- new CMICmdArgValListOfN(m_constStrArgNamedGroup, false, true,
- CMICmdArgValListBase::eArgValType_Number));
- m_setCmdArgs.Add(
- new CMICmdArgValThreadGrp(m_constStrArgNamedThreadGroup, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -list-thread-groups [ --available ] [ --recurse 1 ] [
-// group ... ]
-// This command does not follow the MI documentation exactly. Has an
-// extra
-// argument "i1" to handle.
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdListThreadGroups::Execute() {
- if (m_setCmdArgs.IsArgContextEmpty())
- // No options so "top level thread groups"
- return MIstatus::success;
-
- CMICMDBASE_GETOPTION(pArgAvailable, OptionLong, m_constStrArgNamedAvailable);
- CMICMDBASE_GETOPTION(pArgRecurse, OptionLong, m_constStrArgNamedRecurse);
- CMICMDBASE_GETOPTION(pArgThreadGroup, ThreadGrp,
- m_constStrArgNamedThreadGroup);
-
- // Got some options so "threads"
- if (pArgAvailable->GetFound()) {
- if (pArgRecurse->GetFound()) {
- m_bHaveArgRecurse = true;
- return MIstatus::success;
- }
-
- m_bHaveArgOption = true;
- return MIstatus::success;
- }
- // "i1" as first argument (pos 0 of possible arg)
- if (!pArgThreadGroup->GetFound())
- return MIstatus::success;
- m_bIsI1 = true;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
-
- // Note do not check for sbProcess is IsValid(), continue
-
- m_vecMIValueTuple.clear();
- const MIuint nThreads = sbProcess.GetNumThreads();
- for (MIuint i = 0; i < nThreads; i++) {
- // GetThreadAtIndex() uses a base 0 index
- // GetThreadByIndexID() uses a base 1 index
- lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
-
- if (thread.IsValid()) {
- CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo(
- m_cmdData, thread,
- CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_NoFrames, miTuple))
- return MIstatus::failure;
-
- m_vecMIValueTuple.push_back(miTuple);
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdListThreadGroups::Acknowledge() {
- if (m_bHaveArgOption) {
- if (m_bHaveArgRecurse) {
- const CMICmnMIValueConst miValueConst(
- MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst1("i1");
- const CMICmnMIValueResult miValueResult1("id", miValueConst1);
- CMICmnMIValueTuple miTuple(miValueResult1);
-
- const CMICmnMIValueConst miValueConst2("process");
- const CMICmnMIValueResult miValueResult2("type", miValueConst2);
- miTuple.Add(miValueResult2);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- if (rSessionInfo.GetProcess().IsValid()) {
- const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
- const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
- const CMICmnMIValueConst miValueConst3(strPid);
- const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
- miTuple.Add(miValueResult3);
- }
-
- const CMICmnMIValueConst miValueConst4(
- MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
- const CMICmnMIValueResult miValueResult4("num_children", miValueConst4);
- miTuple.Add(miValueResult4);
-
- const CMICmnMIValueConst miValueConst5(
- MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
- const CMICmnMIValueResult miValueResult5("cores", miValueConst5);
- miTuple.Add(miValueResult5);
-
- const CMICmnMIValueList miValueList(miTuple);
- const CMICmnMIValueResult miValueResult6("groups", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult6);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- if (!m_bIsI1) {
- const CMICmnMIValueConst miValueConst1("i1");
- const CMICmnMIValueResult miValueResult1("id", miValueConst1);
- CMICmnMIValueTuple miTuple(miValueResult1);
-
- const CMICmnMIValueConst miValueConst2("process");
- const CMICmnMIValueResult miValueResult2("type", miValueConst2);
- miTuple.Add(miValueResult2);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- if (rSessionInfo.GetProcess().IsValid()) {
- const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
- const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
- const CMICmnMIValueConst miValueConst3(strPid);
- const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
- miTuple.Add(miValueResult3);
- }
-
- if (rSessionInfo.GetTarget().IsValid()) {
- lldb::SBTarget sbTrgt = rSessionInfo.GetTarget();
- const char *pDir = sbTrgt.GetExecutable().GetDirectory();
- const char *pFileName = sbTrgt.GetExecutable().GetFilename();
- const CMIUtilString strFile(
- CMIUtilString::Format("%s/%s",
- CMIUtilString::WithNullAsEmpty(pDir),
- CMIUtilString::WithNullAsEmpty(pFileName)));
- const CMICmnMIValueConst miValueConst4(strFile);
- const CMICmnMIValueResult miValueResult4("executable", miValueConst4);
- miTuple.Add(miValueResult4);
- }
-
- const CMICmnMIValueList miValueList(miTuple);
- const CMICmnMIValueResult miValueResult5("groups", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult5);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // Build up a list of thread information from tuples
- VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
- if (it == m_vecMIValueTuple.end()) {
- const CMICmnMIValueConst miValueConst("[]");
- const CMICmnMIValueResult miValueResult("threads", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
- CMICmnMIValueList miValueList(*it);
- ++it;
- while (it != m_vecMIValueTuple.end()) {
- const CMICmnMIValueTuple &rTuple(*it);
- miValueList.Add(rTuple);
-
- // Next
- ++it;
- }
-
- const CMICmnMIValueResult miValueResult("threads", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdListThreadGroups::CreateSelf() {
- return new CMICmdCmdListThreadGroups();
-}
-
-
-//++
-// Details: CMICmdCmdInterpreterExec constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec()
- : m_constStrArgNamedInterpreter("interpreter"),
- m_constStrArgNamedCommand("command") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "interpreter-exec";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdInterpreterExec::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdInterpreterExec destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdInterpreterExec::~CMICmdCmdInterpreterExec() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdInterpreterExec::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgNamedInterpreter, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgNamedCommand, true, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdInterpreterExec::Execute() {
- CMICMDBASE_GETOPTION(pArgInterpreter, String, m_constStrArgNamedInterpreter);
- CMICMDBASE_GETOPTION(pArgCommand, String, m_constStrArgNamedCommand);
-
- // Handle the interpreter parameter by do nothing on purpose (set to 'handled'
- // in the arg definition above)
- const CMIUtilString &rStrInterpreter(pArgInterpreter->GetValue());
- MIunused(rStrInterpreter);
-
- const CMIUtilString &rStrCommand(pArgCommand->GetValue());
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- const lldb::ReturnStatus rtn =
- rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(
- rStrCommand.c_str(), m_lldbResult, true);
- MIunused(rtn);
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdInterpreterExec::Acknowledge() {
- if (m_lldbResult.GetOutputSize() > 0) {
- const CMIUtilString line(m_lldbResult.GetOutput());
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput, miValueConst);
- const bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
- if (!bOk)
- return MIstatus::failure;
- }
- if (m_lldbResult.GetErrorSize() > 0) {
- const CMIUtilString line(m_lldbResult.GetError());
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput, miValueConst);
- const bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
- if (!bOk)
- return MIstatus::failure;
- }
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdInterpreterExec::CreateSelf() {
- return new CMICmdCmdInterpreterExec();
-}
-
-
-//++
-// Details: CMICmdCmdInferiorTtySet constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdInferiorTtySet::CMICmdCmdInferiorTtySet() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "inferior-tty-set";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdInferiorTtySet::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdInferiorTtySet destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdInferiorTtySet::~CMICmdCmdInferiorTtySet() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdInferiorTtySet::Execute() {
- // Do nothing
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdInferiorTtySet::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdInferiorTtySet::CreateSelf() {
- return new CMICmdCmdInferiorTtySet();
-}
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.h b/tools/lldb-mi/MICmdCmdMiscellanous.h
deleted file mode 100644
index 614638e59345..000000000000
--- a/tools/lldb-mi/MICmdCmdMiscellanous.h
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- MICmdCmdMiscellanous.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdGdbExit interface.
-// CMICmdCmdListThreadGroups interface.
-// CMICmdCmdInterpreterExec interface.
-// CMICmdCmdInferiorTtySet interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBCommandReturnObject.h"
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "gdb-exit".
-//--
-class CMICmdCmdGdbExit : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdGdbExit();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdGdbExit() override;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "list-thread-groups".
-// This command does not follow the MI documentation exactly.
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
-//--
-class CMICmdCmdListThreadGroups : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdListThreadGroups();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdListThreadGroups() override;
-
- // Typedefs:
-private:
- typedef std::vector<CMICmnMIValueTuple> VecMIValueTuple_t;
-
- // Attributes:
-private:
- bool m_bIsI1; // True = Yes command argument equal "i1", false = no match
- bool m_bHaveArgOption; // True = Yes "--available" present, false = not found
- bool m_bHaveArgRecurse; // True = Yes command argument "--recurse", false = no
- // found
- VecMIValueTuple_t m_vecMIValueTuple;
- const CMIUtilString m_constStrArgNamedAvailable;
- const CMIUtilString m_constStrArgNamedRecurse;
- const CMIUtilString m_constStrArgNamedGroup;
- const CMIUtilString m_constStrArgNamedThreadGroup;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "interpreter-exec".
-//--
-class CMICmdCmdInterpreterExec : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdInterpreterExec();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdInterpreterExec() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedInterpreter;
- const CMIUtilString m_constStrArgNamedCommand;
- lldb::SBCommandReturnObject m_lldbResult;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "inferior-tty-set".
-//--
-class CMICmdCmdInferiorTtySet : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdInferiorTtySet();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdInferiorTtySet() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdStack.cpp b/tools/lldb-mi/MICmdCmdStack.cpp
deleted file mode 100644
index 599db37417f5..000000000000
--- a/tools/lldb-mi/MICmdCmdStack.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//===-- MICmdCmdStack.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdStackInfoDepth implementation.
-// CMICmdCmdStackInfoFrame implementation.
-// CMICmdCmdStackListFrames implementation.
-// CMICmdCmdStackListArguments implementation.
-// CMICmdCmdStackListLocals implementation.
-// CMICmdCmdStackSelectFrame implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBThread.h"
-
-// In-house headers:
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValPrintValues.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdStack.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-#include <algorithm>
-
-//++
-// Details: CMICmdCmdStackInfoDepth constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth()
- : m_nThreadFrames(0), m_constStrArgMaxDepth("max-depth") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-info-depth";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackInfoDepth destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackInfoDepth::~CMICmdCmdStackInfoDepth() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoDepth::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgMaxDepth, false, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoDepth::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgMaxDepth, Number, m_constStrArgMaxDepth);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- m_nThreadFrames = thread.GetNumFrames();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoDepth::Acknowledge() {
- const CMIUtilString strDepth(CMIUtilString::Format("%d", m_nThreadFrames));
- const CMICmnMIValueConst miValueConst(strDepth);
- const CMICmnMIValueResult miValueResult("depth", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackInfoDepth::CreateSelf() {
- return new CMICmdCmdStackInfoDepth();
-}
-
-
-//++
-// Details: CMICmdCmdStackInfoFrame constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackInfoFrame::CMICmdCmdStackInfoFrame() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-info-frame";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackInfoFrame::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackInfoFrame destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackInfoFrame::~CMICmdCmdStackInfoFrame() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoFrame::ParseArgs() { return ParseValidateCmdOptions(); }
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoFrame::Execute() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBThread sbThread = sbProcess.GetSelectedThread();
- MIuint nFrameId = sbThread.GetSelectedFrame().GetFrameID();
- if (!rSessionInfo.MIResponseFormFrameInfo(
- sbThread, nFrameId,
- CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
- m_miValueTuple))
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackInfoFrame::Acknowledge() {
- const CMICmnMIValueResult miValueResult("frame", m_miValueTuple);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackInfoFrame::CreateSelf() {
- return new CMICmdCmdStackInfoFrame();
-}
-
-
-//++
-// Details: CMICmdCmdStackListFrames constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListFrames::CMICmdCmdStackListFrames()
- : m_nThreadFrames(0), m_constStrArgFrameLow("low-frame"),
- m_constStrArgFrameHigh("high-frame") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-list-frames";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackListFrames destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListFrames::~CMICmdCmdStackListFrames() {
- m_vecMIValueResult.clear();
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListFrames::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListFrames::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
- CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- // Frame low and high options are not mandatory
- MIuint nFrameHigh =
- pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT32_MAX;
- const MIuint nFrameLow =
- pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- MIuint nThreadFrames = thread.GetNumFrames();
-
- // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in
- // the min calc as the arg
- // is not an index, but a frame id value.
- if (nFrameHigh < UINT32_MAX) {
- nFrameHigh++;
- nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
- }
-
- m_nThreadFrames = nThreadFrames;
- if (nThreadFrames == 0)
- return MIstatus::success;
-
- m_vecMIValueResult.clear();
- for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++) {
- CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormFrameInfo(
- thread, nLevel,
- CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
- miValueTuple))
- return MIstatus::failure;
-
- const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
- m_vecMIValueResult.push_back(miValueResult8);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListFrames::Acknowledge() {
- if (m_nThreadFrames == 0) {
- // MI print "3^done,stack=[{}]"
- const CMICmnMIValueTuple miValueTuple;
- const CMICmnMIValueList miValueList(miValueTuple);
- const CMICmnMIValueResult miValueResult("stack", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- // Build up a list of thread information from tuples
- VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin();
- if (it == m_vecMIValueResult.end()) {
- // MI print "3^done,stack=[{}]"
- const CMICmnMIValueTuple miValueTuple;
- const CMICmnMIValueList miValueList(miValueTuple);
- const CMICmnMIValueResult miValueResult("stack", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
- CMICmnMIValueList miValueList(*it);
- ++it;
- while (it != m_vecMIValueResult.end()) {
- const CMICmnMIValueResult &rTuple(*it);
- miValueList.Add(rTuple);
-
- // Next
- ++it;
- }
- const CMICmnMIValueResult miValueResult("stack", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackListFrames::CreateSelf() {
- return new CMICmdCmdStackListFrames();
-}
-
-
-//++
-// Details: CMICmdCmdStackListArguments constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListArguments::CMICmdCmdStackListArguments()
- : m_bThreadInvalid(false), m_miValueList(true),
- m_constStrArgPrintValues("print-values"),
- m_constStrArgFrameLow("low-frame"), m_constStrArgFrameHigh("high-frame") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-list-arguments";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackListArguments destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListArguments::~CMICmdCmdStackListArguments() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListArguments::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListArguments::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
- CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound()) {
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
- nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- }
-
- const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
- static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
- pArgPrintValues->GetValue());
-
- MIuint nFrameLow = 0;
- MIuint nFrameHigh = UINT32_MAX;
- if (pArgFrameLow->GetFound() && pArgFrameHigh->GetFound()) {
- nFrameLow = pArgFrameLow->GetValue();
- nFrameHigh = pArgFrameHigh->GetValue() + 1;
- } else if (pArgFrameLow->GetFound() || pArgFrameHigh->GetFound()) {
- // Only low-frame or high-frame was specified but both are required
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- m_bThreadInvalid = !thread.IsValid();
- if (m_bThreadInvalid)
- return MIstatus::success;
-
- const lldb::StopReason eStopReason = thread.GetStopReason();
- if ((eStopReason == lldb::eStopReasonNone) ||
- (eStopReason == lldb::eStopReasonInvalid)) {
- m_bThreadInvalid = true;
- return MIstatus::success;
- }
-
- const MIuint nFrames = thread.GetNumFrames();
- if (nFrameLow >= nFrames) {
- // The low-frame is larger than the actual number of frames
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- nFrameHigh = std::min(nFrameHigh, nFrames);
- for (MIuint i = nFrameLow; i < nFrameHigh; i++) {
- lldb::SBFrame frame = thread.GetFrameAtIndex(i);
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes =
- CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
- eVarInfoFormat, miValueList))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
- const CMICmnMIValueResult miValueResult("level", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueResult miValueResult2("args", miValueList);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueResult miValueResult3("frame", miValueTuple);
- m_miValueList.Add(miValueResult3);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListArguments::Acknowledge() {
- if (m_bThreadInvalid) {
- // MI print "%s^done,stack-args=[]"
- const CMICmnMIValueList miValueList(true);
- const CMICmnMIValueResult miValueResult("stack-args", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // MI print
- // "%s^done,stack-args=[frame={level=\"0\",args=[%s]},frame={level=\"1\",args=[%s]}]"
- const CMICmnMIValueResult miValueResult4("stack-args", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult4);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackListArguments::CreateSelf() {
- return new CMICmdCmdStackListArguments();
-}
-
-
-//++
-// Details: CMICmdCmdStackListLocals constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListLocals::CMICmdCmdStackListLocals()
- : m_bThreadInvalid(false), m_miValueList(true),
- m_constStrArgPrintValues("print-values") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-list-locals";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackListLocals destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListLocals::~CMICmdCmdStackListLocals() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListLocals::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListLocals::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
- CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound()) {
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
- nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- }
-
- MIuint64 nFrame = UINT64_MAX;
- if (pArgFrame->GetFound()) {
- if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgFrame.c_str()));
- return MIstatus::failure;
- }
- }
-
- const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
- static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
- pArgPrintValues->GetValue());
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- m_bThreadInvalid = !thread.IsValid();
- if (m_bThreadInvalid)
- return MIstatus::success;
-
- const lldb::StopReason eStopReason = thread.GetStopReason();
- if ((eStopReason == lldb::eStopReasonNone) ||
- (eStopReason == lldb::eStopReasonInvalid)) {
- m_bThreadInvalid = true;
- return MIstatus::success;
- }
-
- lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
- : thread.GetSelectedFrame();
-
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Locals |
- CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
- if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
- eVarInfoFormat, miValueList))
- return MIstatus::failure;
-
- m_miValueList = miValueList;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListLocals::Acknowledge() {
- if (m_bThreadInvalid) {
- // MI print "%s^done,locals=[]"
- const CMICmnMIValueList miValueList(true);
- const CMICmnMIValueResult miValueResult("locals", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // MI print "%s^done,locals=[%s]"
- const CMICmnMIValueResult miValueResult("locals", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackListLocals::CreateSelf() {
- return new CMICmdCmdStackListLocals();
-}
-
-
-//++
-// Details: CMICmdCmdStackListVariables constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListVariables::CMICmdCmdStackListVariables()
- : m_bThreadInvalid(false), m_miValueList(true),
- m_constStrArgPrintValues("print-values") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-list-variables";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackListVariables::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackListVariables destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackListVariables::~CMICmdCmdStackListVariables() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListVariables::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListVariables::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
- CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound()) {
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
- nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
- }
-
- MIuint64 nFrame = UINT64_MAX;
- if (pArgFrame->GetFound()) {
- if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgFrame.c_str()));
- return MIstatus::failure;
- }
- }
-
- const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
- static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
- pArgPrintValues->GetValue());
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- m_bThreadInvalid = !thread.IsValid();
- if (m_bThreadInvalid)
- return MIstatus::success;
-
- const lldb::StopReason eStopReason = thread.GetStopReason();
- if ((eStopReason == lldb::eStopReasonNone) ||
- (eStopReason == lldb::eStopReasonInvalid)) {
- m_bThreadInvalid = true;
- return MIstatus::success;
- }
-
- lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
- : thread.GetSelectedFrame();
-
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes =
- CMICmnLLDBDebugSessionInfo::eVariableType_Arguments |
- CMICmnLLDBDebugSessionInfo::eVariableType_Locals |
- CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
- if (!rSessionInfo.MIResponseFormVariableInfo(
- frame, maskVarTypes, eVarInfoFormat, miValueList, 10, true))
- return MIstatus::failure;
- m_miValueList = miValueList;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackListVariables::Acknowledge() {
- if (m_bThreadInvalid) {
- // MI print "%s^done,variables=[]"
- const CMICmnMIValueList miValueList(true);
- const CMICmnMIValueResult miValueResult("variables", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // MI print "%s^done,variables=[%s]"
- const CMICmnMIValueResult miValueResult("variables", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackListVariables::CreateSelf() {
- return new CMICmdCmdStackListVariables();
-}
-
-
-//++
-// Details: CMICmdCmdStackSelectFrame constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackSelectFrame::CMICmdCmdStackSelectFrame()
- : m_bFrameInvalid(false), m_constStrArgFrameId("frame_id") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "stack-select-frame";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdStackSelectFrame::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdStackSelectFrame destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdStackSelectFrame::~CMICmdCmdStackSelectFrame() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackSelectFrame::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameId, true, false));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackSelectFrame::Execute() {
- CMICMDBASE_GETOPTION(pArgFrame, Number, m_constStrArgFrameId);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
-
- const MIuint nFrameId = pArgFrame->GetValue();
- m_bFrameInvalid = (nFrameId >= sbThread.GetNumFrames());
- if (m_bFrameInvalid)
- return MIstatus::success;
-
- lldb::SBFrame sbFrame = sbThread.SetSelectedFrame(nFrameId);
- m_bFrameInvalid = !sbFrame.IsValid();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmdCmdStackSelectFrame::Acknowledge() {
- if (m_bFrameInvalid) {
- // MI print "%s^error,msg=\"Command '-stack-select-frame'. Frame ID
- // invalid\""
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_FRAME_INVALID), m_cmdData.strMiCmd.c_str()));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdStackSelectFrame::CreateSelf() {
- return new CMICmdCmdStackSelectFrame();
-}
diff --git a/tools/lldb-mi/MICmdCmdStack.h b/tools/lldb-mi/MICmdCmdStack.h
deleted file mode 100644
index 04aeb5db0340..000000000000
--- a/tools/lldb-mi/MICmdCmdStack.h
+++ /dev/null
@@ -1,256 +0,0 @@
-//===-- MICmdCmdStack.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdStackInfoDepth interface.
-// CMICmdCmdStackInfoFrame interface.
-// CMICmdCmdStackListFrames interface.
-// CMICmdCmdStackListArguments interface.
-// CMICmdCmdStackListLocals interface.
-// CMICmdCmdStackSelectFrame interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-info-depth".
-//--
-class CMICmdCmdStackInfoDepth : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackInfoDepth();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackInfoDepth() override;
-
- // Attributes:
-private:
- MIuint m_nThreadFrames;
- const CMIUtilString m_constStrArgMaxDepth; // Not handled by *this command
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-info-frame".
-//--
-class CMICmdCmdStackInfoFrame : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackInfoFrame();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackInfoFrame() override;
-
- // Attributes:
-private:
- CMICmnMIValueTuple m_miValueTuple;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-list-frames".
-//--
-class CMICmdCmdStackListFrames : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackListFrames();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackListFrames() override;
-
- // Typedefs:
-private:
- typedef std::vector<CMICmnMIValueResult> VecMIValueResult_t;
-
- // Attributes:
-private:
- MIuint m_nThreadFrames;
- VecMIValueResult_t m_vecMIValueResult;
- const CMIUtilString m_constStrArgFrameLow;
- const CMIUtilString m_constStrArgFrameHigh;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-list-arguments".
-//--
-class CMICmdCmdStackListArguments : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackListArguments();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackListArguments() override;
-
- // Attributes:
-private:
- bool m_bThreadInvalid; // True = yes invalid thread, false = thread object
- // valid
- CMICmnMIValueList m_miValueList;
- const CMIUtilString m_constStrArgPrintValues;
- const CMIUtilString m_constStrArgFrameLow;
- const CMIUtilString m_constStrArgFrameHigh;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-list-locals".
-//--
-class CMICmdCmdStackListLocals : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackListLocals();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackListLocals() override;
-
- // Attributes:
-private:
- bool m_bThreadInvalid; // True = yes invalid thread, false = thread object
- // valid
- CMICmnMIValueList m_miValueList;
- const CMIUtilString m_constStrArgPrintValues;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-list-variables".
-//--
-class CMICmdCmdStackListVariables : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackListVariables();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackListVariables() override;
-
- // Attributes
-private:
- bool m_bThreadInvalid; // True = yes invalid thread, false = thread object
- // valid
- CMICmnMIValueList m_miValueList;
- const CMIUtilString m_constStrArgPrintValues;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "stack-select-frame".
-//--
-class CMICmdCmdStackSelectFrame : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdStackSelectFrame();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdStackSelectFrame() override;
-
- // Attributes:
-private:
- bool m_bFrameInvalid; // True = yes invalid frame, false = ok
- const CMIUtilString m_constStrArgFrameId;
-};
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.cpp b/tools/lldb-mi/MICmdCmdSupportInfo.cpp
deleted file mode 100644
index e17f70a90472..000000000000
--- a/tools/lldb-mi/MICmdCmdSupportInfo.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-//===-- MICmdCmdSupportInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSupportInfoMiCmdQuery implementation.
-
-// In-house headers:
-#include "MICmdCmdSupportInfo.h"
-#include "MICmdArgValString.h"
-#include "MICmdFactory.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-// Details: CMICmdCmdSupportInfoMiCmdQuery constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSupportInfoMiCmdQuery::CMICmdCmdSupportInfoMiCmdQuery()
- : m_bCmdFound(false), m_constStrArgCmdName("cmd_name") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "info-gdb-mi-command";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdSupportInfoMiCmdQuery::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdSupportInfoMiCmdQuery destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSupportInfoMiCmdQuery::~CMICmdCmdSupportInfoMiCmdQuery() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSupportInfoMiCmdQuery::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgCmdName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSupportInfoMiCmdQuery::Execute() {
- CMICMDBASE_GETOPTION(pArgNamedCmdName, String, m_constStrArgCmdName);
- const CMIUtilString &rCmdToQuery(pArgNamedCmdName->GetValue());
- const MIuint nLen = rCmdToQuery.length();
- const CMICmdFactory &rCmdFactory = CMICmdFactory::Instance();
- if ((nLen > 1) && (rCmdToQuery[0] == '-'))
- m_bCmdFound = rCmdFactory.CmdExist(rCmdToQuery.substr(1, nLen - 1).c_str());
- else
- m_bCmdFound = rCmdFactory.CmdExist(rCmdToQuery);
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSupportInfoMiCmdQuery::Acknowledge() {
- const CMICmnMIValueConst miValueConst(m_bCmdFound ? "true" : "false");
- const CMICmnMIValueResult miValueResult("exists", miValueConst);
- const CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueResult miValueResult2("command", miValueTuple);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult2);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdSupportInfoMiCmdQuery::CreateSelf() {
- return new CMICmdCmdSupportInfoMiCmdQuery();
-}
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.h b/tools/lldb-mi/MICmdCmdSupportInfo.h
deleted file mode 100644
index ba3e4a6c66a5..000000000000
--- a/tools/lldb-mi/MICmdCmdSupportInfo.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===-- MICmdCmdSupportInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSupportInfoMiCmdQuery interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "info-gdb-mi-command".
-// This command does not follow the MI documentation exactly.
-//--
-class CMICmdCmdSupportInfoMiCmdQuery : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdSupportInfoMiCmdQuery();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdSupportInfoMiCmdQuery() override;
-
- // Attributes:
-private:
- bool m_bCmdFound; // True = query for the command in command factory found,
- // false = not found not recognised
- const CMIUtilString m_constStrArgCmdName;
-};
diff --git a/tools/lldb-mi/MICmdCmdSupportList.cpp b/tools/lldb-mi/MICmdCmdSupportList.cpp
deleted file mode 100644
index e457e0101f4e..000000000000
--- a/tools/lldb-mi/MICmdCmdSupportList.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-//===-- MICmdCmdSupportList.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSupportListFeatures implementation.
-
-// In-house headers:
-#include "MICmdCmdSupportList.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueList.h"
-
-//++
-// Details: CMICmdCmdSupportListFeatures constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSupportListFeatures::CMICmdCmdSupportListFeatures() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "list-features";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdSupportListFeatures::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdSupportListFeatures destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSupportListFeatures::~CMICmdCmdSupportListFeatures() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSupportListFeatures::Execute() {
- // Do nothing
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSupportListFeatures::Acknowledge() {
- // Declare supported features here
- const CMICmnMIValueConst miValueConst1("data-read-memory-bytes");
- const CMICmnMIValueConst miValueConst2("exec-run-start-option");
- // Some features may depend on host and/or target, decide what to add below
- CMICmnMIValueList miValueList(true);
- miValueList.Add(miValueConst1);
- miValueList.Add(miValueConst2);
- const CMICmnMIValueResult miValueResult("features", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdSupportListFeatures::CreateSelf() {
- return new CMICmdCmdSupportListFeatures();
-}
diff --git a/tools/lldb-mi/MICmdCmdSupportList.h b/tools/lldb-mi/MICmdCmdSupportList.h
deleted file mode 100644
index 9e8a64bc11a1..000000000000
--- a/tools/lldb-mi/MICmdCmdSupportList.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-- MICmdCmdSupportList.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSupportListFeatures interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "list-features".
-// This command does not follow the MI documentation exactly.
-//--
-class CMICmdCmdSupportListFeatures : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdSupportListFeatures();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdSupportListFeatures() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdSymbol.cpp b/tools/lldb-mi/MICmdCmdSymbol.cpp
deleted file mode 100644
index d57d1b008e59..000000000000
--- a/tools/lldb-mi/MICmdCmdSymbol.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-//===-- MICmdCmdSymbol.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSymbolListLines implementation.
-
-// Third Party Headers:
-#include "llvm/ADT/Twine.h"
-#include "lldb/API/SBAddress.h"
-#include "lldb/API/SBLineEntry.h"
-#include "lldb/API/SBFileSpec.h"
-#include "lldb/API/SBCompileUnit.h"
-#include "lldb/API/SBSymbolContext.h"
-#include "lldb/API/SBSymbolContextList.h"
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdCmdSymbol.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueTuple.h"
-#include "MICmnMIValueResult.h"
-
-namespace {
-const CMICmnMIValueTuple
-CreateMITuplePCLine(const uint32_t addr, const uint32_t line_number) {
- const CMICmnMIValueConst miValueConstAddr("0x" + llvm::Twine::utohexstr(addr).str());
- const CMICmnMIValueConst miValueConstLine(llvm::Twine(line_number).str());
- const CMICmnMIValueResult miValueResultAddr("pc", miValueConstAddr);
- const CMICmnMIValueResult miValueResultLine("line", miValueConstLine);
- CMICmnMIValueTuple miValueTuple(miValueResultAddr);
- miValueTuple.Add(miValueResultLine);
- return miValueTuple;
-}
-} // namespace
-
-using namespace lldb; // For operator==(const SBAddress &, const SBAddress &).
-
-//++
-// Details: CMICmdCmdSymbolListLines constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSymbolListLines::CMICmdCmdSymbolListLines()
- : m_resultList(false), m_constStrArgNameFile("file") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "symbol-list-lines";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdSymbolListLines::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdSymbolListLines destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdSymbolListLines::~CMICmdCmdSymbolListLines() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSymbolListLines::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNameFile, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -symbol-list-lines file
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Symbol-Query.html#GDB_002fMI-Symbol-Query
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSymbolListLines::Execute() {
- CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile);
-
- const auto &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- if (rSessionInfo.GetTarget() == rSessionInfo.GetDebugger().GetDummyTarget()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- const lldb::SBFileSpec source_file_spec(pArgFile->GetValue().c_str(), true);
- const char *source_file_name = source_file_spec.GetFilename();
- const char *source_file_directory = source_file_spec.GetDirectory();
- const bool has_path = source_file_directory;
-
- lldb::SBSymbolContextList sc_cu_list =
- CMICmnLLDBDebugSessionInfo::Instance().GetTarget().FindCompileUnits(
- source_file_spec);
-
- bool found_something = false;
- for (uint32_t i = 0, e = sc_cu_list.GetSize(); i < e; ++i) {
- const lldb::SBCompileUnit cu =
- sc_cu_list.GetContextAtIndex(i).GetCompileUnit();
- for (uint32_t j = 0, e = cu.GetNumLineEntries(); j < e; ++j) {
- const lldb::SBLineEntry line = cu.GetLineEntryAtIndex(j);
- const lldb::SBFileSpec line_spec = line.GetFileSpec();
- if (line_spec.GetFilename() == source_file_name) {
- if (has_path && (line_spec.GetDirectory() != source_file_directory))
- continue;
- // We don't need a line with start address equals to end one,
- // so just skip it.
- const lldb::SBAddress line_start_address = line.GetStartAddress();
- const lldb::SBAddress line_end_address = line.GetEndAddress();
- if (line_start_address == line_end_address)
- continue;
- // We have a matching line.
- found_something = true;
- m_resultList.Add(CreateMITuplePCLine(
- line_start_address.GetFileAddress(),
- line.GetLine()));
- }
- }
- }
- if (!found_something) {
- SetError(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
- return MIstatus::failure;
- }
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdSymbolListLines::Acknowledge() {
- // MI print "%s^done,lines=[{pc=\"%d\",line=\"%d\"}...]"
- const CMICmnMIValueResult miValueResult("lines", m_resultList);
- m_miResultRecord = CMICmnMIResultRecord(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdSymbolListLines::CreateSelf() {
- return new CMICmdCmdSymbolListLines();
-}
diff --git a/tools/lldb-mi/MICmdCmdSymbol.h b/tools/lldb-mi/MICmdCmdSymbol.h
deleted file mode 100644
index 839b0153a772..000000000000
--- a/tools/lldb-mi/MICmdCmdSymbol.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- MICmdCmdSymbol.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdSymbolListLines interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// Third party headers:
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "symbol-list-lines".
-//--
-class CMICmdCmdSymbolListLines : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdSymbolListLines();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdSymbolListLines() override;
-
- // Attributes:
-private:
- CMICmnMIValueList m_resultList;
- const CMIUtilString m_constStrArgNameFile;
-};
diff --git a/tools/lldb-mi/MICmdCmdTarget.cpp b/tools/lldb-mi/MICmdCmdTarget.cpp
deleted file mode 100644
index 18ce038b1685..000000000000
--- a/tools/lldb-mi/MICmdCmdTarget.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-//===-- MICmdCmdTarget.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdTargetSelect implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBError.h"
-
-// In-house headers:
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValString.h"
-#include "MICmdCmdTarget.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdCmdTargetSelect constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetSelect::CMICmdCmdTargetSelect()
- : m_constStrArgNamedType("type"),
- m_constStrArgNamedParameters("parameters") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "target-select";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdTargetSelect::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdTargetSelect destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect() = default;
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetSelect::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedType, true, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgNamedParameters, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -target-select type parameters ...
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetSelect::Execute() {
- CMICMDBASE_GETOPTION(pArgType, String, m_constStrArgNamedType);
- CMICMDBASE_GETOPTION(pArgParameters, String, m_constStrArgNamedParameters);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget target = rSessionInfo.GetTarget();
-
- // Check we have a valid target.
- // Note: target created via 'file-exec-and-symbols' command.
- if (!target.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- // Verify that we are executing remotely.
- const CMIUtilString &rRemoteType(pArgType->GetValue());
- if (rRemoteType != "remote") {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_TYPE),
- m_cmdData.strMiCmd.c_str(),
- rRemoteType.c_str()));
- return MIstatus::failure;
- }
-
- // Create a URL pointing to the remote gdb stub.
- const CMIUtilString strUrl =
- CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str());
-
- lldb::SBError error;
- // Ask LLDB to connect to the target port.
- const char *pPlugin("gdb-remote");
- lldb::SBProcess process = target.ConnectRemote(
- rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error);
-
- // Verify that we have managed to connect successfully.
- if (!process.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN),
- m_cmdData.strMiCmd.c_str(),
- error.GetCString()));
- return MIstatus::failure;
- }
-
- // Set the environment path if we were given one.
- CMIUtilString strWkDir;
- if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(
- rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir)) {
- lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
- if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str())) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
- m_cmdData.strMiCmd.c_str(),
- "target-select"));
- return MIstatus::failure;
- }
- }
-
- // Set the shared object path if we were given one.
- CMIUtilString strSolibPath;
- if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(
- rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath))
- target.AppendImageSearchPath(".", strSolibPath.c_str(), error);
-
- return HandleSBError(error);
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetSelect::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Connected);
- m_miResultRecord = miRecordResult;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
- // Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
- // because it is using LLDB debugger
- // Give the client '=thread-group-started,id="i1"'
- m_bHasResultRecordExtra = true;
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("id", miValueConst2);
- const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
- const CMICmnMIValueConst miValueConst(strPid);
- const CMICmnMIValueResult miValueResult("pid", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
- miOutOfBand.Add(miValueResult);
- m_miResultRecordExtra = miOutOfBand.GetString();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdTargetSelect::CreateSelf() {
- return new CMICmdCmdTargetSelect();
-}
-
-//++
-// Details: CMICmdCmdTargetAttach constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetAttach::CMICmdCmdTargetAttach()
- : m_constStrArgPid("pid"), m_constStrArgNamedFile("n"),
- m_constStrArgWaitFor("waitfor") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "target-attach";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdTargetAttach::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdTargetAttach destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetAttach::~CMICmdCmdTargetAttach() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetAttach::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgPid, false, true));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgNamedFile, false, true,
- CMICmdArgValListBase::eArgValType_String, 1));
- m_setCmdArgs.Add(
- new CMICmdArgValOptionLong(m_constStrArgWaitFor, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -target-attach file
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetAttach::Execute() {
- CMICMDBASE_GETOPTION(pArgPid, Number, m_constStrArgPid);
- CMICMDBASE_GETOPTION(pArgFile, OptionShort, m_constStrArgNamedFile);
- CMICMDBASE_GETOPTION(pArgWaitFor, OptionLong, m_constStrArgWaitFor);
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- // If the current target is invalid, create one
- lldb::SBTarget target = rSessionInfo.GetTarget();
- if (!target.IsValid()) {
- target = rSessionInfo.GetDebugger().CreateTarget(nullptr);
- if (!target.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
- }
-
- lldb::SBError error;
- lldb::SBListener listener;
- if (pArgPid->GetFound() && pArgPid->GetValid()) {
- lldb::pid_t pid;
- pid = pArgPid->GetValue();
- target.AttachToProcessWithID(listener, pid, error);
- } else if (pArgFile->GetFound() && pArgFile->GetValid()) {
- bool bWaitFor = (pArgWaitFor->GetFound());
- CMIUtilString file;
- pArgFile->GetExpectedOption<CMICmdArgValString>(file);
- target.AttachToProcessWithName(listener, file.c_str(), bWaitFor, error);
- } else {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_BAD_ARGS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBStream errMsg;
- if (error.Fail()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_FAILED),
- m_cmdData.strMiCmd.c_str(),
- errMsg.GetData()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetAttach::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
- // Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
- // because it is using LLDB debugger
- // Give the client '=thread-group-started,id="i1"'
- m_bHasResultRecordExtra = true;
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("id", miValueConst2);
- const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
- const CMICmnMIValueConst miValueConst(strPid);
- const CMICmnMIValueResult miValueResult("pid", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
- miOutOfBand.Add(miValueResult);
- m_miResultRecordExtra = miOutOfBand.GetString();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdTargetAttach::CreateSelf() {
- return new CMICmdCmdTargetAttach();
-}
-
-//++
-// Details: CMICmdCmdTargetDetach constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetDetach::CMICmdCmdTargetDetach() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "target-detach";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdTargetDetach::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdTargetDetach destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTargetDetach::~CMICmdCmdTargetDetach() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetDetach::ParseArgs() { return MIstatus::success; }
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Synopsis: -target-attach file
-// Ref:
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetDetach::Execute() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- lldb::SBProcess process = rSessionInfo.GetProcess();
-
- if (!process.IsValid()) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- process.Detach();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTargetDetach::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdTargetDetach::CreateSelf() {
- return new CMICmdCmdTargetDetach();
-}
diff --git a/tools/lldb-mi/MICmdCmdTarget.h b/tools/lldb-mi/MICmdCmdTarget.h
deleted file mode 100644
index 5cb140fd68b9..000000000000
--- a/tools/lldb-mi/MICmdCmdTarget.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===-- MICmdCmdTarget.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdTargetSelect interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "target-select".
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-//--
-class CMICmdCmdTargetSelect : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdTargetSelect();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdTargetSelect() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgNamedType;
- const CMIUtilString m_constStrArgNamedParameters;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "target-attach".
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-//--
-class CMICmdCmdTargetAttach : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdTargetAttach();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdTargetAttach() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgPid;
- const CMIUtilString m_constStrArgNamedFile;
- const CMIUtilString m_constStrArgWaitFor;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "target-attach".
-// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
-//--
-class CMICmdCmdTargetDetach : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdTargetDetach();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdTargetDetach() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp
deleted file mode 100644
index e0c74f925a9b..000000000000
--- a/tools/lldb-mi/MICmdCmdThread.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-//===-- MICmdCmdThread.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdThreadInfo implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBBreakpointLocation.h"
-#include "lldb/API/SBThread.h"
-
-// In-house headers:
-#include "MICmdArgValNumber.h"
-#include "MICmdCmdThread.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdCmdThreadInfo constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdThreadInfo::CMICmdCmdThreadInfo()
- : m_bSingleThread(false), m_bThreadInvalid(true),
- m_constStrArgNamedThreadId("thread-id"), m_bHasCurrentThread(false) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "thread-info";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdThreadInfo::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdThreadInfo destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdThreadInfo::~CMICmdCmdThreadInfo() { m_vecMIValueTuple.clear(); }
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdThreadInfo::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValNumber(m_constStrArgNamedThreadId, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdThreadInfo::Execute() {
- CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId);
- MIuint nThreadId = 0;
- if (pArgThreadId->GetFound() && pArgThreadId->GetValid()) {
- m_bSingleThread = true;
- nThreadId = static_cast<MIuint>(pArgThreadId->GetValue());
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
-
- if (m_bSingleThread) {
- thread = sbProcess.GetThreadByIndexID(nThreadId);
- m_bThreadInvalid = !thread.IsValid();
- if (m_bThreadInvalid)
- return MIstatus::success;
-
- CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo(
- m_cmdData, thread,
- CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
- return MIstatus::failure;
-
- m_miValueTupleThread = miTuple;
-
- return MIstatus::success;
- }
-
- // Multiple threads
- m_vecMIValueTuple.clear();
- const MIuint nThreads = sbProcess.GetNumThreads();
- for (MIuint i = 0; i < nThreads; i++) {
- lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
- if (thread.IsValid()) {
- CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo(
- m_cmdData, thread,
- CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
- return MIstatus::failure;
-
- m_vecMIValueTuple.push_back(miTuple);
- }
- }
-
- // -thread-info with multiple threads ends with the current thread id if any
- if (thread.IsValid()) {
- const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID()));
- CMICmnMIValueConst miValueCurrThreadId(strId);
- m_miValueCurrThreadId = miValueCurrThreadId;
- m_bHasCurrentThread = true;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdThreadInfo::Acknowledge() {
- if (m_bSingleThread) {
- if (m_bThreadInvalid) {
- const CMICmnMIValueConst miValueConst("invalid thread id");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // MI print
- // "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
- const CMICmnMIValueList miValueList(m_miValueTupleThread);
- const CMICmnMIValueResult miValueResult("threads", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- // Build up a list of thread information from tuples
- VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
- if (it == m_vecMIValueTuple.end()) {
- const CMICmnMIValueConst miValueConst("[]");
- const CMICmnMIValueResult miValueResult("threads", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
- CMICmnMIValueList miValueList(*it);
- ++it;
- while (it != m_vecMIValueTuple.end()) {
- const CMICmnMIValueTuple &rTuple(*it);
- miValueList.Add(rTuple);
-
- // Next
- ++it;
- }
-
- CMICmnMIValueResult miValueResult("threads", miValueList);
- if (m_bHasCurrentThread) {
- CMIUtilString strCurrThreadId = "current-thread-id";
- miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId);
- }
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdThreadInfo::CreateSelf() {
- return new CMICmdCmdThreadInfo();
-}
diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h
deleted file mode 100644
index 413e293447ac..000000000000
--- a/tools/lldb-mi/MICmdCmdThread.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MICmdCmdThread.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdThreadInfo interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "thread-info".
-//--
-class CMICmdCmdThreadInfo : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdThreadInfo();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdThreadInfo() override;
-
- // Typedefs:
-private:
- typedef std::vector<CMICmnMIValueTuple> VecMIValueTuple_t;
-
- // Attributes:
-private:
- CMICmnMIValueTuple m_miValueTupleThread;
- bool m_bSingleThread; // True = yes single thread, false = multiple threads
- bool m_bThreadInvalid; // True = invalid, false = ok
- VecMIValueTuple_t m_vecMIValueTuple;
- const CMIUtilString m_constStrArgNamedThreadId;
-
- // mi value of current-thread-id if multiple threads are requested
- bool m_bHasCurrentThread;
- CMICmnMIValue m_miValueCurrThreadId;
-};
diff --git a/tools/lldb-mi/MICmdCmdTrace.cpp b/tools/lldb-mi/MICmdCmdTrace.cpp
deleted file mode 100644
index 1daa18010c97..000000000000
--- a/tools/lldb-mi/MICmdCmdTrace.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- MICmdCmdTrace.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdTraceStatus implementation.
-
-// In-house headers:
-#include "MICmdCmdTrace.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-//++
-// Details: CMICmdCmdTraceStatus constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTraceStatus::CMICmdCmdTraceStatus() {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "trace-status";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdTraceStatus::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdTraceStatus destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdTraceStatus::~CMICmdCmdTraceStatus() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTraceStatus::Execute() {
- // Do nothing
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdTraceStatus::Acknowledge() {
- const CMICmnMIValueConst miValueConst(MIRSRC(IDS_CMD_ERR_NOT_IMPLEMENTED));
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdTraceStatus::CreateSelf() {
- return new CMICmdCmdTraceStatus();
-}
diff --git a/tools/lldb-mi/MICmdCmdTrace.h b/tools/lldb-mi/MICmdCmdTrace.h
deleted file mode 100644
index 8796de55b958..000000000000
--- a/tools/lldb-mi/MICmdCmdTrace.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- MICmdCmdTrace.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdTraceStatus interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "trace-status".
-//--
-class CMICmdCmdTraceStatus : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdTraceStatus();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdTraceStatus() override;
-};
diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp
deleted file mode 100644
index 3063b1b464dc..000000000000
--- a/tools/lldb-mi/MICmdCmdVar.cpp
+++ /dev/null
@@ -1,1460 +0,0 @@
-//===-- MICmdCmdVar.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdVarCreate implementation.
-// CMICmdCmdVarUpdate implementation.
-// CMICmdCmdVarDelete implementation.
-// CMICmdCmdVarAssign implementation.
-// CMICmdCmdVarSetFormat implementation.
-// CMICmdCmdVarListChildren implementation.
-// CMICmdCmdVarEvaluateExpression implementation.
-// CMICmdCmdVarInfoPathExpression implementation.
-// CMICmdCmdVarShowAttributes implementation.
-
-// Third Party Headers:
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBThread.h"
-#include "lldb/API/SBType.h"
-
-// In-house headers:
-#include "MICmdArgValListOfN.h"
-#include "MICmdArgValNumber.h"
-#include "MICmdArgValOptionLong.h"
-#include "MICmdArgValOptionShort.h"
-#include "MICmdArgValPrintValues.h"
-#include "MICmdArgValString.h"
-#include "MICmdArgValThreadGrp.h"
-#include "MICmdCmdVar.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLLDBProxySBValue.h"
-#include "MICmnLLDBUtilSBValue.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-
-#include <algorithm>
-
-//++
-// Details: CMICmdCmdVarCreate constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarCreate::CMICmdCmdVarCreate()
- : m_nChildren(0), m_nThreadId(0), m_strType("??"), m_bValid(false),
- m_strValue("??"), m_constStrArgName("name"),
- m_constStrArgFrameAddr("frame-addr"),
- m_constStrArgExpression("expression") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-create";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarCreate destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarCreate::~CMICmdCmdVarCreate() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarCreate::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, false, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFrameAddr, false, true));
- m_setCmdArgs.Add(
- new CMICmdArgValString(m_constStrArgExpression, true, true, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarCreate::Execute() {
- CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
- CMICMDBASE_GETOPTION(pArgFrameAddr, String, m_constStrArgFrameAddr);
- CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
-
- // Retrieve the --thread option's thread ID (only 1)
- MIuint64 nThreadId = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgThread.c_str()));
- return MIstatus::failure;
- }
-
- // Retrieve the --frame option's number
- MIuint64 nFrame = UINT64_MAX;
- if (pArgThread->GetFound() &&
- !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgFrame.c_str()));
- return MIstatus::failure;
- }
-
- const CMICmdArgValOptionLong::VecArgObjPtr_t &rVecFrameId(
- pArgFrame->GetExpectedOptions());
- CMICmdArgValOptionLong::VecArgObjPtr_t::const_iterator it2 =
- rVecFrameId.begin();
- if (it2 != rVecFrameId.end()) {
- const CMICmdArgValNumber *pOption = static_cast<CMICmdArgValNumber *>(*it2);
- nFrame = pOption->GetValue();
- }
-
- m_strVarName = "<unnamedvariable>";
- if (pArgName->GetFound()) {
- const CMIUtilString &rArg = pArgName->GetValue();
- const bool bAutoName = (rArg == "-");
- if (bAutoName) {
- m_strVarName = CMIUtilString::Format(
- "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
- CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
- } else
- m_strVarName = rArg;
- }
-
- bool bCurrentFrame = false;
- if (pArgFrameAddr->GetFound()) {
- const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
- bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
- if (!bCurrentFrame && (nFrame == UINT64_MAX)) {
- // FIXME: *addr isn't implemented. Exit with error if --thread isn't
- // specified.
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
- m_cmdData.strMiCmd.c_str(),
- m_constStrArgFrame.c_str()));
- return MIstatus::failure;
- }
- }
-
- const CMIUtilString &rStrExpression(pArgExpression->GetValue());
- m_strExpression = rStrExpression;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = (nThreadId != UINT64_MAX)
- ? sbProcess.GetThreadByIndexID(nThreadId)
- : sbProcess.GetSelectedThread();
- m_nThreadId = thread.GetIndexID();
- lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame()
- : thread.GetFrameAtIndex(nFrame);
- lldb::SBValue value;
-
- if (rStrExpression[0] == '$') {
- const CMIUtilString rStrRegister(rStrExpression.substr(1));
- value = frame.FindRegister(rStrRegister.c_str());
- } else {
- const bool bArgs = true;
- const bool bLocals = true;
- const bool bStatics = true;
- const bool bInScopeOnly = true;
- const lldb::SBValueList valueList =
- frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
- value = valueList.GetFirstValueByName(rStrExpression.c_str());
- }
-
- if (!value.IsValid())
- value = frame.EvaluateExpression(rStrExpression.c_str());
-
- if (value.IsValid() && value.GetError().Success()) {
- CompleteSBValue(value);
- m_bValid = true;
- m_nChildren = value.GetNumChildren();
- m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
-
- // This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
- // varObjs
- CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName,
- value);
- m_strValue = varObj.GetValueFormatted();
- } else {
- m_strValue = value.GetError().GetCString();
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarCreate::Acknowledge() {
- if (m_bValid) {
- // MI print
- // "%s^done,name=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%llu\",has_more=\"%u\""
- const CMICmnMIValueConst miValueConst(m_strVarName);
- CMICmnMIValueResult miValueResultAll("name", miValueConst);
- const CMIUtilString strNumChild(CMIUtilString::Format("%d", m_nChildren));
- const CMICmnMIValueConst miValueConst2(strNumChild);
- miValueResultAll.Add("numchild", miValueConst2);
- const CMICmnMIValueConst miValueConst3(m_strValue);
- miValueResultAll.Add("value", miValueConst3);
- const CMICmnMIValueConst miValueConst4(m_strType);
- miValueResultAll.Add("type", miValueConst4);
- const CMIUtilString strThreadId(CMIUtilString::Format("%llu", m_nThreadId));
- const CMICmnMIValueConst miValueConst5(strThreadId);
- miValueResultAll.Add("thread-id", miValueConst5);
- const CMICmnMIValueConst miValueConst6("0");
- miValueResultAll.Add("has_more", miValueConst6);
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResultAll);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- CMIUtilString strErrMsg(m_strValue);
- if (m_strValue.empty())
- strErrMsg = CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
- const CMICmnMIValueConst miValueConst(
- strErrMsg.Escape(true /* vbEscapeQuotes */));
- CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarCreate::CreateSelf() {
- return new CMICmdCmdVarCreate();
-}
-
-//++
-// Details: Complete SBValue object and its children to get
-// SBValue::GetValueDidChange
-// work.
-// Type: Method.
-// Args: vrwValue - (R) Value to update.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue) {
- // Force a value to update
- vrwValue.GetValueDidChange();
-
- // And update its children
- lldb::SBType valueType = vrwValue.GetType();
- if (!valueType.IsPointerType() && !valueType.IsReferenceType()) {
- const MIuint nChildren = vrwValue.GetNumChildren();
- for (MIuint i = 0; i < nChildren; ++i) {
- lldb::SBValue member = vrwValue.GetChildAtIndex(i);
- if (member.IsValid())
- CompleteSBValue(member);
- }
- }
-}
-
-
-//++
-// Details: CMICmdCmdVarUpdate constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarUpdate::CMICmdCmdVarUpdate()
- : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
- m_bValueChanged(false), m_miValueList(true) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-update";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarUpdate destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarUpdate::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarUpdate::Execute() {
- CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
-
- CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
- if (pArgPrintValues->GetFound())
- eVarInfoFormat =
- static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
- pArgPrintValues->GetValue());
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBValue &rValue = varObj.GetValue();
- if (!ExamineSBValueForChange(rValue, m_bValueChanged))
- return MIstatus::failure;
-
- if (m_bValueChanged) {
- varObj.UpdateValue();
- const bool bPrintValue(
- (eVarInfoFormat ==
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
- (eVarInfoFormat ==
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
- rValue.GetNumChildren() == 0));
- const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
- const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
- MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr,
- strInScope);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarUpdate::Acknowledge() {
- if (m_bValueChanged) {
- // MI print
- // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
- CMICmnMIValueResult miValueResult("changelist", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- } else {
- // MI print "%s^done,changelist=[]"
- const CMICmnMIValueList miValueList(true);
- CMICmnMIValueResult miValueResult6("changelist", miValueList);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult6);
- m_miResultRecord = miRecordResult;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarUpdate::CreateSelf() {
- return new CMICmdCmdVarUpdate();
-}
-
-//++
-// Details: Form the MI response for multiple variables.
-// Type: Method.
-// Args: vrStrVarName - (R) Session var object's name.
-// vpValue - (R) Text version of the value held in the
-// variable.
-// vrStrScope - (R) In scope "yes" or "no".
-// Return: None.
-// Throws: None.
-//--
-void CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName,
- const char *const vpValue,
- const CMIUtilString &vrStrScope) {
- // MI print
- // "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
- const CMICmnMIValueConst miValueConst(vrStrVarName);
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- if (vpValue != nullptr) {
- const CMICmnMIValueConst miValueConst2(vpValue);
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- }
- const CMICmnMIValueConst miValueConst3(vrStrScope);
- const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
- miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("false");
- const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueConst miValueConst5("0");
- const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
- miValueTuple.Add(miValueResult5);
- m_miValueList.Add(miValueTuple);
-}
-
-//++
-// Details: Determine if the var object was changed.
-// Type: Method.
-// Args: vrVarObj - (R) Session var object to examine.
-// vrwbChanged - (W) True = The var object was changed,
-// False = It was not changed.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue,
- bool &vrwbChanged) {
- if (vrwValue.GetValueDidChange()) {
- vrwbChanged = true;
- return MIstatus::success;
- }
-
- const MIuint nChildren = vrwValue.GetNumChildren();
- for (MIuint i = 0; i < nChildren; ++i) {
- lldb::SBValue member = vrwValue.GetChildAtIndex(i);
- if (!member.IsValid())
- continue;
-
- // skip pointers and references to avoid infinite loop
- if (member.GetType().GetTypeFlags() &
- (lldb::eTypeIsPointer | lldb::eTypeIsReference))
- continue;
-
- // Handle composite types (i.e. struct or arrays)
- if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
- return MIstatus::success;
- }
- vrwbChanged = false;
- return MIstatus::success;
-}
-
-
-//++
-// Details: CMICmdCmdVarDelete constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarDelete::CMICmdCmdVarDelete() : m_constStrArgName("name") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-delete";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
-}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarDelete::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: CMICmdCmdVarDelete destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarDelete::~CMICmdCmdVarDelete() {}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarDelete::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(rVarObjName);
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarDelete::Acknowledge() {
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarDelete::CreateSelf() {
- return new CMICmdCmdVarDelete();
-}
-
-
-//++
-// Details: CMICmdCmdVarAssign constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarAssign::CMICmdCmdVarAssign()
- : m_bOk(true), m_constStrArgName("name"),
- m_constStrArgExpression("expression") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-assign";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarAssign destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarAssign::~CMICmdCmdVarAssign() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarAssign::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgExpression, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarAssign::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
- CMICMDBASE_GETOPTION(pArgExpression, String, m_constStrArgExpression);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- const CMIUtilString &rExpression(pArgExpression->GetValue());
-
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
- m_varObjName = rVarObjName;
-
- CMIUtilString strExpression(rExpression.Trim());
- strExpression = strExpression.Trim('"');
- lldb::SBValue &rValue(const_cast<lldb::SBValue &>(varObj.GetValue()));
- m_bOk = rValue.SetValueFromCString(strExpression.c_str());
- if (m_bOk)
- varObj.UpdateValue();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarAssign::Acknowledge() {
- if (m_bOk) {
- // MI print "%s^done,value=\"%s\""
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
- const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst("expression could not be evaluated");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarAssign::CreateSelf() {
- return new CMICmdCmdVarAssign();
-}
-
-
-//++
-// Details: CMICmdCmdVarSetFormat constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat()
- : m_constStrArgName("name"), m_constStrArgFormatSpec("format-spec") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-set-format";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarSetFormat destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarSetFormat::~CMICmdCmdVarSetFormat() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarSetFormat::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormatSpec, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarSetFormat::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
- CMICMDBASE_GETOPTION(pArgFormatSpec, String, m_constStrArgFormatSpec);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- const CMIUtilString &rExpression(pArgFormatSpec->GetValue());
-
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
- if (!varObj.SetVarFormat(
- CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
- rExpression))) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_ENUM_INVALID),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str(), rExpression.c_str()));
- return MIstatus::failure;
- }
- varObj.UpdateValue();
-
- m_varObjName = rVarObjName;
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarSetFormat::Acknowledge() {
- // MI print
- // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
- const CMICmnMIValueConst miValueConst(m_varObjName);
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(varObj.GetValueFormatted());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- const CMICmnMIValueConst miValueConst3(rValue.IsInScope() ? "true" : "false");
- const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
- miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("false");
- const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueConst miValueConst5("0");
- const CMICmnMIValueResult miValueResult5("type_changed", miValueConst5);
- miValueTuple.Add(miValueResult5);
- const CMICmnMIValueList miValueList(miValueTuple);
- const CMICmnMIValueResult miValueResult6("changelist", miValueList);
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult6);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarSetFormat::CreateSelf() {
- return new CMICmdCmdVarSetFormat();
-}
-
-
-//++
-// Details: CMICmdCmdVarListChildren constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarListChildren::CMICmdCmdVarListChildren()
- : m_constStrArgPrintValues("print-values"), m_constStrArgName("name"),
- m_constStrArgFrom("from"), m_constStrArgTo("to"), m_bValueValid(false),
- m_nChildren(0), m_miValueList(true), m_bHasMore(false) {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-list-children";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarListChildren destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarListChildren::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrom, false, true));
- m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgTo, false, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarListChildren::Execute() {
- CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
- CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
- CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
-
- CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
- if (pArgPrintValues->GetFound())
- eVarInfoFormat =
- static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
- pArgPrintValues->GetValue());
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- MIuint nFrom = 0;
- MIuint nTo = UINT32_MAX;
- if (pArgFrom->GetFound() && pArgTo->GetFound()) {
- nFrom = pArgFrom->GetValue();
- nTo = pArgTo->GetValue();
- } else if (pArgFrom->GetFound() || pArgTo->GetFound()) {
- // Only from or to was specified but both are required
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID),
- m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- m_bValueValid = rValue.IsValid();
- if (!m_bValueValid)
- return MIstatus::success;
-
- const MIuint nChildren = rValue.GetNumChildren();
- m_bHasMore = nTo < nChildren;
- nTo = std::min(nTo, nChildren);
- m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
- for (MIuint i = nFrom; i < nTo; i++) {
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- const CMICmnLLDBUtilSBValue utilValue(member);
- const CMIUtilString strExp = utilValue.GetName();
- const CMIUtilString name(
- strExp.empty() ? CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i)
- : CMIUtilString::Format("%s.%s", rVarObjName.c_str(),
- strExp.c_str()));
- const MIuint nChildren = member.GetNumChildren();
- const CMIUtilString strThreadId(
- CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
-
- // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of
- // varObjs
- CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
-
- // MI print
- // "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
- const CMICmnMIValueConst miValueConst(name);
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(strExp);
- const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
- const CMICmnMIValueConst miValueConst3(strNumChild);
- const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
- miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
- const CMICmnMIValueResult miValueResult5("type", miValueConst5);
- miValueTuple.Add(miValueResult5);
- const CMICmnMIValueConst miValueConst6(strThreadId);
- const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
- miValueTuple.Add(miValueResult6);
- // nChildren == 0 is used to check for simple values
- if (eVarInfoFormat ==
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
- (eVarInfoFormat ==
- CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues &&
- nChildren == 0)) {
- const CMIUtilString strValue(
- CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
- member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
- const CMICmnMIValueConst miValueConst7(strValue);
- const CMICmnMIValueResult miValueResult7("value", miValueConst7);
- miValueTuple.Add(miValueResult7);
- }
- const CMICmnMIValueConst miValueConst8("0");
- const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
- miValueTuple.Add(miValueResult8);
- const CMICmnMIValueResult miValueResult9("child", miValueTuple);
- m_miValueList.Add(miValueResult9);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarListChildren::Acknowledge() {
- if (m_bValueValid) {
- // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
- const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
- const CMICmnMIValueConst miValueConst(strNumChild);
- CMICmnMIValueResult miValueResult("numchild", miValueConst);
- if (m_nChildren != 0)
- miValueResult.Add("children", m_miValueList);
- const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
- const CMICmnMIValueConst miValueConst2(strHasMore);
- miValueResult.Add("has_more", miValueConst2);
-
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
-
- // MI print "%s^error,msg=\"variable invalid\""
- const CMICmnMIValueConst miValueConst("variable invalid");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarListChildren::CreateSelf() {
- return new CMICmdCmdVarListChildren();
-}
-
-
-//++
-// Details: CMICmdCmdVarEvaluateExpression constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression()
- : m_bValueValid(true), m_constStrArgFormatSpec("-f"),
- m_constStrArgName("name") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-evaluate-expression";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarEvaluateExpression destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarEvaluateExpression::~CMICmdCmdVarEvaluateExpression() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarEvaluateExpression::ParseArgs() {
- m_setCmdArgs.Add(
- new CMICmdArgValOptionShort(m_constStrArgFormatSpec, false, false,
- CMICmdArgValListBase::eArgValType_String, 1));
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarEvaluateExpression::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- m_bValueValid = rValue.IsValid();
- if (!m_bValueValid)
- return MIstatus::success;
-
- m_varObjName = rVarObjName;
- varObj.UpdateValue();
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarEvaluateExpression::Acknowledge() {
- if (m_bValueValid) {
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_varObjName, varObj);
- const CMICmnMIValueConst miValueConst(varObj.GetValueFormatted());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst("variable invalid");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarEvaluateExpression::CreateSelf() {
- return new CMICmdCmdVarEvaluateExpression();
-}
-
-
-//++
-// Details: CMICmdCmdVarInfoPathExpression constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression()
- : m_bValueValid(true), m_constStrArgName("name") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-info-path-expression";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarInfoPathExpression destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarInfoPathExpression::~CMICmdCmdVarInfoPathExpression() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarInfoPathExpression::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarInfoPathExpression::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- m_bValueValid = rValue.IsValid();
- if (!m_bValueValid)
- return MIstatus::success;
-
- lldb::SBStream stream;
- if (!rValue.GetExpressionPath(stream, true)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- const char *pPathExpression = stream.GetData();
- if (pPathExpression == nullptr) {
- // Build expression from what we do know
- m_strPathExpression = varObj.GetNameReal();
- return MIstatus::success;
- }
-
- // Has LLDB returned a var signature of it's own
- if (pPathExpression[0] != '$') {
- m_strPathExpression = pPathExpression;
- return MIstatus::success;
- }
-
- // Build expression from what we do know
- const CMIUtilString &rVarParentName(varObj.GetVarParentName());
- if (rVarParentName.empty()) {
- m_strPathExpression = varObj.GetNameReal();
- } else {
- CMICmnLLDBDebugSessionInfoVarObj varObjParent;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarParentName,
- varObjParent)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarParentName.c_str()));
- return MIstatus::failure;
- }
- m_strPathExpression =
- CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(),
- varObj.GetNameReal().c_str());
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarInfoPathExpression::Acknowledge() {
- if (m_bValueValid) {
- const CMICmnMIValueConst miValueConst(m_strPathExpression);
- const CMICmnMIValueResult miValueResult("path_expr", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
- return MIstatus::success;
- }
-
- const CMICmnMIValueConst miValueConst("variable invalid");
- const CMICmnMIValueResult miValueResult("msg", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarInfoPathExpression::CreateSelf() {
- return new CMICmdCmdVarInfoPathExpression();
-}
-
-
-//++
-// Details: CMICmdCmdVarShowAttributes constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes()
- : m_constStrArgName("name") {
- // Command factory matches this name with that received from the stdin stream
- m_strMiCmd = "var-show-attributes";
-
- // Required by the CMICmdFactory when registering *this command
- m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
-}
-
-//++
-// Details: CMICmdCmdVarShowAttributes destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes() {}
-
-//++
-// Details: The invoker requires this function. The parses the command line
-// options
-// arguments to extract values for each of those arguments.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarShowAttributes::ParseArgs() {
- m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgName, true, true));
- return ParseValidateCmdOptions();
-}
-
-//++
-// Details: The invoker requires this function. The command does work in this
-// function.
-// The command is likely to communicate with the LLDB SBDebugger in
-// here.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarShowAttributes::Execute() {
- CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
-
- const CMIUtilString &rVarObjName(pArgName->GetValue());
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST),
- m_cmdData.strMiCmd.c_str(),
- rVarObjName.c_str()));
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: The invoker requires this function. The command prepares a MI Record
-// Result
-// for the work carried out in the Execute().
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdCmdVarShowAttributes::Acknowledge() {
- // MI output: "%s^done,status=\"editable\"]"
- const CMICmnMIValueConst miValueConst("editable");
- const CMICmnMIValueResult miValueResult("status", miValueConst);
- const CMICmnMIResultRecord miRecordResult(
- m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
- miValueResult);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Required by the CMICmdFactory when registering *this command. The
-// factory
-// calls this function to create an instance of *this command.
-// Type: Static method.
-// Args: None.
-// Return: CMICmdBase * - Pointer to a new command.
-// Throws: None.
-//--
-CMICmdBase *CMICmdCmdVarShowAttributes::CreateSelf() {
- return new CMICmdCmdVarShowAttributes();
-}
diff --git a/tools/lldb-mi/MICmdCmdVar.h b/tools/lldb-mi/MICmdCmdVar.h
deleted file mode 100644
index cdd036688ca3..000000000000
--- a/tools/lldb-mi/MICmdCmdVar.h
+++ /dev/null
@@ -1,348 +0,0 @@
-//===-- MICmdCmdVar.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: CMICmdCmdVarCreate interface.
-// CMICmdCmdVarUpdate interface.
-// CMICmdCmdVarDelete interface.
-// CMICmdCmdVarAssign interface.
-// CMICmdCmdVarSetFormat interface.
-// CMICmdCmdVarListChildren interface.
-// CMICmdCmdVarEvaluateExpression interface.
-// CMICmdCmdVarInfoPathExpression interface.
-// CMICmdCmdVarShowAttributes interface.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-// For an introduction to adding a new command see
-// CMICmdCmdSupportInfoMiCmdQuery
-// command class as an example.
-
-#pragma once
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugSessionInfoVarObj.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-
-// Declarations:
-class CMICmnLLDBDebugSessionInfoVarObj;
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-create".
-//--
-class CMICmdCmdVarCreate : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarCreate();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarCreate() override;
-
- // Methods:
-private:
- void CompleteSBValue(lldb::SBValue &vrwValue);
-
- // Attribute:
-private:
- CMIUtilString m_strVarName;
- MIuint m_nChildren;
- MIuint64 m_nThreadId;
- CMIUtilString m_strType;
- bool m_bValid; // True = Variable is valid, false = not valid
- CMIUtilString m_strExpression;
- CMIUtilString m_strValue;
- const CMIUtilString m_constStrArgName;
- const CMIUtilString m_constStrArgFrameAddr;
- const CMIUtilString m_constStrArgExpression;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-update".
-//--
-class CMICmdCmdVarUpdate : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarUpdate();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarUpdate() override;
-
- // Methods:
-private:
- bool ExamineSBValueForChange(lldb::SBValue &vrwValue, bool &vrwbChanged);
- void MIFormResponse(const CMIUtilString &vrStrVarName,
- const char *const vpValue,
- const CMIUtilString &vrStrScope);
-
- // Attribute:
-private:
- const CMIUtilString m_constStrArgPrintValues;
- const CMIUtilString m_constStrArgName;
- bool m_bValueChanged; // True = yes value changed, false = no change
- CMICmnMIValueList m_miValueList;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-delete".
-//--
-class CMICmdCmdVarDelete : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarDelete();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarDelete() override;
-
- // Attribute:
-private:
- const CMIUtilString m_constStrArgName;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-assign".
-//--
-class CMICmdCmdVarAssign : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarAssign();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarAssign() override;
-
- // Attributes:
-private:
- bool m_bOk; // True = success, false = failure
- CMIUtilString m_varObjName;
- const CMIUtilString m_constStrArgName;
- const CMIUtilString m_constStrArgExpression;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-set-format".
-//--
-class CMICmdCmdVarSetFormat : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarSetFormat();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarSetFormat() override;
-
- // Attributes:
-private:
- CMIUtilString m_varObjName;
- const CMIUtilString m_constStrArgName;
- const CMIUtilString m_constStrArgFormatSpec;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-list-children".
-//--
-class CMICmdCmdVarListChildren : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarListChildren();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarListChildren() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgPrintValues;
- const CMIUtilString m_constStrArgName;
- const CMIUtilString m_constStrArgFrom;
- const CMIUtilString m_constStrArgTo;
- bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
- MIuint m_nChildren;
- CMICmnMIValueList m_miValueList;
- bool m_bHasMore;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-evaluate-expression".
-//--
-class CMICmdCmdVarEvaluateExpression : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarEvaluateExpression();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarEvaluateExpression() override;
-
- // Attributes:
-private:
- bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
- CMIUtilString m_varObjName;
- const CMIUtilString m_constStrArgFormatSpec; // Not handled by *this command
- const CMIUtilString m_constStrArgName;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-info-path-expression".
-//--
-class CMICmdCmdVarInfoPathExpression : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarInfoPathExpression();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarInfoPathExpression() override;
-
- // Attributes:
-private:
- bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
- CMIUtilString m_strPathExpression;
- const CMIUtilString m_constStrArgName;
-};
-
-//++
-//============================================================================
-// Details: MI command class. MI commands derived from the command base class.
-// *this class implements MI command "var-show-attributes".
-//--
-class CMICmdCmdVarShowAttributes : public CMICmdBase {
- // Statics:
-public:
- // Required by the CMICmdFactory when registering *this command
- static CMICmdBase *CreateSelf();
-
- // Methods:
-public:
- /* ctor */ CMICmdCmdVarShowAttributes();
-
- // Overridden:
-public:
- // From CMICmdInvoker::ICmd
- bool Execute() override;
- bool Acknowledge() override;
- bool ParseArgs() override;
- // From CMICmnBase
- /* dtor */ ~CMICmdCmdVarShowAttributes() override;
-
- // Attributes:
-private:
- const CMIUtilString m_constStrArgName;
-};
diff --git a/tools/lldb-mi/MICmdCommands.cpp b/tools/lldb-mi/MICmdCommands.cpp
deleted file mode 100644
index cffc50a9ba6d..000000000000
--- a/tools/lldb-mi/MICmdCommands.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//===-- MICmdCommands.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: MI command are registered with the MI command factory.
-//
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-
-// In-house headers:
-#include "MICmdCommands.h"
-#include "MICmdCmd.h"
-#include "MICmdCmdBreak.h"
-#include "MICmdCmdData.h"
-#include "MICmdCmdEnviro.h"
-#include "MICmdCmdExec.h"
-#include "MICmdCmdFile.h"
-#include "MICmdCmdGdbInfo.h"
-#include "MICmdCmdGdbSet.h"
-#include "MICmdCmdGdbShow.h"
-#include "MICmdCmdGdbThread.h"
-#include "MICmdCmdMiscellanous.h"
-#include "MICmdCmdStack.h"
-#include "MICmdCmdSupportInfo.h"
-#include "MICmdCmdSupportList.h"
-#include "MICmdCmdSymbol.h"
-#include "MICmdCmdTarget.h"
-#include "MICmdCmdThread.h"
-#include "MICmdCmdTrace.h"
-#include "MICmdCmdVar.h"
-#include "MICmdFactory.h"
-
-namespace MICmnCommands {
-template <typename T> static bool Register();
-}
-
-//++
-// Details: Command to command factory registration function.
-// Type: Template function.
-// Args: typename T - A command type class.
-// Return: bool - True = yes command is registered, false = command failed to
-// register.
-// Throws: None.
-//--
-template <typename T> static bool MICmnCommands::Register() {
- static CMICmdFactory &rCmdFactory = CMICmdFactory::Instance();
- const CMIUtilString strMiCmd = T().GetMiCmd();
- CMICmdFactory::CmdCreatorFnPtr fn = T().GetCmdCreatorFn();
- return rCmdFactory.CmdRegister(strMiCmd, fn);
-}
-
-//++
-// Details: Register commands with MI command factory
-// Type: Function.
-// Args: None.
-// Return: bool - True = yes all commands are registered,
-// false = one or more commands failed to register.
-// Throws: None.
-//--
-bool MICmnCommands::RegisterAll() {
- bool bOk = MIstatus::success;
-
- bOk &= Register<CMICmdCmdSupportInfoMiCmdQuery>();
- bOk &= Register<CMICmdCmdBreakAfter>();
- bOk &= Register<CMICmdCmdBreakCondition>();
- bOk &= Register<CMICmdCmdBreakDelete>();
- bOk &= Register<CMICmdCmdBreakDisable>();
- bOk &= Register<CMICmdCmdBreakEnable>();
- bOk &= Register<CMICmdCmdBreakInsert>();
- bOk &= Register<CMICmdCmdDataDisassemble>();
- bOk &= Register<CMICmdCmdDataEvaluateExpression>();
- bOk &= Register<CMICmdCmdDataInfoLine>();
- bOk &= Register<CMICmdCmdDataReadMemoryBytes>();
- bOk &= Register<CMICmdCmdDataReadMemory>();
- bOk &= Register<CMICmdCmdDataListRegisterNames>();
- bOk &= Register<CMICmdCmdDataListRegisterValues>();
- bOk &= Register<CMICmdCmdDataWriteMemory>();
- bOk &= Register<CMICmdCmdEnablePrettyPrinting>();
- bOk &= Register<CMICmdCmdEnvironmentCd>();
- bOk &= Register<CMICmdCmdExecAbort>();
- bOk &= Register<CMICmdCmdExecArguments>();
- bOk &= Register<CMICmdCmdExecContinue>();
- bOk &= Register<CMICmdCmdExecInterrupt>();
- bOk &= Register<CMICmdCmdExecFinish>();
- bOk &= Register<CMICmdCmdExecNext>();
- bOk &= Register<CMICmdCmdExecNextInstruction>();
- bOk &= Register<CMICmdCmdExecRun>();
- bOk &= Register<CMICmdCmdExecStep>();
- bOk &= Register<CMICmdCmdExecStepInstruction>();
- bOk &= Register<CMICmdCmdFileExecAndSymbols>();
- bOk &= Register<CMICmdCmdGdbExit>();
- bOk &= Register<CMICmdCmdGdbInfo>();
- bOk &= Register<CMICmdCmdGdbSet>();
- bOk &= Register<CMICmdCmdGdbShow>();
- bOk &= Register<CMICmdCmdGdbThread>();
- bOk &= Register<CMICmdCmdInferiorTtySet>();
- bOk &= Register<CMICmdCmdInterpreterExec>();
- bOk &= Register<CMICmdCmdListThreadGroups>();
- bOk &= Register<CMICmdCmdSource>();
- bOk &= Register<CMICmdCmdStackInfoDepth>();
- bOk &= Register<CMICmdCmdStackInfoFrame>();
- bOk &= Register<CMICmdCmdStackListFrames>();
- bOk &= Register<CMICmdCmdStackListArguments>();
- bOk &= Register<CMICmdCmdStackListLocals>();
- bOk &= Register<CMICmdCmdStackListVariables>();
- bOk &= Register<CMICmdCmdStackSelectFrame>();
- bOk &= Register<CMICmdCmdSupportListFeatures>();
- bOk &= Register<CMICmdCmdSymbolListLines>();
- bOk &= Register<CMICmdCmdTargetSelect>();
- bOk &= Register<CMICmdCmdTargetAttach>();
- bOk &= Register<CMICmdCmdTargetDetach>();
- bOk &= Register<CMICmdCmdThreadInfo>();
- bOk &= Register<CMICmdCmdVarAssign>();
- bOk &= Register<CMICmdCmdVarCreate>();
- bOk &= Register<CMICmdCmdVarDelete>();
- bOk &= Register<CMICmdCmdVarEvaluateExpression>();
- bOk &= Register<CMICmdCmdVarInfoPathExpression>();
- bOk &= Register<CMICmdCmdVarListChildren>();
- bOk &= Register<CMICmdCmdVarSetFormat>();
- bOk &= Register<CMICmdCmdVarShowAttributes>();
- bOk &= Register<CMICmdCmdVarUpdate>();
-
- return bOk;
-}
diff --git a/tools/lldb-mi/MICmdCommands.h b/tools/lldb-mi/MICmdCommands.h
deleted file mode 100644
index f2e3bfde7603..000000000000
--- a/tools/lldb-mi/MICmdCommands.h
+++ /dev/null
@@ -1,19 +0,0 @@
-//===-- MICmdCommands.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-namespace MICmnCommands {
-
-//++
-//============================================================================
-// Details: MI Command are instantiated and registered automatically with the
-// Command Factory
-//--
-bool RegisterAll();
-}
diff --git a/tools/lldb-mi/MICmdData.cpp b/tools/lldb-mi/MICmdData.cpp
deleted file mode 100644
index 6d0b679b8571..000000000000
--- a/tools/lldb-mi/MICmdData.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-//===-- MICmdData.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdData.h"
diff --git a/tools/lldb-mi/MICmdData.h b/tools/lldb-mi/MICmdData.h
deleted file mode 100644
index 3e46b54d835d..000000000000
--- a/tools/lldb-mi/MICmdData.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//===-- MICmdData.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnResources.h"
-
-//++
-//============================================================================
-// Details: MI command metadata. Holds the command's name, MI number and options
-// as found on stdin. Holds the command's MI output (written to
-// stdout).
-//--
-struct SMICmdData {
- SMICmdData()
- : id(0), bCmdValid(false), bCmdExecutedSuccessfully(false),
- bMIOldStyle(false), bHasResultRecordExtra(false) {}
-
- MIuint id; // A command's unique ID i.e. GUID
- CMIUtilString strMiCmdToken; // The command's MI token (a number)
- CMIUtilString strMiCmd; // The command's name
- CMIUtilString strMiCmdOption; // The command's arguments or options
- CMIUtilString strMiCmdAll; // The text as received from the client
- CMIUtilString
- strMiCmdResultRecord; // Each command forms 1 response to its input
- CMIUtilString strMiCmdResultRecordExtra; // Hack command produce more response
- // text to help the client because of
- // using LLDB
- bool bCmdValid; // True = Valid MI format command, false = invalid
- bool bCmdExecutedSuccessfully; // True = Command finished successfully, false
- // = Did not start/did not complete
- CMIUtilString strErrorDescription; // Command failed this is why
- bool bMIOldStyle; // True = format "3thread", false = format "3-thread"
- bool bHasResultRecordExtra; // True = Yes command produced additional MI
- // output to its 1 line response, false = no extra
- // MI output formed
-
- void Clear() {
- id = 0;
- strMiCmdToken.clear();
- strMiCmd = MIRSRC(IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION);
- strMiCmdOption.clear();
- strMiCmdAll.clear();
- strMiCmdResultRecord.clear();
- strMiCmdResultRecordExtra.clear();
- bCmdValid = false;
- bCmdExecutedSuccessfully = false;
- strErrorDescription.clear();
- bMIOldStyle = false;
- bHasResultRecordExtra = false;
- }
-};
diff --git a/tools/lldb-mi/MICmdFactory.cpp b/tools/lldb-mi/MICmdFactory.cpp
deleted file mode 100644
index 30995835c688..000000000000
--- a/tools/lldb-mi/MICmdFactory.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-//===-- MICmdFactory.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdFactory.h"
-#include "MICmdBase.h"
-#include "MICmdCommands.h"
-#include "MICmdData.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMICmdFactory constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdFactory::CMICmdFactory() {}
-
-//++
-// Details: CMICmdFactory destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdFactory::~CMICmdFactory() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Command factory.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdFactory::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = true;
-
- MICmnCommands::RegisterAll();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Command Factory.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdFactory::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_mapMiCmdToCmdCreatorFn.clear();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Register a command's creator function with the command identifier
-// the MI
-// command name i.e. 'file-exec-and-symbols'.
-// Type: Method.
-// Args: vMiCmd - (R) Command's name, the MI command.
-// vCmdCreateFn - (R) Command's creator function pointer.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdFactory::CmdRegister(const CMIUtilString &vMiCmd,
- CmdCreatorFnPtr vCmdCreateFn) {
- if (!IsValid(vMiCmd)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_NAME), vMiCmd.c_str()));
- return MIstatus::failure;
- }
- if (vCmdCreateFn == nullptr) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_CR8FN), vMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- if (HaveAlready(vMiCmd)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED), vMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- MapPairMiCmdToCmdCreatorFn_t pr(vMiCmd, vCmdCreateFn);
- m_mapMiCmdToCmdCreatorFn.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Check a command is already registered.
-// Type: Method.
-// Args: vMiCmd - (R) Command's name, the MI command.
-// Return: True - registered.
-// False - not found.
-// Throws: None.
-//--
-bool CMICmdFactory::HaveAlready(const CMIUtilString &vMiCmd) const {
- const MapMiCmdToCmdCreatorFn_t::const_iterator it =
- m_mapMiCmdToCmdCreatorFn.find(vMiCmd);
- return it != m_mapMiCmdToCmdCreatorFn.end();
-}
-
-//++
-// Details: Check a command's name is valid:
-// - name is not empty
-// - name does not have spaces
-// Type: Method.
-// Args: vMiCmd - (R) Command's name, the MI command.
-// Return: True - valid.
-// False - not valid.
-// Throws: None.
-//--
-bool CMICmdFactory::IsValid(const CMIUtilString &vMiCmd) const {
- bool bValid = true;
-
- if (vMiCmd.empty()) {
- bValid = false;
- return false;
- }
-
- const size_t nPos = vMiCmd.find(' ');
- if (nPos != std::string::npos)
- bValid = false;
-
- return bValid;
-}
-
-//++
-// Details: Check a command is already registered.
-// Type: Method.
-// Args: vMiCmd - (R) Command's name, the MI command.
-// Return: True - registered.
-// False - not found.
-// Throws: None.
-//--
-bool CMICmdFactory::CmdExist(const CMIUtilString &vMiCmd) const {
- return HaveAlready(vMiCmd);
-}
-
-//++
-// Details: Create a command given the specified MI command name. The command
-// data object
-// contains the options for the command.
-// Type: Method.
-// Args: vMiCmd - (R) Command's name, the MI command.
-// vCmdData - (RW) Command's metadata status/information/result
-// object.
-// vpNewCmd - (W) New command instance.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdFactory::CmdCreate(const CMIUtilString &vMiCmd,
- const SMICmdData &vCmdData,
- CMICmdBase *&vpNewCmd) {
- vpNewCmd = nullptr;
-
- if (!IsValid(vMiCmd)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_NAME), vMiCmd.c_str()));
- return MIstatus::failure;
- }
- if (!HaveAlready(vMiCmd)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMDFACTORY_ERR_CMD_NOT_REGISTERED), vMiCmd.c_str()));
- return MIstatus::failure;
- }
-
- const MapMiCmdToCmdCreatorFn_t::const_iterator it =
- m_mapMiCmdToCmdCreatorFn.find(vMiCmd);
- const CMIUtilString &rMiCmd((*it).first);
- MIunused(rMiCmd);
- CmdCreatorFnPtr pFn = (*it).second;
- CMICmdBase *pCmd = (*pFn)();
-
- SMICmdData cmdData(vCmdData);
- cmdData.id = pCmd->GetGUID();
- pCmd->SetCmdData(cmdData);
- vpNewCmd = pCmd;
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmdFactory.h b/tools/lldb-mi/MICmdFactory.h
deleted file mode 100644
index 19987c281ad0..000000000000
--- a/tools/lldb-mi/MICmdFactory.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- MICmdFactory.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <map>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-
-// Declarations:
-class CMICmdBase;
-struct SMICmdData;
-
-//++
-//============================================================================
-// Details: MI Command Factory. Holds a list of registered MI commands that
-// MI application understands to interpret. Creates commands objects.
-// The Command Factory is carried out in the main thread.
-// A singleton class.
-//--
-class CMICmdFactory : public CMICmnBase, public MI::ISingleton<CMICmdFactory> {
- friend class MI::ISingleton<CMICmdFactory>;
-
- // Typedefs:
-public:
- typedef CMICmdBase *(*CmdCreatorFnPtr)();
-
- // Class:
-public:
- //++
- // Description: Command's factory's interface for commands to implement.
- //--
- class ICmd {
- public:
- virtual const CMIUtilString &GetMiCmd() const = 0;
- virtual CmdCreatorFnPtr GetCmdCreatorFn() const = 0;
- // virtual CMICmdBase * CreateSelf( void ) = 0; // Not
- // possible as require a static creator
- // function in the command class, here for awareness
-
- /* dtor */ virtual ~ICmd() {}
- };
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- bool CmdRegister(const CMIUtilString &vMiCmd, CmdCreatorFnPtr vCmdCreateFn);
- bool CmdCreate(const CMIUtilString &vMiCmd, const SMICmdData &vCmdData,
- CMICmdBase *&vpNewCmd);
- bool CmdExist(const CMIUtilString &vMiCmd) const;
-
- // Methods:
-private:
- /* ctor */ CMICmdFactory();
- /* ctor */ CMICmdFactory(const CMICmdFactory &);
- void operator=(const CMICmdFactory &);
-
- bool HaveAlready(const CMIUtilString &vMiCmd) const;
- bool IsValid(const CMIUtilString &vMiCmd) const;
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmdFactory() override;
-
- // Typedefs:
-private:
- typedef std::map<CMIUtilString, CmdCreatorFnPtr> MapMiCmdToCmdCreatorFn_t;
- typedef std::pair<CMIUtilString, CmdCreatorFnPtr>
- MapPairMiCmdToCmdCreatorFn_t;
-
- // Attributes:
-private:
- MapMiCmdToCmdCreatorFn_t m_mapMiCmdToCmdCreatorFn;
-};
diff --git a/tools/lldb-mi/MICmdInterpreter.cpp b/tools/lldb-mi/MICmdInterpreter.cpp
deleted file mode 100644
index 9e37ac2d6108..000000000000
--- a/tools/lldb-mi/MICmdInterpreter.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-//===-- MICmdInterpreter.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdInterpreter.h"
-#include "MICmdFactory.h"
-
-//++
-// Details: CMICmdInterpreter constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdInterpreter::CMICmdInterpreter()
- : m_rCmdFactory(CMICmdFactory::Instance()) {}
-
-//++
-// Details: CMICmdInterpreter destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdInterpreter::~CMICmdInterpreter() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Command Interpreter.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdInterpreter::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = true;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Command Interpreter.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdInterpreter::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Establish whether the text data is an MI format type command.
-// Type: Method.
-// Args: vTextLine - (R) Text data to interpret.
-// vwbYesValid - (W) True = MI type command, false = not
-// recognised.
-// vwbCmdNotInCmdFactor - (W) True = MI command not found in the
-// command factory, false = recognised.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdInterpreter::ValidateIsMi(const CMIUtilString &vTextLine,
- bool &vwbYesValid,
- bool &vwbCmdNotInCmdFactor,
- SMICmdData &rwCmdData) {
- vwbYesValid = false;
- vwbCmdNotInCmdFactor = false;
- rwCmdData.Clear();
-
- if (vTextLine.empty())
- return MIstatus::success;
-
- // MI format is [cmd #]-[command name]<space>[command arg(s)]
- // i.e. 1-file-exec-and-symbols --thread-group i1 DEVICE_EXECUTABLE
- // 5-data-evaluate-expression --thread 1 --frame 0 *(argv)
-
- m_miCmdData.Clear();
- m_miCmdData.strMiCmd = vTextLine;
-
- // The following change m_miCmdData as valid parts are identified
- vwbYesValid = (MiHasCmdTokenEndingHyphen(vTextLine) ||
- MiHasCmdTokenEndingAlpha(vTextLine));
- vwbYesValid = vwbYesValid && MiHasCmd(vTextLine);
- if (vwbYesValid) {
- vwbCmdNotInCmdFactor = !HasCmdFactoryGotMiCmd(MiGetCmdData());
- vwbYesValid = !vwbCmdNotInCmdFactor;
- }
-
- // Update command's meta data valid state
- m_miCmdData.bCmdValid = vwbYesValid;
-
- // Ok to return new updated command information
- rwCmdData = MiGetCmdData();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Establish whether the command name entered on the stdin stream is
-// recognised by
-// the MI driver.
-// Type: Method.
-// Args: vCmd - (R) Command information structure.
-// Return: bool - True = yes command is recognised, false = command not
-// recognised.
-// Throws: None.
-//--
-bool CMICmdInterpreter::HasCmdFactoryGotMiCmd(const SMICmdData &vCmd) const {
- return m_rCmdFactory.CmdExist(vCmd.strMiCmd);
-}
-
-//++
-// Details: Does the command entered match the criteria for a MI command format.
-// The format to validate against is 'nn-' where there can be 1 to n
-// digits.
-// I.e. '2-gdb-exit'.
-// Is the execution token present? The command token is entered into
-// the
-// command meta data structure whether correct or not for reporting or
-// later
-// command execution purposes.
-// Type: Method.
-// Args: vTextLine - (R) Text data to interpret.
-// Return: bool - True = yes command token present, false = command not
-// recognised.
-// Throws: None.
-//--
-bool CMICmdInterpreter::MiHasCmdTokenEndingHyphen(
- const CMIUtilString &vTextLine) {
- // The hyphen is mandatory
- const size_t nPos = vTextLine.find('-', 0);
- if ((nPos == std::string::npos))
- return false;
-
- if (MiHasCmdTokenPresent(vTextLine)) {
- const std::string strNum = vTextLine.substr(0, nPos);
- if (!CMIUtilString(strNum).IsNumber())
- return false;
-
- m_miCmdData.strMiCmdToken = strNum;
- }
-
- m_miCmdData.bMIOldStyle = false;
-
- return true;
-}
-
-//++
-// Details: Does the command entered match the criteria for a MI command format.
-// The format to validate against is 'nnA' where there can be 1 to n
-// digits.
-// 'A' represents any non numeric token. I.e. '1source .gdbinit'.
-// Is the execution token present? The command token is entered into
-// the
-// command meta data structure whether correct or not for reporting or
-// later
-// command execution purposes.
-// Type: Method.
-// Args: vTextLine - (R) Text data to interpret.
-// Return: bool - True = yes command token present, false = command not
-// recognised.
-// Throws: None.
-//--
-bool CMICmdInterpreter::MiHasCmdTokenEndingAlpha(
- const CMIUtilString &vTextLine) {
- char cChar = vTextLine[0];
- MIuint i = 0;
- while (::isdigit(cChar) != 0) {
- cChar = vTextLine[++i];
- }
- if (::isalpha(cChar) == 0)
- return false;
- if (i == 0)
- return false;
-
- const std::string strNum = vTextLine.substr(0, i);
- m_miCmdData.strMiCmdToken = strNum.c_str();
- m_miCmdData.bMIOldStyle = true;
-
- return true;
-}
-
-//++
-// Details: Does the command entered match the criteria for a MI command format.
-// Is the command token present before the hyphen?
-// Type: Method.
-// Args: vTextLine - (R) Text data to interpret.
-// Return: bool - True = yes command token present, false = token not present.
-// Throws: None.
-//--
-bool CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine) {
- const size_t nPos = vTextLine.find('-', 0);
- return (nPos > 0);
-}
-
-//++
-// Details: Does the command name entered match the criteria for a MI command
-// format.
-// Is a recognised command present? The command name is entered into
-// the
-// command meta data structure whether correct or not for reporting or
-// later
-// command execution purposes. Command options is present are also put
-// into the
-// command meta data structure.
-// Type: Method.
-// Args: vTextLine - (R) Command information structure.
-// Return: bool - True = yes command name present, false = command not
-// recognised.
-// Throws: None.
-//--
-bool CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine) {
- size_t nPos = 0;
- if (m_miCmdData.bMIOldStyle) {
- char cChar = vTextLine[0];
- size_t i = 0;
- while (::isdigit(cChar) != 0) {
- cChar = vTextLine[++i];
- }
- nPos = --i;
- } else {
- nPos = vTextLine.find('-', 0);
- }
-
- bool bFoundCmd = false;
- const size_t nLen = vTextLine.length();
- const size_t nPos2 = vTextLine.find(' ', nPos);
- if (nPos2 != std::string::npos) {
- if (nPos2 == nLen)
- return false;
- const CMIUtilString cmd =
- CMIUtilString(vTextLine.substr(nPos + 1, nPos2 - nPos - 1));
- if (cmd.empty())
- return false;
-
- m_miCmdData.strMiCmd = cmd;
-
- if (nPos2 < nLen)
- m_miCmdData.strMiCmdOption =
- CMIUtilString(vTextLine.substr(nPos2 + 1, nLen - nPos2 - 1));
-
- bFoundCmd = true;
- } else {
- const CMIUtilString cmd =
- CMIUtilString(vTextLine.substr(nPos + 1, nLen - nPos - 1));
- if (cmd.empty())
- return false;
- m_miCmdData.strMiCmd = cmd;
- bFoundCmd = true;
- }
-
- if (bFoundCmd)
- m_miCmdData.strMiCmdAll = vTextLine;
-
- return bFoundCmd;
-}
-
-//++
-// Details: Retrieve the just entered new command from stdin. It contains the
-// command
-// name, number and any options.
-// Type: Method.
-// Args: vTextLine - (R) Command information structure.
-// Return: SMICmdData & - Command meta data information/result/status.
-// Throws: None.
-//--
-const SMICmdData &CMICmdInterpreter::MiGetCmdData() const {
- return m_miCmdData;
-}
diff --git a/tools/lldb-mi/MICmdInterpreter.h b/tools/lldb-mi/MICmdInterpreter.h
deleted file mode 100644
index 100d309ac772..000000000000
--- a/tools/lldb-mi/MICmdInterpreter.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===-- MICmdInterpreter.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmdData.h"
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-
-// Declarations:
-class CMICmdFactory;
-
-//++
-//============================================================================
-// Details: MI command interpreter. It takes text data from the MI driver
-// (which got it from Stdin singleton) and validate the text to see if
-// matches Machine Interface (MI) format and commands defined in the
-// MI application.
-// A singleton class.
-//--
-class CMICmdInterpreter : public CMICmnBase,
- public MI::ISingleton<CMICmdInterpreter> {
- friend MI::ISingleton<CMICmdInterpreter>;
-
- // Methods:
-public:
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- bool ValidateIsMi(const CMIUtilString &vTextLine, bool &vwbYesValid,
- bool &vwbCmdNotInCmdFactor, SMICmdData &rwCmdData);
-
- // Methods:
-private:
- /* ctor */ CMICmdInterpreter();
- /* ctor */ CMICmdInterpreter(const CMICmdInterpreter &);
- void operator=(const CMICmdInterpreter &);
-
- bool HasCmdFactoryGotMiCmd(const SMICmdData &vCmdData) const;
- bool MiHasCmdTokenEndingHyphen(const CMIUtilString &vTextLine);
- bool MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine);
- bool MiHasCmd(const CMIUtilString &vTextLine);
- bool MiHasCmdTokenPresent(const CMIUtilString &vTextLine);
- const SMICmdData &MiGetCmdData() const;
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmdInterpreter() override;
-
- // Attributes:
-private:
- SMICmdData m_miCmdData; // Filled in on each new line being interpreted
- CMICmdFactory &m_rCmdFactory;
-};
diff --git a/tools/lldb-mi/MICmdInvoker.cpp b/tools/lldb-mi/MICmdInvoker.cpp
deleted file mode 100644
index f4150a20ccd9..000000000000
--- a/tools/lldb-mi/MICmdInvoker.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-//===-- MICmdInvoker.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdInvoker.h"
-#include "MICmdBase.h"
-#include "MICmdMgr.h"
-#include "MICmnLog.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriver.h"
-
-//++
-// Details: CMICmdInvoker constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdInvoker::CMICmdInvoker() : m_rStreamOut(CMICmnStreamStdout::Instance()) {}
-
-//++
-// Details: CMICmdInvoker destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdInvoker::~CMICmdInvoker() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Command Invoker.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdInvoker::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = true;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdInvoker::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- CmdDeleteAll();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Empty the map of invoked commands doing work. Command objects are
-// deleted too.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdInvoker::CmdDeleteAll() {
- CMICmdMgr &rMgr = CMICmdMgr::Instance();
- MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.begin();
- while (it != m_mapCmdIdToCmd.end()) {
- const MIuint cmdId((*it).first);
- MIunused(cmdId);
- CMICmdBase *pCmd = (*it).second;
- const CMIUtilString &rCmdName(pCmd->GetCmdData().strMiCmd);
- MIunused(rCmdName);
- rMgr.CmdDelete(pCmd->GetCmdData());
-
- // Next
- ++it;
- }
- m_mapCmdIdToCmd.clear();
-}
-
-//++
-// Details: Remove from the map of invoked commands doing work a command that
-// has finished
-// its work. The command object is deleted too.
-// Type: Method.
-// Args: vId - (R) Command object's unique ID.
-// vbYesDeleteCmd - (R) True = Delete command object, false = delete
-// via the Command Manager.
-// Return: None.
-// Throws: None.
-//--
-bool CMICmdInvoker::CmdDelete(const MIuint vId,
- const bool vbYesDeleteCmd /*= false*/) {
- CMICmdMgr &rMgr = CMICmdMgr::Instance();
- MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(vId);
- if (it != m_mapCmdIdToCmd.end()) {
- CMICmdBase *pCmd = (*it).second;
- if (vbYesDeleteCmd) {
- // Via registered interest command manager callback *this object to delete
- // the command
- m_mapCmdIdToCmd.erase(it);
- delete pCmd;
- } else
- // Notify other interested object of this command's pending deletion
- rMgr.CmdDelete(pCmd->GetCmdData());
- }
-
- if (m_mapCmdIdToCmd.empty())
- rMgr.CmdUnregisterForDeleteNotification(*this);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Add to the map of invoked commands doing work a command that is
-// about to
-// start to do work.
-// Type: Method.
-// Args: vCmd - (R) Command object.
-// Return: None.
-// Throws: None.
-//--
-bool CMICmdInvoker::CmdAdd(const CMICmdBase &vCmd) {
- if (m_mapCmdIdToCmd.empty()) {
- CMICmdMgr &rMgr = CMICmdMgr::Instance();
- rMgr.CmdRegisterForDeleteNotification(*this);
- }
-
- const MIuint &cmdId(vCmd.GetCmdData().id);
- MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(cmdId);
- if (it != m_mapCmdIdToCmd.end())
- return MIstatus::success;
-
- MapPairCmdIdToCmd_t pr(cmdId, const_cast<CMICmdBase *>(&vCmd));
- m_mapCmdIdToCmd.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Having previously had the potential command validated and found
-// valid now
-// get the command executed.
-// If the Functionality returns MIstatus::failure call
-// GetErrorDescription().
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vCmd - (RW) Command object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdInvoker::CmdExecute(CMICmdBase &vCmd) {
- bool bOk = CmdAdd(vCmd);
-
- if (bOk) {
- vCmd.AddCommonArgs();
- if (!vCmd.ParseArgs()) {
- // Report command execution failed
- const SMICmdData cmdData(vCmd.GetCmdData());
- CmdStdout(cmdData);
- CmdCauseAppExit(vCmd);
- CmdDelete(cmdData.id);
-
- // Proceed to wait or execute next command
- return MIstatus::success;
- }
- }
-
- if (bOk && !vCmd.Execute()) {
- // Report command execution failed
- const SMICmdData cmdData(vCmd.GetCmdData());
- CmdStdout(cmdData);
- CmdCauseAppExit(vCmd);
- CmdDelete(cmdData.id);
-
- // Proceed to wait or execute next command
- return MIstatus::success;
- }
-
- bOk = CmdExecuteFinished(vCmd);
-
- return bOk;
-}
-
-//++
-// Details: Called when a command has finished its Execution() work either
-// synchronously
-// because the command executed was the type a non event type or
-// asynchronously
-// via the command's callback (because of an SB Listener event). Needs
-// to be called
-// so that *this invoker call do some house keeping and then proceed to
-// call
-// the command's Acknowledge() function.
-// Type: Method.
-// Args: vCmd - (R) Command object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdInvoker::CmdExecuteFinished(CMICmdBase &vCmd) {
- // Command finished now get the command to gather it's information and form
- // the MI
- // Result record
- if (!vCmd.Acknowledge()) {
- // Report command acknowledge functionality failed
- const SMICmdData cmdData(vCmd.GetCmdData());
- CmdStdout(cmdData);
- CmdCauseAppExit(vCmd);
- CmdDelete(cmdData.id);
-
- // Proceed to wait or execute next command
- return MIstatus::success;
- }
-
- // Retrieve the command's latest data/information. Needed for commands of the
- // event type so have
- // a record of commands pending finishing execution.
- const CMIUtilString &rMIResultRecord(vCmd.GetMIResultRecord());
- SMICmdData cmdData(
- vCmd.GetCmdData()); // Make a copy as the command will be deleted soon
- cmdData.strMiCmdResultRecord = rMIResultRecord; // Precautionary copy as the
- // command might forget to do
- // this
- if (vCmd.HasMIResultRecordExtra()) {
- cmdData.bHasResultRecordExtra = true;
- const CMIUtilString &rMIExtra(vCmd.GetMIResultRecordExtra());
- cmdData.strMiCmdResultRecordExtra =
- rMIExtra; // Precautionary copy as the command might forget to do this
- }
-
- // Send command's MI response to the client
- bool bOk = CmdStdout(cmdData);
-
- // Delete the command object as do not require anymore
- bOk = bOk && CmdDelete(vCmd.GetCmdData().id);
-
- return bOk;
-}
-
-//++
-// Details: If the MI Driver is not operating via a client i.e. Eclipse check
-// the command
-// on failure suggests the application exits. A command can be such
-// that a
-// failure cannot the allow the application to continue operating.
-// Args: vCmd - (R) Command object.
-// Return: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdInvoker::CmdCauseAppExit(const CMICmdBase &vCmd) const {
- if (vCmd.GetExitAppOnCommandFailure()) {
- CMIDriver &rDriver(CMIDriver::Instance());
- if (rDriver.IsDriverDebuggingArgExecutable()) {
- rDriver.SetExitApplicationFlag(true);
- }
- }
-}
-
-//++
-// Details: Write to stdout and the Log file the command's MI formatted result.
-// Type: vCmdData - (R) A command's information.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Return: None.
-// Throws: None.
-//--
-bool CMICmdInvoker::CmdStdout(const SMICmdData &vCmdData) const {
- bool bOk = m_pLog->WriteLog(vCmdData.strMiCmdAll);
- const bool bLock = bOk && m_rStreamOut.Lock();
- bOk = bOk && bLock &&
- m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecord);
- if (bOk && vCmdData.bHasResultRecordExtra) {
- bOk = m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecordExtra);
- }
- bOk = bLock && m_rStreamOut.Unlock();
-
- return bOk;
-}
-
-//++
-// Details: Required by the CMICmdMgr::ICmdDeleteCallback. *this object is
-// registered
-// with the Command Manager to receive callbacks when a command is
-// being deleted.
-// An object, *this invoker, does not delete a command object itself
-// but calls
-// the Command Manager to delete a command object. This function is the
-// Invoker's
-// called.
-// The Invoker owns the command objects and so can delete them but must
-// do it
-// via the manager so other objects can be notified of the deletion.
-// Type: Method.
-// Args: vCmd - (RW) Command.
-// Return: None.
-// Throws: None.
-//--
-void CMICmdInvoker::Delete(SMICmdData &vCmd) { CmdDelete(vCmd.id, true); }
diff --git a/tools/lldb-mi/MICmdInvoker.h b/tools/lldb-mi/MICmdInvoker.h
deleted file mode 100644
index 5db8d36ad26e..000000000000
--- a/tools/lldb-mi/MICmdInvoker.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- MICmdInvoker.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <map>
-
-// In-house headers:
-#include "MICmdData.h"
-#include "MICmdMgrSetCmdDeleteCallback.h"
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-
-// Declarations:
-class CMICmdBase;
-class CMICmnStreamStdout;
-
-//++
-//============================================================================
-// Details: MI Command Invoker. The Invoker works on the command pattern design.
-// There two main jobs; action command Execute() function, followed by
-// the command's Acknowledge() function. When a command has finished
-// its
-// execute function it returns to the invoker. The invoker then calls
-// the
-// command's Acknowledge() function to do more work, form and give
-// back a MI result. In the meantime the Command Monitor is monitoring
-// the each command doing their Execute() function work so they do not
-// exceed a time limit which if it exceeds informs the command(s) to
-// stop work.
-// The work by the Invoker is carried out in the main thread.
-// The Invoker takes ownership of any commands created which means it
-// is the only object to delete them when a command is finished
-// working.
-// A singleton class.
-//--
-class CMICmdInvoker : public CMICmnBase,
- public CMICmdMgrSetCmdDeleteCallback::ICallback,
- public MI::ISingleton<CMICmdInvoker> {
- friend class MI::ISingleton<CMICmdInvoker>;
-
- // Class:
-public:
- //++
- // Description: Invoker's interface for commands to implement.
- //--
- class ICmd {
- public:
- virtual bool Acknowledge() = 0;
- virtual bool Execute() = 0;
- virtual bool ParseArgs() = 0;
- virtual void SetCmdData(const SMICmdData &vCmdData) = 0;
- virtual const SMICmdData &GetCmdData() const = 0;
- virtual const CMIUtilString &GetErrorDescription() const = 0;
- virtual void CmdFinishedTellInvoker() const = 0;
- virtual const CMIUtilString &GetMIResultRecord() const = 0;
- virtual const CMIUtilString &GetMIResultRecordExtra() const = 0;
- virtual bool HasMIResultRecordExtra() const = 0;
-
- /* dtor */ virtual ~ICmd() {}
- };
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- bool CmdExecute(CMICmdBase &vCmd);
- bool CmdExecuteFinished(CMICmdBase &vCmd);
-
- // Typedefs:
-private:
- typedef std::map<MIuint, CMICmdBase *> MapCmdIdToCmd_t;
- typedef std::pair<MIuint, CMICmdBase *> MapPairCmdIdToCmd_t;
-
- // Methods:
-private:
- /* ctor */ CMICmdInvoker();
- /* ctor */ CMICmdInvoker(const CMICmdInvoker &);
- void operator=(const CMICmdInvoker &);
- void CmdDeleteAll();
- bool CmdDelete(const MIuint vCmdId, const bool vbYesDeleteCmd = false);
- bool CmdAdd(const CMICmdBase &vCmd);
- bool CmdStdout(const SMICmdData &vCmdData) const;
- void CmdCauseAppExit(const CMICmdBase &vCmd) const;
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmdInvoker() override;
- // From CMICmdMgrSetCmdDeleteCallback::ICallback
- void Delete(SMICmdData &vCmd) override;
-
- // Attributes:
-private:
- MapCmdIdToCmd_t m_mapCmdIdToCmd;
- CMICmnStreamStdout &m_rStreamOut;
-};
diff --git a/tools/lldb-mi/MICmdMgr.cpp b/tools/lldb-mi/MICmdMgr.cpp
deleted file mode 100644
index 453ffedbd33d..000000000000
--- a/tools/lldb-mi/MICmdMgr.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-//===-- MICmdMgr.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdMgr.h"
-#include "MICmdBase.h"
-#include "MICmdFactory.h"
-#include "MICmdInterpreter.h"
-#include "MICmdInvoker.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilSingletonHelper.h"
-
-//++
-// Details: CMICmdMgr constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdMgr::CMICmdMgr()
- : m_interpretor(CMICmdInterpreter::Instance()),
- m_factory(CMICmdFactory::Instance()),
- m_invoker(CMICmdInvoker::Instance()) {}
-
-//++
-// Details: CMICmdMgr destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmdMgr::~CMICmdMgr() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Command Manager.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdMgr::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialization order is important here as some resources depend on
- // previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- if (bOk && !m_interpretor.Initialize()) {
- bOk = false;
- errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDINTERPRETER),
- m_interpretor.GetErrorDescription().c_str());
- }
- if (bOk && !m_factory.Initialize()) {
- bOk = false;
- errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDFACTORY),
- m_factory.GetErrorDescription().c_str());
- }
- if (bOk && !m_invoker.Initialize()) {
- bOk = false;
- errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDINVOKER),
- m_invoker.GetErrorDescription().c_str());
- }
- m_bInitialized = bOk;
-
- if (!bOk) {
- CMIUtilString strInitError(
- CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_CMDMGR), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Command Manager.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdMgr::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Tidy up
- m_setCmdDeleteCallback.clear();
-
- // Note shutdown order is important here
- if (!m_invoker.Shutdown()) {
- bOk = false;
- errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINVOKER),
- m_invoker.GetErrorDescription().c_str());
- }
- if (!m_factory.Shutdown()) {
- bOk = false;
- if (!errMsg.empty())
- errMsg += ", ";
- errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDFACTORY),
- m_factory.GetErrorDescription().c_str());
- }
- if (!m_interpretor.Shutdown()) {
- bOk = false;
- if (!errMsg.empty())
- errMsg += ", ";
- errMsg +=
- CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINTERPRETER),
- m_interpretor.GetErrorDescription().c_str());
- }
- MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Establish whether the text data is an MI format type command.
-// Type: Method.
-// Args: vTextLine - (R) Text data to interpret.
-// vwbYesValid - (W) True = MI type command, false = not
-// recognised.
-// vwbCmdNotInCmdFactor - (W) True = MI command not found in the
-// command factor, false = recognised.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdMgr::CmdInterpret(const CMIUtilString &vTextLine, bool &vwbYesValid,
- bool &vwbCmdNotInCmdFactor,
- SMICmdData &rwCmdData) {
- return m_interpretor.ValidateIsMi(vTextLine, vwbYesValid,
- vwbCmdNotInCmdFactor, rwCmdData);
-}
-
-//++
-// Details: Having previously had the potential command validated and found
-// valid now
-// get the command executed.
-// If the Functionality returns MIstatus::failure call
-// GetErrorDescription().
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vCmdData - (RW) Command meta data.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmdMgr::CmdExecute(const SMICmdData &vCmdData) {
- bool bOk = MIstatus::success;
-
- // Pass the command's meta data structure to the command
- // so it can update it if required. (Need to copy it out of the
- // command before the command is deleted)
- CMICmdBase *pCmd = nullptr;
- bOk = m_factory.CmdCreate(vCmdData.strMiCmd, vCmdData, pCmd);
- if (!bOk) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_FAILED_CREATE),
- m_factory.GetErrorDescription().c_str()));
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- bOk = m_invoker.CmdExecute(*pCmd);
- if (!bOk) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_INVOKER),
- m_invoker.GetErrorDescription().c_str()));
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- return bOk;
-}
-
-//++
-// Details: Iterate all interested clients and tell them a command is being
-// deleted.
-// Type: Method.
-// Args: vCmdData - (RW) The command to be deleted.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdMgr::CmdDelete(SMICmdData vCmdData) {
- // Note vCmdData is a copy! The command holding its copy will be deleted soon
- // we still need to iterate callback clients after a command object is deleted
-
- m_setCmdDeleteCallback.Delete(vCmdData);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Register an object to be called when a command object is deleted.
-// Type: Method.
-// Args: vObject - (R) A new interested client.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdMgr::CmdRegisterForDeleteNotification(
- CMICmdMgrSetCmdDeleteCallback::ICallback &vObject) {
- return m_setCmdDeleteCallback.Register(vObject);
-}
-
-//++
-// Details: Unregister an object from being called when a command object is
-// deleted.
-// Type: Method.
-// Args: vObject - (R) The was interested client.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmdMgr::CmdUnregisterForDeleteNotification(
- CMICmdMgrSetCmdDeleteCallback::ICallback &vObject) {
- return m_setCmdDeleteCallback.Unregister(vObject);
-}
diff --git a/tools/lldb-mi/MICmdMgr.h b/tools/lldb-mi/MICmdMgr.h
deleted file mode 100644
index 307ef897c58d..000000000000
--- a/tools/lldb-mi/MICmdMgr.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MICmdMgr.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <set>
-
-// In-house headers:
-#include "MICmdBase.h"
-#include "MICmdMgrSetCmdDeleteCallback.h"
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-
-// Declarations:
-class CMICmdInterpreter;
-class CMICmdFactory;
-class CMICmdInvoker;
-class CMICmdBase;
-
-//++
-//============================================================================
-// Details: MI command manager. Oversees command operations, controls command
-// production and the running of commands.
-// Command Invoker, Command Factory and Command Monitor while
-// independent
-// units are overseen/managed by *this manager.
-// A singleton class.
-//--
-class CMICmdMgr : public CMICmnBase, public MI::ISingleton<CMICmdMgr> {
- friend class MI::ISingleton<CMICmdMgr>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
-
- bool CmdInterpret(const CMIUtilString &vTextLine, bool &vwbYesValid,
- bool &vwbCmdNotInCmdFactor, SMICmdData &rwCmdData);
- bool CmdExecute(const SMICmdData &vCmdData);
- bool CmdDelete(SMICmdData vCmdData);
- bool CmdRegisterForDeleteNotification(
- CMICmdMgrSetCmdDeleteCallback::ICallback &vObject);
- bool CmdUnregisterForDeleteNotification(
- CMICmdMgrSetCmdDeleteCallback::ICallback &vObject);
-
- // Methods:
-private:
- /* ctor */ CMICmdMgr();
- /* ctor */ CMICmdMgr(const CMICmdMgr &);
- void operator=(const CMICmdMgr &);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmdMgr() override;
-
- // Attributes:
-private:
- CMICmdInterpreter &m_interpretor;
- CMICmdFactory &m_factory;
- CMICmdInvoker &m_invoker;
- CMICmdMgrSetCmdDeleteCallback::CSetClients m_setCmdDeleteCallback;
-};
diff --git a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp
deleted file mode 100644
index d6146b8d276d..000000000000
--- a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- MICmdMgrSetCmdDeleteCallback.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmdMgrSetCmdDeleteCallback.h"
-
-namespace CMICmdMgrSetCmdDeleteCallback {
-
-//++
-// Details: CSetClients constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CSetClients::CSetClients() : m_bClientUnregistered(false) {}
-
-//++
-// Details: CSetClients destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CSetClients::~CSetClients() {}
-
-//++
-// Details: Register an object to be called when a command object is deleted.
-// Type: Method.
-// Args: vObject - (R) A new interested client.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CSetClients::Register(ICallback &vObject) {
- insert(&vObject);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Unregister an object from being called when a command object is
-// deleted.
-// Type: Method.
-// Args: vObject - (R) The was interested client.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CSetClients::Unregister(ICallback &vObject) {
- m_bClientUnregistered = true;
- erase(&vObject);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Iterate all interested clients and tell them a command is being
-// deleted.
-// Type: Method.
-// Args: vCmd - (RW) The command to be deleted.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void CSetClients::Delete(SMICmdData &vCmd) {
- m_bClientUnregistered = false; // Reset
- iterator it = begin();
- while (it != end()) {
- ICallback *pObj = *it;
- pObj->Delete(vCmd);
-
- if (m_bClientUnregistered) {
- m_bClientUnregistered = false; // Reset
- it = begin();
- } else
- // Next
- ++it;
- }
-}
-
-} // namespace CMICmdMgrSetCmdDeleteCallback
diff --git a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h
deleted file mode 100644
index 30df5e9cd424..000000000000
--- a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- MICmdMgrSetCmdDeleteCallback.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
-//
-//===----------------------------------------------------------------------===//
-//--
-
-#pragma once
-
-// Third party headers:
-#include <set>
-
-// In-house headers:
-#include "MICmnBase.h"
-
-// Declarations:
-struct SMICmdData;
-
-namespace CMICmdMgrSetCmdDeleteCallback {
-
-//++
-//============================================================================
-// Details: MI Command Manager interface for client call back.
-// Objects that want to be notified of a command being deleted
-// inherit this interface and register interest in command object
-// deletion. An object deleting a command must not do it itself but
-// call
-// the Command Manager CmdDelete() function to delete a command object.
-//--
-class ICallback {
-public:
- virtual void Delete(SMICmdData &vCmd) = 0;
-
- /* dtor */ virtual ~ICallback() {}
-};
-
-//++
-//============================================================================
-// Details: MI Command Manager container for clients registered interest in
-// command
-// objects being deleted. Objects register an interest so when a
-// command
-// is to be deleted that object wanting the delete calls the Command
-// Manager to delete the command object. In so do all other registered
-// objects get called to about the deletion including the object
-// wanting
-// to do the delete in the first place.
-//--
-class CSetClients : public std::set<class ICallback *>, public CMICmnBase {
- // Methods:
-public:
- /* ctor */ CSetClients();
-
- bool Register(class ICallback &vObject);
- bool Unregister(class ICallback &vObject);
- void Delete(SMICmdData &vCmdData);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CSetClients() override;
-
- // Attributes:
-private:
- bool m_bClientUnregistered; // True = yes while deleting a client
- // unregistered, false = no client unregistered
- // during deletion
-};
-
-} // namespace CMICmdMgrSetCmdDeleteCallback
diff --git a/tools/lldb-mi/MICmnBase.cpp b/tools/lldb-mi/MICmnBase.cpp
deleted file mode 100644
index 9d87064aa64c..000000000000
--- a/tools/lldb-mi/MICmnBase.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-//===-- MICmnBase.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers
-#include <stdarg.h>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnLog.h"
-#include "MICmnStreamStderr.h"
-
-//++
-// Details: CMICmnBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnBase::CMICmnBase()
- : m_strMILastErrorDescription(CMIUtilString()), m_bInitialized(false),
- m_pLog(&CMICmnLog::Instance()), m_clientUsageRefCnt(0) {}
-
-//++
-// Details: CMICmnBase destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnBase::~CMICmnBase() { m_pLog = nullptr; }
-
-//++
-// Details: Retrieve whether *this object has an error description set.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes already defined, false = empty description.
-// Throws: None.
-//--
-bool CMICmnBase::HaveErrorDescription() const {
- return m_strMILastErrorDescription.empty();
-}
-
-//++
-// Details: Retrieve MI's last error condition.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnBase::GetErrorDescription() const {
- return m_strMILastErrorDescription;
-}
-
-//++
-// Details: Set MI's error condition description. This may be accessed by
-// clients and
-// seen by users. Message is available to the client using the server
-// and sent
-// to the Logger.
-// Type: Method.
-// Args: vrTxt - (R) Text description.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnBase::SetErrorDescription(const CMIUtilString &vrTxt) const {
- m_strMILastErrorDescription = vrTxt;
- if (!vrTxt.empty()) {
- const CMIUtilString txt(CMIUtilString::Format("Error: %s", vrTxt.c_str()));
- CMICmnStreamStderr::Instance().Write(txt);
- }
-}
-
-//++
-// Details: Set MI's error condition description. This may be accessed by
-// clients and
-// seen by users. Message is available to the client using the server
-// and sent
-// to the Logger.
-// Type: Method.
-// Args: vrTxt - (R) Text description.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnBase::SetErrorDescriptionNoLog(const CMIUtilString &vrTxt) const {
- m_strMILastErrorDescription = vrTxt;
-}
-
-//++
-// Details: Clear MI's error condition description.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnBase::ClrErrorDescription() const {
- m_strMILastErrorDescription.clear();
-}
-
-//++
-// Details: Set MI's error condition description. This may be accessed by
-// clients and
-// seen by users. Message is available to the client using the server
-// and sent
-// to the Logger.
-// Type: Method.
-// Args: vFormat - (R) Format string.
-// ... - (R) Variable number of CMIUtilString type objects.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnBase::SetErrorDescriptionn(const char *vFormat, ...) const {
- va_list args;
- va_start(args, vFormat);
- CMIUtilString strResult = CMIUtilString::FormatValist(vFormat, args);
- va_end(args);
-
- SetErrorDescription(strResult);
-}
diff --git a/tools/lldb-mi/MICmnBase.h b/tools/lldb-mi/MICmnBase.h
deleted file mode 100644
index 368e912b6d8a..000000000000
--- a/tools/lldb-mi/MICmnBase.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- MICmnBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MIDataTypes.h"
-#include "MIUtilString.h"
-
-// Declarations:
-class CMICmnLog;
-
-//++
-//============================================================================
-// Details: MI common code implementation base class.
-//--
-class CMICmnBase {
- // Methods:
-public:
- /* ctor */ CMICmnBase();
-
- bool HaveErrorDescription() const;
- const CMIUtilString &GetErrorDescription() const;
- void SetErrorDescription(const CMIUtilString &vrTxt) const;
- void SetErrorDescriptionn(const char *vFormat, ...) const;
- void SetErrorDescriptionNoLog(const CMIUtilString &vrTxt) const;
- void ClrErrorDescription() const;
-
- // Overrideable:
-public:
- /* dtor */ virtual ~CMICmnBase();
-
- // Attributes:
-protected:
- mutable CMIUtilString m_strMILastErrorDescription;
- bool m_bInitialized; // True = yes successfully initialized, false = no yet or
- // failed
- CMICmnLog *m_pLog; // Allow all derived classes to use the logger
- MIint m_clientUsageRefCnt; // Count of client using *this object so not
- // shutdown() object to early
-};
diff --git a/tools/lldb-mi/MICmnConfig.h b/tools/lldb-mi/MICmnConfig.h
deleted file mode 100644
index 9dd57922cecf..000000000000
--- a/tools/lldb-mi/MICmnConfig.h
+++ /dev/null
@@ -1,19 +0,0 @@
-//===-- MICmnConfig.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
-//
-//===----------------------------------------------------------------------===//
-//--
-#pragma once
-
-// 1 = Show debug process attach modal dialog, 0 = do not show
-// For windows only ATM, other OS's code is an infinite loop which a debugger
-// must change a value to continue
-#define MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG 0
-
-// 1 = Write to MI's Log file warnings about commands that did not handle
-// arguments or
-// options present to them by the driver's client, 0 = no warnings given
-#define MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED 1
diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp b/tools/lldb-mi/MICmnLLDBBroadcaster.cpp
deleted file mode 100644
index 554ec1f7e9fd..000000000000
--- a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- MICmnLLDBBroadcaster.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnLLDBBroadcaster.h"
-
-//++
-// Details: CMICmnLLDBBroadcaster constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBBroadcaster::CMICmnLLDBBroadcaster()
- : lldb::SBBroadcaster("MI driver") {}
-
-//++
-// Details: CMICmnLLDBBroadcaster destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBBroadcaster::~CMICmnLLDBBroadcaster() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this broadcaster object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBBroadcaster::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = MIstatus::success;
-
- return m_bInitialized;
-}
-
-//++
-// Details: Release resources for *this broadcaster object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBBroadcaster::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.h b/tools/lldb-mi/MICmnLLDBBroadcaster.h
deleted file mode 100644
index 326b6769fcb7..000000000000
--- a/tools/lldb-mi/MICmnLLDBBroadcaster.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- MICmnLLDBBroadcaster.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "lldb/API/SBBroadcaster.h"
-
-//++
-//============================================================================
-// Details: MI derived class from LLDB SBBroadcaster API.
-//
-// *** This class (files) is a place holder until we know we need it or
-// *** not
-//
-// A singleton class.
-//--
-class CMICmnLLDBBroadcaster : public CMICmnBase,
- public lldb::SBBroadcaster,
- public MI::ISingleton<CMICmnLLDBBroadcaster> {
- friend MI::ISingleton<CMICmnLLDBBroadcaster>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- // Methods:
-private:
- /* ctor */ CMICmnLLDBBroadcaster();
- /* ctor */ CMICmnLLDBBroadcaster(const CMICmnLLDBBroadcaster &);
- void operator=(const CMICmnLLDBBroadcaster &);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnLLDBBroadcaster() override;
-};
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
deleted file mode 100644
index 5ec2c588e201..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
+++ /dev/null
@@ -1,863 +0,0 @@
-//===-- MICmnLLDBDebugSessionInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBThread.h"
-#include <inttypes.h>
-#ifdef _WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif // _WIN32
-#include "lldb/API/SBBreakpointLocation.h"
-
-// In-house headers:
-#include "MICmdData.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLLDBUtilSBValue.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-#include "MICmnResources.h"
-#include "Platform.h"
-
-//++
-// Details: CMICmnLLDBDebugSessionInfo constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo()
- : m_nBrkPointCntMax(INT32_MAX),
- m_currentSelectedThread(LLDB_INVALID_THREAD_ID),
- m_constStrSharedDataKeyWkDir("Working Directory"),
- m_constStrSharedDataSolibPath("Solib Path"),
- m_constStrPrintCharArrayAsString("Print CharArrayAsString"),
- m_constStrPrintExpandAggregates("Print ExpandAggregates"),
- m_constStrPrintAggregateFieldNames("Print AggregateFieldNames") {}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfo destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_currentSelectedThread = LLDB_INVALID_THREAD_ID;
- CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero();
-
- m_bInitialized = MIstatus::success;
-
- return m_bInitialized;
-}
-
-//++
-// Details: Release resources for *this object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- // Tidy up
- SharedDataDestroy();
-
- m_vecActiveThreadId.clear();
- CMICmnLLDBDebugSessionInfoVarObj::VarObjClear();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Command instances can create and share data between other instances
-// of commands.
-// Data can also be assigned by a command and retrieved by LLDB event
-// handler.
-// This function takes down those resources build up over the use of
-// the commands.
-// This function should be called when the creation and running of
-// command has
-// stopped i.e. application shutdown.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfo::SharedDataDestroy() {
- m_mapIdToSessionData.Clear();
- m_vecVarObj.clear();
- m_mapBrkPtIdToBrkPtInfo.clear();
-}
-
-//++
-// Details: Record information about a LLDB break point so that is can be
-// recalled in other
-// commands or LLDB event handling functions.
-// Type: Method.
-// Args: vBrkPtId - (R) LLDB break point ID.
-// vrBrkPtInfo - (R) Break point information object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo(
- const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo) {
- MapPairBrkPtIdToBrkPtInfo_t pr(vnBrkPtId, vrBrkPtInfo);
- m_mapBrkPtIdToBrkPtInfo.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve information about a LLDB break point previous recorded
-// either by
-// commands or LLDB event handling functions.
-// Type: Method.
-// Args: vBrkPtId - (R) LLDB break point ID.
-// vrwBrkPtInfo - (W) Break point information object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet(
- const MIuint vnBrkPtId, SBrkPtInfo &vrwBrkPtInfo) const {
- const MapBrkPtIdToBrkPtInfo_t::const_iterator it =
- m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId);
- if (it != m_mapBrkPtIdToBrkPtInfo.end()) {
- vrwBrkPtInfo = (*it).second;
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Delete information about a specific LLDB break point object. This
-// function
-// should be called when a LLDB break point is deleted.
-// Type: Method.
-// Args: vBrkPtId - (R) LLDB break point ID.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete(const MIuint vnBrkPtId) {
- const MapBrkPtIdToBrkPtInfo_t::const_iterator it =
- m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId);
- if (it != m_mapBrkPtIdToBrkPtInfo.end()) {
- m_mapBrkPtIdToBrkPtInfo.erase(it);
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Retrieve the specified thread's frame information.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vThreadIdx - (R) Thread index.
-// vwrThreadFrames - (W) Frame data.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::GetThreadFrames(
- const SMICmdData &vCmdData, const MIuint vThreadIdx,
- const FrameInfoFormat_e veFrameInfoFormat, CMIUtilString &vwrThreadFrames) {
- lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
- const uint32_t nFrames = thread.GetNumFrames();
- if (nFrames == 0) {
- // MI print "frame={}"
- CMICmnMIValueTuple miValueTuple;
- CMICmnMIValueResult miValueResult("frame", miValueTuple);
- vwrThreadFrames = miValueResult.GetString();
- return MIstatus::success;
- }
-
- // MI print
- // "frame={level=\"%d\",addr=\"0x%016" PRIx64
- // "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%016"
- // PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},
- // ..."
- CMIUtilString strListCommaSeparated;
- for (MIuint nLevel = 0; nLevel < nFrames; nLevel++) {
- CMICmnMIValueTuple miValueTuple;
- if (!MIResponseFormFrameInfo(thread, nLevel, veFrameInfoFormat,
- miValueTuple))
- return MIstatus::failure;
-
- const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
- if (nLevel != 0)
- strListCommaSeparated += ",";
- strListCommaSeparated += miValueResult2.GetString();
- }
-
- vwrThreadFrames = strListCommaSeparated;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Return the resolved file's path for the given file.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vPath - (R) Original path.
-// vwrResolvedPath - (W) Resolved path.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::ResolvePath(const SMICmdData &vCmdData,
- const CMIUtilString &vPath,
- CMIUtilString &vwrResolvedPath) {
- // ToDo: Verify this code as it does not work as vPath is always empty
-
- CMIUtilString strResolvedPath;
- if (!SharedDataRetrieve<CMIUtilString>(m_constStrSharedDataKeyWkDir,
- strResolvedPath)) {
- vwrResolvedPath = "";
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_SHARED_DATA_NOT_FOUND), vCmdData.strMiCmd.c_str(),
- m_constStrSharedDataKeyWkDir.c_str()));
- return MIstatus::failure;
- }
-
- vwrResolvedPath = vPath;
-
- return ResolvePath(strResolvedPath, vwrResolvedPath);
-}
-
-//++
-// Details: Return the resolved file's path for the given file.
-// Type: Method.
-// Args: vstrUnknown - (R) String assigned to path when resolved path
-// is empty.
-// vwrResolvedPath - (RW) The original path overwritten with resolved
-// path.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::ResolvePath(const CMIUtilString &vstrUnknown,
- CMIUtilString &vwrResolvedPath) {
- if (vwrResolvedPath.size() < 1) {
- vwrResolvedPath = vstrUnknown;
- return MIstatus::success;
- }
-
- bool bOk = MIstatus::success;
-
- CMIUtilString::VecString_t vecPathFolders;
- const MIuint nSplits = vwrResolvedPath.Split("/", vecPathFolders);
- MIunused(nSplits);
- MIuint nFoldersBack = 1; // 1 is just the file (last element of vector)
- while (bOk && (vecPathFolders.size() >= nFoldersBack)) {
- CMIUtilString strTestPath;
- MIuint nFoldersToAdd = nFoldersBack;
- while (nFoldersToAdd > 0) {
- strTestPath += "/";
- strTestPath += vecPathFolders[vecPathFolders.size() - nFoldersToAdd];
- nFoldersToAdd--;
- }
- bool bYesAccessible = false;
- bOk = AccessPath(strTestPath, bYesAccessible);
- if (bYesAccessible) {
- vwrResolvedPath = strTestPath;
- return MIstatus::success;
- } else
- nFoldersBack++;
- }
-
- // No files exist in the union of working directory and debuginfo path
- // Simply use the debuginfo path and let the IDE handle it.
-
- return bOk;
-}
-
-//++
-// Details: Determine the given file path exists or not.
-// Type: Method.
-// Args: vPath - (R) File name path.
-// vwbYesAccessible - (W) True - file exists, false = does not
-// exist.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::AccessPath(const CMIUtilString &vPath,
- bool &vwbYesAccessible) {
-#ifdef _WIN32
- vwbYesAccessible = (::_access(vPath.c_str(), 0) == 0);
-#else
- vwbYesAccessible = (::access(vPath.c_str(), 0) == 0);
-#endif // _WIN32
-
- return MIstatus::success;
-}
-
-//++
-// Details: Form MI partial response by appending more MI value type objects to
-// the
-// tuple type object past in.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vrThread - (R) LLDB thread object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(
- const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
- const ThreadInfoFormat_e veThreadInfoFormat,
- CMICmnMIValueTuple &vwrMIValueTuple) {
- lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
-
- const bool bSuspended = rThread.IsSuspended();
- const lldb::StopReason eReason = rThread.GetStopReason();
- const bool bValidReason = !((eReason == lldb::eStopReasonNone) ||
- (eReason == lldb::eStopReasonInvalid));
- const CMIUtilString strState((bSuspended || bValidReason) ? "stopped"
- : "running");
-
- // Add "id"
- const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID()));
- const CMICmnMIValueConst miValueConst1(strId);
- const CMICmnMIValueResult miValueResult1("id", miValueConst1);
- vwrMIValueTuple.Add(miValueResult1);
-
- // Add "target-id"
- const char *pThreadName = rThread.GetName();
- const MIuint len = CMIUtilString(pThreadName).length();
- const bool bHaveName = (len > 0) && (len < 32) && // 32 is arbitrary number
- CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName);
- const char *pThrdFmt = bHaveName ? "%s" : "Thread %d";
- CMIUtilString strThread;
- if (bHaveName)
- strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
- else
- strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID());
- const CMICmnMIValueConst miValueConst2(strThread);
- const CMICmnMIValueResult miValueResult2("target-id", miValueConst2);
- vwrMIValueTuple.Add(miValueResult2);
-
- // Add "frame"
- if (veThreadInfoFormat != eThreadInfoFormat_NoFrames) {
- CMIUtilString strFrames;
- if (!GetThreadFrames(vCmdData, rThread.GetIndexID(),
- eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames))
- return MIstatus::failure;
-
- const CMICmnMIValueConst miValueConst3(strFrames, true);
- vwrMIValueTuple.Add(miValueConst3, false);
- }
-
- // Add "state"
- const CMICmnMIValueConst miValueConst4(strState);
- const CMICmnMIValueResult miValueResult4("state", miValueConst4);
- vwrMIValueTuple.Add(miValueResult4);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Form MI partial response by appending more MI value type objects to
-// the
-// tuple type object past in.
-// Type: Method.
-// Args: vrFrame - (R) LLDB thread object.
-// vMaskVarTypes - (R) Construed according to VariableType_e.
-// veVarInfoFormat - (R) The type of variable info that should be
-// shown.
-// vwrMIValueList - (W) MI value list object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(
- const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat,
- CMICmnMIValueList &vwrMiValueList, const MIuint vnMaxDepth, /* = 10 */
- const bool vbMarkArgs /* = false*/) {
- bool bOk = MIstatus::success;
- lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
-
- const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
- const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
- const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
- const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
-
- // Handle arguments first
- lldb::SBValueList listArg = rFrame.GetVariables(bArg, false, false, false);
- bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat,
- vwrMiValueList, listArg,
- vnMaxDepth, true, vbMarkArgs);
-
- // Handle remaining variables
- lldb::SBValueList listVars =
- rFrame.GetVariables(false, bLocals, bStatics, bInScopeOnly);
- bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat,
- vwrMiValueList, listVars,
- vnMaxDepth, false, vbMarkArgs);
-
- return bOk;
-}
-
-bool CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(
- const VariableInfoFormat_e veVarInfoFormat,
- CMICmnMIValueList &vwrMiValueList, const lldb::SBValueList &vwrSBValueList,
- const MIuint vnMaxDepth, const bool vbIsArgs, const bool vbMarkArgs) {
- const MIuint nArgs = vwrSBValueList.GetSize();
- for (MIuint i = 0; i < nArgs; i++) {
- CMICmnMIValueTuple miValueTuple;
- lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i);
- // If one stops inside try block with, which catch clause type is unnamed
- // (e.g std::exception&) then value name will be nullptr as well as value
- // pointer
- const char *name = value.GetName();
- if (name == nullptr)
- continue;
- const CMICmnMIValueConst miValueConst(name);
- const CMICmnMIValueResult miValueResultName("name", miValueConst);
- if (vbMarkArgs && vbIsArgs) {
- const CMICmnMIValueConst miValueConstArg("1");
- const CMICmnMIValueResult miValueResultArg("arg", miValueConstArg);
- miValueTuple.Add(miValueResultArg);
- }
- if (veVarInfoFormat != eVariableInfoFormat_NoValues) {
- miValueTuple.Add(miValueResultName); // name
- if (veVarInfoFormat == eVariableInfoFormat_SimpleValues) {
- const CMICmnMIValueConst miValueConst3(value.GetTypeName());
- const CMICmnMIValueResult miValueResult3("type", miValueConst3);
- miValueTuple.Add(miValueResult3);
- }
- const MIuint nChildren = value.GetNumChildren();
- const bool bIsPointerType = value.GetType().IsPointerType();
- if (nChildren == 0 || // no children
- (bIsPointerType && nChildren == 1) || // pointers
- veVarInfoFormat == eVariableInfoFormat_AllValues) // show all values
- {
- CMIUtilString strValue;
- if (GetVariableInfo(value, vnMaxDepth == 0, strValue)) {
- const CMICmnMIValueConst miValueConst2(
- strValue.Escape().AddSlashes());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- }
- }
- vwrMiValueList.Add(miValueTuple);
- continue;
- }
-
- if (vbMarkArgs) {
- // If we are printing names only with vbMarkArgs, we still need to add the
- // name to the value tuple
- miValueTuple.Add(miValueResultName); // name
- vwrMiValueList.Add(miValueTuple);
- } else {
- // If we are printing name only then no need to put it in the tuple.
- vwrMiValueList.Add(miValueResultName);
- }
- }
- return MIstatus::success;
-}
-
-//++
-// Details: Extract the value's name and value or recurse into child value
-// object.
-// Type: Method.
-// Args: vrValue - (R) LLDB value object.
-// vbInSimpleForm - (R) True = Get variable info in simple form (i.e.
-// don't expand aggregates).
-// - False = Get variable info (and expand
-// aggregates if any).
-// vwrStrValue t - (W) The string representation of this value.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::GetVariableInfo(const lldb::SBValue &vrValue,
- const bool vbInSimpleForm,
- CMIUtilString &vwrStrValue) {
- const CMICmnLLDBUtilSBValue utilValue(vrValue, true, false);
- const bool bExpandAggregates = !vbInSimpleForm;
- vwrStrValue = utilValue.GetValue(bExpandAggregates);
- return MIstatus::success;
-}
-
-//++
-// Details: Form MI partial response by appending more MI value type objects to
-// the
-// tuple type object past in.
-// Type: Method.
-// Args: vrThread - (R) LLDB thread object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// vArgInfo - (R) Args information in MI response form.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(
- const lldb::SBThread &vrThread, const MIuint vnLevel,
- const FrameInfoFormat_e veFrameInfoFormat,
- CMICmnMIValueTuple &vwrMiValueTuple) {
- lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
-
- lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel);
- lldb::addr_t pc = 0;
- CMIUtilString fnName;
- CMIUtilString fileName;
- CMIUtilString path;
- MIuint nLine = 0;
- if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
- return MIstatus::failure;
-
- // MI print "{level=\"0\",addr=\"0x%016" PRIx64
- // "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
- const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel));
- const CMICmnMIValueConst miValueConst(strLevel);
- const CMICmnMIValueResult miValueResult("level", miValueConst);
- vwrMiValueTuple.Add(miValueResult);
- const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc));
- const CMICmnMIValueConst miValueConst2(strAddr);
- const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
- vwrMiValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(fnName);
- const CMICmnMIValueResult miValueResult3("func", miValueConst3);
- vwrMiValueTuple.Add(miValueResult3);
- if (veFrameInfoFormat != eFrameInfoFormat_NoArguments) {
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = eVariableType_Arguments;
- if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm) {
- if (!MIResponseFormVariableInfo(frame, maskVarTypes,
- eVariableInfoFormat_AllValues,
- miValueList, 0))
- return MIstatus::failure;
- } else if (!MIResponseFormVariableInfo(frame, maskVarTypes,
- eVariableInfoFormat_AllValues,
- miValueList))
- return MIstatus::failure;
-
- const CMICmnMIValueResult miValueResult4("args", miValueList);
- vwrMiValueTuple.Add(miValueResult4);
- }
- const CMICmnMIValueConst miValueConst5(fileName);
- const CMICmnMIValueResult miValueResult5("file", miValueConst5);
- vwrMiValueTuple.Add(miValueResult5);
- const CMICmnMIValueConst miValueConst6(path);
- const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
- vwrMiValueTuple.Add(miValueResult6);
- const CMIUtilString strLine(CMIUtilString::Format("%d", nLine));
- const CMICmnMIValueConst miValueConst7(strLine);
- const CMICmnMIValueResult miValueResult7("line", miValueConst7);
- vwrMiValueTuple.Add(miValueResult7);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the frame information from LLDB frame object.
-// Type: Method.
-// Args: vrFrame - (R) LLDB thread object.
-// vPc - (W) Address number.
-// vFnName - (W) Function name.
-// vFileName - (W) File name text.
-// vPath - (W) Full file name and path text.
-// vnLine - (W) File line number.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::GetFrameInfo(
- const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName,
- CMIUtilString &vwFileName, CMIUtilString &vwPath, MIuint &vwnLine) {
- lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
-
- static char pBuffer[PATH_MAX];
- const MIuint nBytes =
- rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
- MIunused(nBytes);
- CMIUtilString strResolvedPath(&pBuffer[0]);
- const char *pUnkwn = "??";
- if (!ResolvePath(pUnkwn, strResolvedPath))
- return MIstatus::failure;
- vwPath = strResolvedPath;
-
- vwPc = rFrame.GetPC();
-
- const char *pFnName = rFrame.GetFunctionName();
- vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn;
-
- const char *pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename();
- vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn;
-
- vwnLine = rFrame.GetLineEntry().GetLine();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Form MI partial response by appending more MI value type objects to
-// the
-// tuple type object past in.
-// Type: Method.
-// Args: vrBrkPtInfo - (R) Break point information object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo(
- const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple) {
- const CMIUtilString strAddr(
- CMIUtilString::Format("0x%016" PRIx64, vrBrkPtInfo.m_pc));
- const CMICmnMIValueConst miValueConst2(strAddr);
- const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
- vwrMiValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_fnName);
- const CMICmnMIValueResult miValueResult3("func", miValueConst3);
- vwrMiValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst5(vrBrkPtInfo.m_fileName);
- const CMICmnMIValueResult miValueResult5("file", miValueConst5);
- vwrMiValueTuple.Add(miValueResult5);
- const CMIUtilString strN5 = CMIUtilString::Format(
- "%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str());
- const CMICmnMIValueConst miValueConst6(strN5);
- const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
- vwrMiValueTuple.Add(miValueResult6);
- const CMIUtilString strLine(CMIUtilString::Format("%d", vrBrkPtInfo.m_nLine));
- const CMICmnMIValueConst miValueConst7(strLine);
- const CMICmnMIValueResult miValueResult7("line", miValueConst7);
- vwrMiValueTuple.Add(miValueResult7);
-}
-
-//++
-// Details: Form MI partial response by appending more MI value type objects to
-// the
-// tuple type object past in.
-// Type: Method.
-// Args: vrBrkPtInfo - (R) Break point information object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo(
- const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple) {
- // MI print
- // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
- // PRIx64 "\",
- // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
-
- // "number="
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%d", vrBrkPtInfo.m_id));
- const CMICmnMIValueResult miValueResult("number", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- // "type="
- const CMICmnMIValueConst miValueConst2(vrBrkPtInfo.m_strType);
- const CMICmnMIValueResult miValueResult2("type", miValueConst2);
- miValueTuple.Add(miValueResult2);
- // "disp="
- const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_bDisp ? "del" : "keep");
- const CMICmnMIValueResult miValueResult3("disp", miValueConst3);
- miValueTuple.Add(miValueResult3);
- // "enabled="
- const CMICmnMIValueConst miValueConst4(vrBrkPtInfo.m_bEnabled ? "y" : "n");
- const CMICmnMIValueResult miValueResult4("enabled", miValueConst4);
- miValueTuple.Add(miValueResult4);
- // "addr="
- // "func="
- // "file="
- // "fullname="
- // "line="
- MIResponseFormBrkPtFrameInfo(vrBrkPtInfo, miValueTuple);
- // "pending="
- if (vrBrkPtInfo.m_bPending) {
- const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOrigLoc);
- const CMICmnMIValueList miValueList(miValueConst);
- const CMICmnMIValueResult miValueResult("pending", miValueList);
- miValueTuple.Add(miValueResult);
- }
- if (vrBrkPtInfo.m_bHaveArgOptionThreadGrp) {
- const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOptThrdGrp);
- const CMICmnMIValueList miValueList(miValueConst);
- const CMICmnMIValueResult miValueResult("thread-groups", miValueList);
- miValueTuple.Add(miValueResult);
- }
- // "times="
- const CMICmnMIValueConst miValueConstB(
- CMIUtilString::Format("%d", vrBrkPtInfo.m_nTimes));
- const CMICmnMIValueResult miValueResultB("times", miValueConstB);
- miValueTuple.Add(miValueResultB);
- // "thread="
- if (vrBrkPtInfo.m_bBrkPtThreadId) {
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%d", vrBrkPtInfo.m_nBrkPtThreadId));
- const CMICmnMIValueResult miValueResult("thread", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- // "cond="
- if (vrBrkPtInfo.m_bCondition) {
- const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strCondition);
- const CMICmnMIValueResult miValueResult("cond", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- // "ignore="
- if (vrBrkPtInfo.m_nIgnore != 0) {
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%d", vrBrkPtInfo.m_nIgnore));
- const CMICmnMIValueResult miValueResult("ignore", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- // "original-location="
- const CMICmnMIValueConst miValueConstC(vrBrkPtInfo.m_strOrigLoc);
- const CMICmnMIValueResult miValueResultC("original-location", miValueConstC);
- miValueTuple.Add(miValueResultC);
-
- vwrMiValueTuple = miValueTuple;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve breakpoint information and write into the given breakpoint
-// information
-// object. Note not all possible information is retrieved and so the
-// information
-// object may need to be filled in with more information after calling
-// this
-// function. Mainly breakpoint location information of information that
-// is
-// unlikely to change.
-// Type: Method.
-// Args: vBrkPt - (R) LLDB break point object.
-// vrBrkPtInfo - (W) Break point information object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt,
- SBrkPtInfo &vrwBrkPtInfo) const {
- lldb::SBBreakpoint &rBrkPt = const_cast<lldb::SBBreakpoint &>(vBrkPt);
- lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex(0);
- lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress();
- lldb::SBSymbolContext symbolCntxt =
- brkPtAddr.GetSymbolContext(lldb::eSymbolContextEverything);
- const char *pUnkwn = "??";
- lldb::SBModule rModule = symbolCntxt.GetModule();
- const char *pModule =
- rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn;
- MIunused(pModule);
- const char *pFile = pUnkwn;
- const char *pFn = pUnkwn;
- const char *pFilePath = pUnkwn;
- size_t nLine = 0;
- lldb::addr_t nAddr = brkPtAddr.GetLoadAddress(GetTarget());
- if (nAddr == LLDB_INVALID_ADDRESS)
- nAddr = brkPtAddr.GetFileAddress();
-
- lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
- if (rCmplUnit.IsValid()) {
- lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec();
- pFile = rFileSpec.GetFilename();
- pFilePath = rFileSpec.GetDirectory();
- lldb::SBFunction rFn = symbolCntxt.GetFunction();
- if (rFn.IsValid())
- pFn = rFn.GetName();
- lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry();
- if (rLnEntry.GetLine() > 0)
- nLine = rLnEntry.GetLine();
- }
-
- vrwBrkPtInfo.m_id = vBrkPt.GetID();
- vrwBrkPtInfo.m_strType = "breakpoint";
- vrwBrkPtInfo.m_pc = nAddr;
- vrwBrkPtInfo.m_fnName = pFn;
- vrwBrkPtInfo.m_fileName = pFile;
- vrwBrkPtInfo.m_path = pFilePath;
- vrwBrkPtInfo.m_nLine = nLine;
- vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Get current debugger.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBDebugger - current debugger.
-// Throws: None.
-//--
-lldb::SBDebugger &CMICmnLLDBDebugSessionInfo::GetDebugger() const {
- return CMICmnLLDBDebugger::Instance().GetTheDebugger();
-}
-
-//++
-// Details: Get current listener.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBListener - current listener.
-// Throws: None.
-//--
-lldb::SBListener &CMICmnLLDBDebugSessionInfo::GetListener() const {
- return CMICmnLLDBDebugger::Instance().GetTheListener();
-}
-
-//++
-// Details: Get current target.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBTarget - current target.
-// Throws: None.
-//--
-lldb::SBTarget CMICmnLLDBDebugSessionInfo::GetTarget() const {
- auto target = GetDebugger().GetSelectedTarget();
- if (target.IsValid())
- return target;
- return GetDebugger().GetDummyTarget();
-}
-
-//++
-// Details: Get current process.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBProcess - current process.
-// Throws: None.
-//--
-lldb::SBProcess CMICmnLLDBDebugSessionInfo::GetProcess() const {
- return GetTarget().GetProcess();
-}
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
deleted file mode 100644
index 1fa81951f43a..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
+++ /dev/null
@@ -1,292 +0,0 @@
-//===-- MICmnLLDBDebugSessionInfo.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBListener.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBTarget.h"
-#include <map>
-#include <vector>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnLLDBDebugSessionInfoVarObj.h"
-#include "MICmnMIValueTuple.h"
-#include "MIUtilMapIdToVariant.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilThreadBaseStd.h"
-
-// Declarations:
-class CMICmnLLDBDebugger;
-struct SMICmdData;
-class CMICmnMIValueTuple;
-class CMICmnMIValueList;
-
-//++
-//============================================================================
-// Details: MI debug session object that holds debugging information between
-// instances of MI commands executing their work and producing MI
-// result records. Information/data is set by one or many commands then
-// retrieved by the same or other subsequent commands.
-// It primarily holds LLDB type objects.
-// A singleton class.
-//--
-class CMICmnLLDBDebugSessionInfo
- : public CMICmnBase,
- public MI::ISingleton<CMICmnLLDBDebugSessionInfo> {
- friend class MI::ISingleton<CMICmnLLDBDebugSessionInfo>;
-
- // Structs:
-public:
- //++
- //============================================================================
- // Details: Break point information object. Used to easily pass information
- // about
- // a break around and record break point information to be recalled
- // by
- // other commands or LLDB event handling functions.
- //--
- struct SBrkPtInfo {
- SBrkPtInfo()
- : m_id(0), m_bDisp(false), m_bEnabled(false), m_pc(0), m_nLine(0),
- m_bHaveArgOptionThreadGrp(false), m_nTimes(0), m_bPending(false),
- m_nIgnore(0), m_bCondition(false), m_bBrkPtThreadId(false),
- m_nBrkPtThreadId(0) {}
-
- MIuint m_id; // LLDB break point ID.
- CMIUtilString m_strType; // Break point type.
- bool m_bDisp; // True = "del", false = "keep".
- bool m_bEnabled; // True = enabled, false = disabled break point.
- lldb::addr_t m_pc; // Address number.
- CMIUtilString m_fnName; // Function name.
- CMIUtilString m_fileName; // File name text.
- CMIUtilString m_path; // Full file name and path text.
- MIuint m_nLine; // File line number.
- bool m_bHaveArgOptionThreadGrp; // True = include MI field, false = do not
- // include "thread-groups".
- CMIUtilString m_strOptThrdGrp; // Thread group number.
- MIuint m_nTimes; // The count of the breakpoint existence.
- CMIUtilString m_strOrigLoc; // The name of the break point.
- bool m_bPending; // True = the breakpoint has not been established yet,
- // false = location found
- MIuint m_nIgnore; // The number of time the breakpoint is run over before it
- // is stopped on a hit
- bool m_bCondition; // True = break point is conditional, use condition
- // expression, false = no condition
- CMIUtilString m_strCondition; // Break point condition expression
- bool m_bBrkPtThreadId; // True = break point is specified to work with a
- // specific thread, false = no specified thread given
- MIuint
- m_nBrkPtThreadId; // Restrict the breakpoint to the specified thread-id
- };
-
- // Enumerations:
-public:
- //++ ===================================================================
- // Details: The type of variable used by MIResponseFormVariableInfo family
- // functions.
- //--
- enum VariableType_e {
- eVariableType_InScope = (1u << 0), // In scope only.
- eVariableType_Statics = (1u << 1), // Statics.
- eVariableType_Locals = (1u << 2), // Locals.
- eVariableType_Arguments = (1u << 3) // Arguments.
- };
-
- //++ ===================================================================
- // Details: Determine the information that should be shown by using
- // MIResponseFormVariableInfo family functions.
- //--
- enum VariableInfoFormat_e {
- eVariableInfoFormat_NoValues = 0,
- eVariableInfoFormat_AllValues = 1,
- eVariableInfoFormat_SimpleValues = 2
- };
-
- //++ ===================================================================
- // Details: Determine the information that should be shown by using
- // MIResponseFormThreadInfo family functions.
- //--
- enum ThreadInfoFormat_e {
- eThreadInfoFormat_NoFrames,
- eThreadInfoFormat_AllFrames
- };
-
- //++ ===================================================================
- // Details: Determine the information that should be shown by using
- // MIResponseFormFrameInfo family functions.
- //--
- enum FrameInfoFormat_e {
- eFrameInfoFormat_NoArguments,
- eFrameInfoFormat_AllArguments,
- eFrameInfoFormat_AllArgumentsInSimpleForm
- };
-
- // Typedefs:
-public:
- typedef std::vector<uint32_t> VecActiveThreadId_t;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
-
- // Variant type data which can be assigned and retrieved across all command
- // instances
- template <typename T>
- bool SharedDataAdd(const CMIUtilString &vKey, const T &vData);
- template <typename T>
- bool SharedDataRetrieve(const CMIUtilString &vKey, T &vwData);
- void SharedDataDestroy();
-
- // Common command required functionality
- bool AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible);
- bool ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath,
- CMIUtilString &vwrResolvedPath);
- bool ResolvePath(const CMIUtilString &vstrUnknown,
- CMIUtilString &vwrResolvedPath);
- bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread,
- const MIuint vnLevel,
- const FrameInfoFormat_e veFrameInfoFormat,
- CMICmnMIValueTuple &vwrMiValueTuple);
- bool MIResponseFormThreadInfo(const SMICmdData &vCmdData,
- const lldb::SBThread &vrThread,
- const ThreadInfoFormat_e veThreadInfoFormat,
- CMICmnMIValueTuple &vwrMIValueTuple);
- bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame,
- const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat,
- CMICmnMIValueList &vwrMiValueList,
- const MIuint vnMaxDepth = 10,
- const bool vbMarkArgs = false);
- void MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo,
- CMICmnMIValueTuple &vwrMiValueTuple);
- bool MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo,
- CMICmnMIValueTuple &vwrMiValueTuple);
- bool GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt,
- SBrkPtInfo &vrwBrkPtInfo) const;
- bool RecordBrkPtInfo(const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo);
- bool RecordBrkPtInfoGet(const MIuint vnBrkPtId,
- SBrkPtInfo &vrwBrkPtInfo) const;
- bool RecordBrkPtInfoDelete(const MIuint vnBrkPtId);
- CMIUtilThreadMutex &GetSessionMutex() { return m_sessionMutex; }
- lldb::SBDebugger &GetDebugger() const;
- lldb::SBListener &GetListener() const;
- lldb::SBTarget GetTarget() const;
- lldb::SBProcess GetProcess() const;
-
- // Attributes:
-public:
- // The following are available to all command instances
- const MIuint m_nBrkPointCntMax;
- VecActiveThreadId_t m_vecActiveThreadId;
- lldb::tid_t m_currentSelectedThread;
-
- // These are keys that can be used to access the shared data map
- // Note: This list is expected to grow and will be moved and abstracted in the
- // future.
- const CMIUtilString m_constStrSharedDataKeyWkDir;
- const CMIUtilString m_constStrSharedDataSolibPath;
- const CMIUtilString m_constStrPrintCharArrayAsString;
- const CMIUtilString m_constStrPrintExpandAggregates;
- const CMIUtilString m_constStrPrintAggregateFieldNames;
-
- // Typedefs:
-private:
- typedef std::vector<CMICmnLLDBDebugSessionInfoVarObj> VecVarObj_t;
- typedef std::map<MIuint, SBrkPtInfo> MapBrkPtIdToBrkPtInfo_t;
- typedef std::pair<MIuint, SBrkPtInfo> MapPairBrkPtIdToBrkPtInfo_t;
-
- // Methods:
-private:
- /* ctor */ CMICmnLLDBDebugSessionInfo();
- /* ctor */ CMICmnLLDBDebugSessionInfo(const CMICmnLLDBDebugSessionInfo &);
- void operator=(const CMICmnLLDBDebugSessionInfo &);
- //
- bool GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm,
- CMIUtilString &vwrStrValue);
- bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc,
- CMIUtilString &vwFnName, CMIUtilString &vwFileName,
- CMIUtilString &vwPath, MIuint &vwnLine);
- bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx,
- const FrameInfoFormat_e veFrameInfoFormat,
- CMIUtilString &vwrThreadFrames);
- bool
- MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat,
- CMICmnMIValueList &vwrMiValueList,
- const lldb::SBValueList &vwrSBValueList,
- const MIuint vnMaxDepth,
- const bool vbIsArgs, const bool vbMarkArgs);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnLLDBDebugSessionInfo() override;
-
- // Attributes:
-private:
- CMIUtilMapIdToVariant m_mapIdToSessionData; // Hold and retrieve key to value
- // data available across all
- // commands
- VecVarObj_t m_vecVarObj; // Vector of session variable objects
- MapBrkPtIdToBrkPtInfo_t m_mapBrkPtIdToBrkPtInfo;
- CMIUtilThreadMutex m_sessionMutex;
-};
-
-//++
-// Details: Command instances can create and share data between other instances
-// of commands.
-// This function adds new data to the shared data. Using the same ID
-// more than
-// once replaces any previous matching data keys.
-// Type: Template method.
-// Args: T - The type of the object to be stored.
-// vKey - (R) A non empty unique data key to retrieve the data by.
-// vData - (R) Data to be added to the share.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-template <typename T>
-bool CMICmnLLDBDebugSessionInfo::SharedDataAdd(const CMIUtilString &vKey,
- const T &vData) {
- if (!m_mapIdToSessionData.Add<T>(vKey, vData)) {
- SetErrorDescription(m_mapIdToSessionData.GetErrorDescription());
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Command instances can create and share data between other instances
-// of commands.
-// This function retrieves data from the shared data container.
-// Type: Method.
-// Args: T - The type of the object being retrieved.
-// vKey - (R) A non empty unique data key to retrieve the data by.
-// vData - (W) The data.
-// Return: bool - True = data found, false = data not found or an error
-// occurred trying to fetch.
-// Throws: None.
-//--
-template <typename T>
-bool CMICmnLLDBDebugSessionInfo::SharedDataRetrieve(const CMIUtilString &vKey,
- T &vwData) {
- bool bDataFound = false;
-
- if (!m_mapIdToSessionData.Get<T>(vKey, vwData, bDataFound)) {
- SetErrorDescription(m_mapIdToSessionData.GetErrorDescription());
- return MIstatus::failure;
- }
-
- return bDataFound;
-}
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp
deleted file mode 100644
index fc0f76b6d495..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp
+++ /dev/null
@@ -1,573 +0,0 @@
-//===-- MICmnLLDBDebugSessionInfoVarObj.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnLLDBDebugSessionInfoVarObj.h"
-#include "MICmnLLDBProxySBValue.h"
-#include "MICmnLLDBUtilSBValue.h"
-
-// Instantiations:
-const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatStrings[] = {
- // CODETAG_SESSIONINFO_VARFORMAT_ENUM
- // *** Order is import here.
- "<Invalid var format>", "binary", "octal", "decimal",
- "hexadecimal", "natural"};
-const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatChars[] = {
- // CODETAG_SESSIONINFO_VARFORMAT_ENUM
- // *** Order is import here.
- "<Invalid var format>", "t", "o", "d", "x", "N"};
-CMICmnLLDBDebugSessionInfoVarObj::MapKeyToVarObj_t
- CMICmnLLDBDebugSessionInfoVarObj::ms_mapVarIdToVarObj;
-MIuint CMICmnLLDBDebugSessionInfoVarObj::ms_nVarUniqueId = 0; // Index from 0
-CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
- CMICmnLLDBDebugSessionInfoVarObj::ms_eDefaultFormat = eVarFormat_Natural;
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj()
- : m_eVarFormat(eVarFormat_Natural), m_eVarType(eVarType_Internal) {
- // Do not call UpdateValue() in here as not necessary
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
-// Type: Method.
-// Args: vrStrNameReal - (R) The actual name of the variable, the
-// expression.
-// vrStrName - (R) The name given for *this var object.
-// vrValue - (R) The LLDB SBValue object represented by *this
-// object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(
- const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
- const lldb::SBValue &vrValue)
- : m_eVarFormat(eVarFormat_Natural), m_eVarType(eVarType_Internal),
- m_strName(vrStrName), m_SBValue(vrValue), m_strNameReal(vrStrNameReal) {
- UpdateValue();
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
-// Type: Method.
-// Args: vrStrNameReal - (R) The actual name of the variable, the
-// expression.
-// vrStrName - (R) The name given for *this var object.
-// vrValue - (R) The LLDB SBValue object represented by
-// *this object.
-// vrStrVarObjParentName - (R) The var object parent to *this var
-// object (LLDB SBValue equivalent).
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(
- const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
- const lldb::SBValue &vrValue, const CMIUtilString &vrStrVarObjParentName)
- : m_eVarFormat(eVarFormat_Natural), m_eVarType(eVarType_Internal),
- m_strName(vrStrName), m_SBValue(vrValue), m_strNameReal(vrStrNameReal),
- m_strVarObjParentName(vrStrVarObjParentName) {
- UpdateValue();
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The object to copy from.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(
- const CMICmnLLDBDebugSessionInfoVarObj &vrOther) {
- CopyOther(vrOther);
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The object to copy from.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(
- CMICmnLLDBDebugSessionInfoVarObj &vrOther) {
- CopyOther(vrOther);
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj move constructor.
-// Type: Method.
-// Args: vrwOther - (R) The object to copy from.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj(
- CMICmnLLDBDebugSessionInfoVarObj &&vrwOther) {
- MoveOther(vrwOther);
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj assignment operator.
-// Type: Method.
-// Args: vrOther - (R) The object to copy from.
-// Return: CMICmnLLDBDebugSessionInfoVarObj & - Updated *this object.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj &CMICmnLLDBDebugSessionInfoVarObj::
-operator=(const CMICmnLLDBDebugSessionInfoVarObj &vrOther) {
- CopyOther(vrOther);
-
- return *this;
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj assignment operator.
-// Type: Method.
-// Args: vrwOther - (R) The object to copy from.
-// Return: CMICmnLLDBDebugSessionInfoVarObj & - Updated *this object.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj &CMICmnLLDBDebugSessionInfoVarObj::
-operator=(CMICmnLLDBDebugSessionInfoVarObj &&vrwOther) {
- MoveOther(vrwOther);
-
- return *this;
-}
-
-//++
-// Details: Copy the other instance of that object to *this object.
-// Type: Method.
-// Args: vrOther - (R) The object to copy from.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfoVarObj::CopyOther(
- const CMICmnLLDBDebugSessionInfoVarObj &vrOther) {
- // Check for self-assignment
- if (this == &vrOther)
- return MIstatus::success;
-
- m_eVarFormat = vrOther.m_eVarFormat;
- m_eVarType = vrOther.m_eVarType;
- m_strName = vrOther.m_strName;
- m_SBValue = vrOther.m_SBValue;
- m_strNameReal = vrOther.m_strNameReal;
- m_strFormattedValue = vrOther.m_strFormattedValue;
- m_strVarObjParentName = vrOther.m_strVarObjParentName;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Move that object to *this object.
-// Type: Method.
-// Args: vrwOther - (RW) The object to copy from.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfoVarObj::MoveOther(
- CMICmnLLDBDebugSessionInfoVarObj &vrwOther) {
- // Check for self-assignment
- if (this == &vrwOther)
- return MIstatus::success;
-
- CopyOther(vrwOther);
- vrwOther.m_eVarFormat = eVarFormat_Natural;
- vrwOther.m_eVarType = eVarType_Internal;
- vrwOther.m_strName.clear();
- vrwOther.m_SBValue.Clear();
- vrwOther.m_strNameReal.clear();
- vrwOther.m_strFormattedValue.clear();
- vrwOther.m_strVarObjParentName.clear();
-
- return MIstatus::success;
-}
-
-//++
-// Details: CMICmnLLDBDebugSessionInfoVarObj destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::~CMICmnLLDBDebugSessionInfoVarObj() {}
-
-//++
-// Details: Retrieve the var format enumeration for the specified string.
-// Type: Static method.
-// Args: vrStrFormat - (R) Text description of the var format.
-// Return: varFormat_e - Var format enumeration.
-// - No match found return eVarFormat_Invalid.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
-CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(
- const CMIUtilString &vrStrFormat) {
- // CODETAG_SESSIONINFO_VARFORMAT_ENUM
- for (MIuint i = 0; i < eVarFormat_count; i++) {
- const char *pVarFormatString = ms_aVarFormatStrings[i];
- if (vrStrFormat == pVarFormatString)
- return static_cast<varFormat_e>(i);
- }
-
- return eVarFormat_Invalid;
-}
-
-//++
-// Details: Retrieve the var format enumeration for the specified character.
-// Type: Static method.
-// Args: vcFormat - Character representing the var format.
-// Return: varFormat_e - Var format enumeration.
-// - No match found return eVarFormat_Invalid.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
-CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(char vcFormat) {
- if ('r' == vcFormat)
- return eVarFormat_Hex;
-
- // CODETAG_SESSIONINFO_VARFORMAT_ENUM
- for (MIuint i = 0; i < eVarFormat_count; i++) {
- const char *pVarFormatChar = ms_aVarFormatChars[i];
- if (*pVarFormatChar == vcFormat)
- return static_cast<varFormat_e>(i);
- }
-
- return eVarFormat_Invalid;
-}
-
-//++
-// Details: Return the equivalent var value formatted string for the given value
-// type,
-// which was prepared for printing (i.e. value was escaped and now it's
-// ready
-// for wrapping into quotes).
-// The SBValue vrValue parameter is checked by LLDB private code for
-// valid
-// scalar type via MI Driver proxy function as the valued returned can
-// also be
-// an error condition. The proxy function determines if the check was
-// valid
-// otherwise return an error condition state by other means saying so.
-// Type: Static method.
-// Args: vrValue - (R) The var value object.
-// veVarFormat - (R) Var format enumeration.
-// Returns: CMIUtilString - Value formatted string.
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(
- const lldb::SBValue &vrValue,
- const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat) {
- const CMICmnLLDBUtilSBValue utilValue(vrValue, true);
- if (utilValue.IsIntegerType()) {
- MIuint64 nValue = 0;
- if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(vrValue, nValue)) {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- return GetStringFormatted(nValue, rValue.GetValue(), veVarFormat);
- }
- }
-
- return utilValue.GetValue().AddSlashes();
-}
-
-//++
-// Details: Return number formatted string according to the given value type.
-// Type: Static method.
-// Args: vnValue - (R) The number value to get formatted.
-// vpStrValueNatural - (R) The natural representation of the number
-// value.
-// veVarFormat - (R) Var format enumeration.
-// Returns: CMIUtilString - Numerical formatted string.
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetStringFormatted(
- const MIuint64 vnValue, const char *vpStrValueNatural,
- const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat) {
- CMIUtilString strFormattedValue;
- CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veFormat = veVarFormat;
- if (ms_eDefaultFormat != eVarFormat_Invalid &&
- veVarFormat == eVarFormat_Natural) {
- veFormat = ms_eDefaultFormat;
- }
-
- switch (veFormat) {
- case eVarFormat_Binary:
- strFormattedValue = CMIUtilString::FormatBinary(vnValue);
- break;
- case eVarFormat_Octal:
- strFormattedValue = CMIUtilString::Format("0%llo", vnValue);
- break;
- case eVarFormat_Decimal:
- strFormattedValue = CMIUtilString::Format("%lld", vnValue);
- break;
- case eVarFormat_Hex:
- strFormattedValue = CMIUtilString::Format("0x%llx", vnValue);
- break;
- case eVarFormat_Natural:
- default: {
- strFormattedValue = (vpStrValueNatural != nullptr) ? vpStrValueNatural : "";
- }
- }
-
- return strFormattedValue;
-}
-
-//++
-// Details: Delete internal container contents.
-// Type: Static method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjClear() {
- ms_mapVarIdToVarObj.clear();
-}
-
-//++
-// Details: Add a var object to the internal container.
-// Type: Static method.
-// Args: vrVarObj - (R) The var value object.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjAdd(
- const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj) {
- VarObjDelete(vrVarObj.GetName());
- MapPairKeyToVarObj_t pr(vrVarObj.GetName(), vrVarObj);
- ms_mapVarIdToVarObj.insert(pr);
-}
-
-//++
-// Details: Delete the var object from the internal container matching the
-// specified name.
-// Type: Static method.
-// Args: vrVarName - (R) The var value name.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete(
- const CMIUtilString &vrVarName) {
- const MapKeyToVarObj_t::const_iterator it =
- ms_mapVarIdToVarObj.find(vrVarName);
- if (it != ms_mapVarIdToVarObj.end()) {
- ms_mapVarIdToVarObj.erase(it);
- }
-}
-
-//++
-// Details: Update an existing var object in the internal container.
-// Type: Static method.
-// Args: vrVarObj - (R) The var value object.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjUpdate(
- const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj) {
- VarObjAdd(vrVarObj);
-}
-
-//++
-// Details: Retrieve the var object matching the specified name.
-// Type: Static method.
-// Args: vrVarName - (R) The var value name.
-// vrwVarObj - (W) A var object.
-// Returns: bool - True = object found, false = object not found.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(
- const CMIUtilString &vrVarName,
- CMICmnLLDBDebugSessionInfoVarObj &vrwVarObj) {
- const MapKeyToVarObj_t::const_iterator it =
- ms_mapVarIdToVarObj.find(vrVarName);
- if (it != ms_mapVarIdToVarObj.end()) {
- const CMICmnLLDBDebugSessionInfoVarObj &rVarObj = (*it).second;
- vrwVarObj = rVarObj;
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: A count is kept of the number of var value objects created. This is
-// count is
-// used to ID the var value object. Reset the count to 0.
-// Type: Static method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero() {
- ms_nVarUniqueId = 0;
-}
-
-//++
-// Details: Default format is globally used as the data format when "natural" is
-// in effect, that is, this overrides the default
-// Type: Static method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(
- varFormat_e eDefaultFormat) {
- ms_eDefaultFormat = eDefaultFormat;
-}
-
-//++
-// Details: A count is kept of the number of var value objects created. This is
-// count is
-// used to ID the var value object. Increment the count by 1.
-// Type: Static method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc() { ms_nVarUniqueId++; }
-
-//++
-// Details: A count is kept of the number of var value objects created. This is
-// count is
-// used to ID the var value object. Retrieve ID.
-// Type: Static method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-MIuint CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet() {
- return ms_nVarUniqueId;
-}
-
-//++
-// Details: Retrieve the value formatted object's name.
-// Type: Method.
-// Args: None.
-// Returns: CMIUtilString & - Value's var%u name text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLLDBDebugSessionInfoVarObj::GetName() const {
- return m_strName;
-}
-
-//++
-// Details: Retrieve the value formatted object's variable name as given in the
-// MI command
-// to create the var object.
-// Type: Method.
-// Args: None.
-// Returns: CMIUtilString & - Value's real name text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLLDBDebugSessionInfoVarObj::GetNameReal() const {
- return m_strNameReal;
-}
-
-//++
-// Details: Retrieve the value formatted string.
-// Type: Method.
-// Args: None.
-// Returns: CMIUtilString & - Value formatted string.
-// Throws: None.
-//--
-const CMIUtilString &
-CMICmnLLDBDebugSessionInfoVarObj::GetValueFormatted() const {
- return m_strFormattedValue;
-}
-
-//++
-// Details: Retrieve the LLDB Value object.
-// Type: Method.
-// Args: None.
-// Returns: lldb::SBValue & - LLDB Value object.
-// Throws: None.
-//--
-lldb::SBValue &CMICmnLLDBDebugSessionInfoVarObj::GetValue() {
- return m_SBValue;
-}
-
-//++
-// Details: Retrieve the LLDB Value object.
-// Type: Method.
-// Args: None.
-// Returns: lldb::SBValue & - Constant LLDB Value object.
-// Throws: None.
-//--
-const lldb::SBValue &CMICmnLLDBDebugSessionInfoVarObj::GetValue() const {
- return m_SBValue;
-}
-
-//++
-// Details: Set the var format type for *this object and update the formatting.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugSessionInfoVarObj::SetVarFormat(
- const varFormat_e veVarFormat) {
- if (veVarFormat >= eVarFormat_count)
- return MIstatus::failure;
-
- m_eVarFormat = veVarFormat;
- UpdateValue();
- return MIstatus::success;
-}
-
-//++
-// Details: Update *this var obj. Update it's value and type.
-// Type: Method.
-// Args: None.
-// Returns: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugSessionInfoVarObj::UpdateValue() {
- m_strFormattedValue = GetValueStringFormatted(m_SBValue, m_eVarFormat);
-
- MIuint64 nValue = 0;
- if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(m_SBValue, nValue) ==
- MIstatus::failure)
- m_eVarType = eVarType_Composite;
-
- CMICmnLLDBDebugSessionInfoVarObj::VarObjUpdate(*this);
-}
-
-//++
-// Details: Retrieve the enumeration type of the var object.
-// Type: Method.
-// Args: None.
-// Returns: varType_e - Enumeration value.
-// Throws: None.
-//--
-CMICmnLLDBDebugSessionInfoVarObj::varType_e
-CMICmnLLDBDebugSessionInfoVarObj::GetType() const {
- return m_eVarType;
-}
-
-//++
-// Details: Retrieve the parent var object's name, the parent var object to
-// *this var
-// object (if assigned). The parent is equivalent to LLDB SBValue
-// variable's
-// parent.
-// Type: Method.
-// Args: None.
-// Returns: CMIUtilString & - Pointer to var object, NULL = no parent.
-// Throws: None.
-//--
-const CMIUtilString &
-CMICmnLLDBDebugSessionInfoVarObj::GetVarParentName() const {
- return m_strVarObjParentName;
-}
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
deleted file mode 100644
index 6cee598fccc3..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===-- MICmnLLDBDebugSessionInfoVarObj.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third Party Headers:
-#include "lldb/API/SBValue.h"
-#include <map>
-
-// In-house headers:
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI debug session variable object. The static functionality in *this
-// class manages a map container of *these variable objects.
-//--
-class CMICmnLLDBDebugSessionInfoVarObj {
- // Enums:
-public:
- //++ ----------------------------------------------------------------------
- // Details: Enumeration of a variable type that is not a composite type
- //--
- enum varFormat_e {
- // CODETAG_SESSIONINFO_VARFORMAT_ENUM
- // *** Order is import here ***
- eVarFormat_Invalid = 0,
- eVarFormat_Binary,
- eVarFormat_Octal,
- eVarFormat_Decimal,
- eVarFormat_Hex,
- eVarFormat_Natural,
- eVarFormat_count // Always last one
- };
-
- //++ ----------------------------------------------------------------------
- // Details: Enumeration of a variable type by composite or internal type
- //--
- enum varType_e {
- eVarType_InValid = 0,
- eVarType_Composite, // i.e. struct
- eVarType_Internal, // i.e. int
- eVarType_count // Always last one
- };
-
- // Statics:
-public:
- static varFormat_e GetVarFormatForString(const CMIUtilString &vrStrFormat);
- static varFormat_e GetVarFormatForChar(char vcFormat);
- static CMIUtilString GetValueStringFormatted(const lldb::SBValue &vrValue,
- const varFormat_e veVarFormat);
- static void VarObjAdd(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj);
- static void VarObjDelete(const CMIUtilString &vrVarName);
- static bool VarObjGet(const CMIUtilString &vrVarName,
- CMICmnLLDBDebugSessionInfoVarObj &vrwVarObj);
- static void VarObjUpdate(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj);
- static void VarObjIdInc();
- static MIuint VarObjIdGet();
- static void VarObjIdResetToZero();
- static void VarObjClear();
- static void VarObjSetFormat(varFormat_e eDefaultFormat);
-
- // Methods:
-public:
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj();
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj(
- const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
- const lldb::SBValue &vrValue);
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj(
- const CMIUtilString &vrStrNameReal, const CMIUtilString &vrStrName,
- const lldb::SBValue &vrValue, const CMIUtilString &vrStrVarObjParentName);
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj(
- const CMICmnLLDBDebugSessionInfoVarObj &vrOther);
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj(
- CMICmnLLDBDebugSessionInfoVarObj &vrOther);
- /* ctor */ CMICmnLLDBDebugSessionInfoVarObj(
- CMICmnLLDBDebugSessionInfoVarObj &&vrOther);
- //
- CMICmnLLDBDebugSessionInfoVarObj &
- operator=(const CMICmnLLDBDebugSessionInfoVarObj &vrOther);
- CMICmnLLDBDebugSessionInfoVarObj &
- operator=(CMICmnLLDBDebugSessionInfoVarObj &&vrwOther);
- //
- const CMIUtilString &GetName() const;
- const CMIUtilString &GetNameReal() const;
- const CMIUtilString &GetValueFormatted() const;
- lldb::SBValue &GetValue();
- const lldb::SBValue &GetValue() const;
- varType_e GetType() const;
- bool SetVarFormat(const varFormat_e veVarFormat);
- const CMIUtilString &GetVarParentName() const;
- void UpdateValue();
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ virtual ~CMICmnLLDBDebugSessionInfoVarObj();
-
- // Typedefs:
-private:
- typedef std::map<CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj>
- MapKeyToVarObj_t;
- typedef std::pair<CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj>
- MapPairKeyToVarObj_t;
-
- // Statics:
-private:
- static CMIUtilString GetStringFormatted(const MIuint64 vnValue,
- const char *vpStrValueNatural,
- varFormat_e veVarFormat);
-
- // Methods:
-private:
- bool CopyOther(const CMICmnLLDBDebugSessionInfoVarObj &vrOther);
- bool MoveOther(CMICmnLLDBDebugSessionInfoVarObj &vrwOther);
-
- // Attributes:
-private:
- static const char *ms_aVarFormatStrings[];
- static const char *ms_aVarFormatChars[];
- static MapKeyToVarObj_t ms_mapVarIdToVarObj;
- static MIuint ms_nVarUniqueId;
- static varFormat_e ms_eDefaultFormat; // overrides "natural" format
- //
- // *** Update the copy move constructors and assignment operator ***
- varFormat_e m_eVarFormat;
- varType_e m_eVarType;
- CMIUtilString m_strName;
- lldb::SBValue m_SBValue;
- CMIUtilString m_strNameReal;
- CMIUtilString m_strFormattedValue;
- CMIUtilString m_strVarObjParentName;
- // *** Update the copy move constructors and assignment operator ***
-};
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.cpp b/tools/lldb-mi/MICmnLLDBDebugger.cpp
deleted file mode 100644
index b22e7d9a1fe6..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugger.cpp
+++ /dev/null
@@ -1,905 +0,0 @@
-//===-- MICmnLLDBDebugger.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBThread.h"
-#include "lldb/API/SBType.h"
-#include "lldb/API/SBTypeCategory.h"
-#include "lldb/API/SBTypeNameSpecifier.h"
-#include "lldb/API/SBTypeSummary.h"
-#include <cassert>
-
-// In-house headers:
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLLDBDebuggerHandleEvents.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MICmnThreadMgrStd.h"
-#include "MIDriverBase.h"
-#include "MIUtilSingletonHelper.h"
-
-//++
-// MI private summary providers
-static inline bool MI_char_summary_provider(lldb::SBValue value,
- lldb::SBTypeSummaryOptions options,
- lldb::SBStream &stream) {
- if (!value.IsValid())
- return false;
-
- lldb::SBType value_type = value.GetType();
- if (!value_type.IsValid())
- return false;
-
- lldb::BasicType type_code = value_type.GetBasicType();
- if (type_code == lldb::eBasicTypeSignedChar)
- stream.Printf("%d %s", (int)value.GetValueAsSigned(),
- CMIUtilString::WithNullAsEmpty(value.GetValue()));
- else if (type_code == lldb::eBasicTypeUnsignedChar)
- stream.Printf("%u %s", (unsigned)value.GetValueAsUnsigned(),
- CMIUtilString::WithNullAsEmpty(value.GetValue()));
- else
- return false;
-
- return true;
-}
-
-//++
-// MI summary helper routines
-static inline bool MI_add_summary(lldb::SBTypeCategory category,
- const char *typeName,
- lldb::SBTypeSummary::FormatCallback cb,
- uint32_t options, bool regex = false) {
-#if defined(LLDB_DISABLE_PYTHON)
- return false;
-#else
- lldb::SBTypeSummary summary =
- lldb::SBTypeSummary::CreateWithCallback(cb, options);
- return summary.IsValid()
- ? category.AddTypeSummary(
- lldb::SBTypeNameSpecifier(typeName, regex), summary)
- : false;
-#endif
-}
-
-//++
-// Details: CMICmnLLDBDebugger constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugger::CMICmnLLDBDebugger()
- : m_constStrThisThreadId("MI debugger event") {}
-
-//++
-// Details: CMICmnLLDBDebugger destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebugger::~CMICmnLLDBDebugger() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this debugger object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
- ClrErrorDescription();
-
- if (m_pClientDriver == nullptr) {
- bOk = false;
- errMsg = MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER);
- }
-
- // Note initialization order is important here as some resources depend on
- // previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg);
- MI::ModuleInit<CMICmnLLDBDebuggerHandleEvents>(
- IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
- MI::ModuleInit<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO,
- bOk, errMsg);
-
- // Note order is important here!
- if (bOk)
- lldb::SBDebugger::Initialize();
- if (bOk && !InitSBDebugger()) {
- bOk = false;
- if (!errMsg.empty())
- errMsg += ", ";
- errMsg += GetErrorDescription().c_str();
- }
- if (bOk && !InitSBListener()) {
- bOk = false;
- if (!errMsg.empty())
- errMsg += ", ";
- errMsg += GetErrorDescription().c_str();
- }
- bOk = bOk && InitStdStreams();
- bOk = bOk && RegisterMISummaryProviders();
- m_bInitialized = bOk;
-
- if (!bOk && !HaveErrorDescription()) {
- CMIUtilString strInitError(CMIUtilString::Format(
- MIRSRC(IDS_MI_INIT_ERR_LLDBDEBUGGER), errMsg.c_str()));
- SetErrorDescription(strInitError);
- }
-
- return bOk;
-}
-
-//++
-// Details: Release resources for *this debugger object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Explicitly delete the remote target in case MI needs to exit prematurely
- // otherwise
- // LLDB debugger may hang in its Destroy() fn waiting on events
- lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
- m_lldbDebugger.DeleteTarget(sbTarget);
-
- // Debug: May need this but does seem to work without it so commented out the
- // fudge 19/06/2014
- // It appears we need to wait as hang does not occur when hitting a debug
- // breakpoint here
- // const std::chrono::milliseconds time( 1000 );
- // std::this_thread::sleep_for( time );
-
- lldb::SBDebugger::Destroy(m_lldbDebugger);
- lldb::SBDebugger::Terminate();
- m_pClientDriver = nullptr;
- m_mapBroadcastClassNameToEventMask.clear();
- m_mapIdToEventMask.clear();
-
- // Note shutdown order is important here
- MI::ModuleShutdown<CMICmnLLDBDebugSessionInfo>(
- IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLLDBDebuggerHandleEvents>(
- IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg);
- MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_LLDBDEBUGGER),
- errMsg.c_str());
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Return the LLDB debugger instance created for this debug session.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBDebugger & - LLDB debugger object reference.
-// Throws: None.
-//--
-lldb::SBDebugger &CMICmnLLDBDebugger::GetTheDebugger() {
- return m_lldbDebugger;
-}
-
-//++
-// Details: Return the LLDB listener instance created for this debug session.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBListener & - LLDB listener object reference.
-// Throws: None.
-//--
-lldb::SBListener &CMICmnLLDBDebugger::GetTheListener() {
- return m_lldbListener;
-}
-
-//++
-// Details: Set the client driver that wants to use *this LLDB debugger. Call
-// this function
-// prior to Initialize().
-// Type: Method.
-// Args: vClientDriver - (R) A driver.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::SetDriver(const CMIDriverBase &vClientDriver) {
- m_pClientDriver = const_cast<CMIDriverBase *>(&vClientDriver);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Get the client driver that is use *this LLDB debugger.
-// Type: Method.
-// Args: vClientDriver - (R) A driver.
-// Return: CMIDriverBase & - A driver instance.
-// Throws: None.
-//--
-CMIDriverBase &CMICmnLLDBDebugger::GetDriver() const {
- return *m_pClientDriver;
-}
-
-//++
-// Details: Wait until all events have been handled.
-// This function works in pair with
-// CMICmnLLDBDebugger::MonitorSBListenerEvents
-// that handles events from queue. When all events were handled and
-// queue is
-// empty the MonitorSBListenerEvents notifies this function that it's
-// ready to
-// go on. To synchronize them the m_mutexEventQueue and
-// m_conditionEventQueueEmpty are used.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugger::WaitForHandleEvent() {
- std::unique_lock<std::mutex> lock(m_mutexEventQueue);
-
- lldb::SBEvent event;
- if (ThreadIsActive() && m_lldbListener.PeekAtNextEvent(event))
- m_conditionEventQueueEmpty.wait(lock);
-}
-
-//++
-// Details: Check if need to rebroadcast stop event. This function will return
-// true if
-// debugger is in synchronouse mode. In such case the
-// CMICmnLLDBDebugger::RebroadcastStopEvent should be called to
-// rebroadcast
-// a new stop event (if any).
-// Type: Method.
-// Args: None.
-// Return: bool - True = Need to rebroadcast stop event, false = otherwise.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- if (!rSessionInfo.GetDebugger().GetAsync()) {
- const bool include_expression_stops = false;
- m_nLastStopId =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetStopID(
- include_expression_stops);
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: Rebroadcast stop event if needed. This function should be called
-// only if the
-// CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() returned
-// true.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLLDBDebugger::RebroadcastStopEvent() {
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- const bool include_expression_stops = false;
- const uint32_t nStopId = process.GetStopID(include_expression_stops);
- if (m_nLastStopId != nStopId) {
- lldb::SBEvent event = process.GetStopEventForStopID(nStopId);
- process.GetBroadcaster().BroadcastEvent(event);
- }
-}
-
-//++
-// Details: Initialize the LLDB Debugger object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::InitSBDebugger() {
- m_lldbDebugger = lldb::SBDebugger::Create(false);
- if (!m_lldbDebugger.IsValid()) {
- SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER));
- return MIstatus::failure;
- }
-
- m_lldbDebugger.GetCommandInterpreter().SetPromptOnQuit(false);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Set the LLDB Debugger's std in, err and out streams. (Not
-// implemented left
-// here for reference. Was called in the
-// CMICmnLLDBDebugger::Initialize() )
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::InitStdStreams() {
- // This is not required when operating the MI driver's code as it has its own
- // streams. Setting the Stdin for the lldbDebugger especially on LINUX will
- // cause
- // another thread to run and partially consume stdin data meant for MI stdin
- // handler
- // m_lldbDebugger.SetErrorFileHandle( m_pClientDriver->GetStderr(), false );
- // m_lldbDebugger.SetOutputFileHandle( m_pClientDriver->GetStdout(), false );
- // m_lldbDebugger.SetInputFileHandle( m_pClientDriver->GetStdin(), false );
-
- return MIstatus::success;
-}
-
-//++
-// Details: Set up the events from the SBDebugger's we would like to listen to.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::InitSBListener() {
- m_lldbListener = m_lldbDebugger.GetListener();
- if (!m_lldbListener.IsValid()) {
- SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER));
- return MIstatus::failure;
- }
-
- const CMIUtilString strDbgId("CMICmnLLDBDebugger1");
- MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged |
- lldb::SBTarget::eBroadcastBitModulesLoaded |
- lldb::SBTarget::eBroadcastBitModulesUnloaded |
- lldb::SBTarget::eBroadcastBitWatchpointChanged |
- lldb::SBTarget::eBroadcastBitSymbolsLoaded;
- bool bOk = RegisterForEvent(
- strDbgId, CMIUtilString(lldb::SBTarget::GetBroadcasterClassName()),
- eventMask);
-
- eventMask = lldb::SBThread::eBroadcastBitStackChanged;
- bOk = bOk &&
- RegisterForEvent(
- strDbgId, CMIUtilString(lldb::SBThread::GetBroadcasterClassName()),
- eventMask);
-
- eventMask = lldb::SBProcess::eBroadcastBitStateChanged |
- lldb::SBProcess::eBroadcastBitInterrupt |
- lldb::SBProcess::eBroadcastBitSTDOUT |
- lldb::SBProcess::eBroadcastBitSTDERR |
- lldb::SBProcess::eBroadcastBitProfileData |
- lldb::SBProcess::eBroadcastBitStructuredData;
- bOk = bOk &&
- RegisterForEvent(
- strDbgId, CMIUtilString(lldb::SBProcess::GetBroadcasterClassName()),
- eventMask);
-
- eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
- lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit |
- lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
- lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData;
- bOk = bOk &&
- RegisterForEvent(
- strDbgId, m_lldbDebugger.GetCommandInterpreter().GetBroadcaster(),
- eventMask);
-
- return bOk;
-}
-
-//++
-// Details: Register with the debugger, the SBListener, the type of events you
-// are interested
-// in. Others, like commands, may have already set the mask.
-// Type: Method.
-// Args: vClientName - (R) ID of the client who wants these events
-// set.
-// vBroadcasterClass - (R) The SBBroadcaster's class name.
-// vEventMask - (R) The mask of events to listen for.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::RegisterForEvent(
- const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass,
- const MIuint vEventMask) {
- MIuint existingMask = 0;
- if (!BroadcasterGetMask(vBroadcasterClass, existingMask))
- return MIstatus::failure;
-
- if (!ClientSaveMask(vClientName, vBroadcasterClass, vEventMask))
- return MIstatus::failure;
-
- const char *pBroadCasterName = vBroadcasterClass.c_str();
- MIuint eventMask = vEventMask;
- eventMask += existingMask;
- const MIuint result = m_lldbListener.StartListeningForEventClass(
- m_lldbDebugger, pBroadCasterName, eventMask);
- if (result == 0) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadCasterName));
- return MIstatus::failure;
- }
-
- return BroadcasterSaveMask(vBroadcasterClass, eventMask);
-}
-
-//++
-// Details: Register with the debugger, the SBListener, the type of events you
-// are interested
-// in. Others, like commands, may have already set the mask.
-// Type: Method.
-// Args: vClientName - (R) ID of the client who wants these events set.
-// vBroadcaster - (R) An SBBroadcaster's derived class.
-// vEventMask - (R) The mask of events to listen for.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::RegisterForEvent(
- const CMIUtilString &vClientName, const lldb::SBBroadcaster &vBroadcaster,
- const MIuint vEventMask) {
- const char *pBroadcasterName = vBroadcaster.GetName();
- if (pBroadcasterName == nullptr) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME),
- MIRSRC(IDS_WORD_INVALIDNULLPTR)));
- return MIstatus::failure;
- }
- CMIUtilString broadcasterName(pBroadcasterName);
- if (broadcasterName.length() == 0) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME),
- MIRSRC(IDS_WORD_INVALIDEMPTY)));
- return MIstatus::failure;
- }
-
- MIuint existingMask = 0;
- if (!BroadcasterGetMask(broadcasterName, existingMask))
- return MIstatus::failure;
-
- if (!ClientSaveMask(vClientName, broadcasterName, vEventMask))
- return MIstatus::failure;
-
- MIuint eventMask = vEventMask;
- eventMask += existingMask;
- const MIuint result =
- m_lldbListener.StartListeningForEvents(vBroadcaster, eventMask);
- if (result == 0) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadcasterName));
- return MIstatus::failure;
- }
-
- return BroadcasterSaveMask(broadcasterName, eventMask);
-}
-
-//++
-// Details: Unregister with the debugger, the SBListener, the type of events you
-// are no
-// longer interested in. Others, like commands, may still remain
-// interested so
-// an event may not necessarily be stopped.
-// Type: Method.
-// Args: vClientName - (R) ID of the client who no longer requires
-// these events.
-// vBroadcasterClass - (R) The SBBroadcaster's class name.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::UnregisterForEvent(
- const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) {
- MIuint clientsEventMask = 0;
- if (!ClientGetTheirMask(vClientName, vBroadcasterClass, clientsEventMask))
- return MIstatus::failure;
- if (!ClientRemoveTheirMask(vClientName, vBroadcasterClass))
- return MIstatus::failure;
-
- const MIuint otherClientsEventMask =
- ClientGetMaskForAllClients(vBroadcasterClass);
- MIuint newEventMask = 0;
- for (MIuint i = 0; i < 32; i++) {
- const MIuint bit = MIuint(1) << i;
- const MIuint clientBit = bit & clientsEventMask;
- const MIuint othersBit = bit & otherClientsEventMask;
- if ((clientBit != 0) && (othersBit == 0)) {
- newEventMask += clientBit;
- }
- }
-
- const char *pBroadCasterName = vBroadcasterClass.c_str();
- if (!m_lldbListener.StopListeningForEventClass(
- m_lldbDebugger, pBroadCasterName, newEventMask)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STOPLISTENER),
- vClientName.c_str(), pBroadCasterName));
- return MIstatus::failure;
- }
-
- return BroadcasterSaveMask(vBroadcasterClass, otherClientsEventMask);
-}
-
-//++
-// Details: Given the SBBroadcaster class name retrieve it's current event mask.
-// Type: Method.
-// Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
-// vEventMask - (W) The mask of events to listen for.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::BroadcasterGetMask(
- const CMIUtilString &vBroadcasterClass, MIuint &vwEventMask) const {
- vwEventMask = 0;
-
- if (vBroadcasterClass.empty()) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER),
- vBroadcasterClass.c_str()));
- return MIstatus::failure;
- }
-
- const MapBroadcastClassNameToEventMask_t::const_iterator it =
- m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass);
- if (it != m_mapBroadcastClassNameToEventMask.end()) {
- vwEventMask = (*it).second;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Remove the event mask for the specified SBBroadcaster class name.
-// Type: Method.
-// Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::BroadcasterRemoveMask(
- const CMIUtilString &vBroadcasterClass) {
- MapBroadcastClassNameToEventMask_t::const_iterator it =
- m_mapBroadcastClassNameToEventMask.find(vBroadcasterClass);
- if (it != m_mapBroadcastClassNameToEventMask.end()) {
- m_mapBroadcastClassNameToEventMask.erase(it);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Given the SBBroadcaster class name save it's current event mask.
-// Type: Method.
-// Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
-// vEventMask - (R) The mask of events to listen for.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::BroadcasterSaveMask(
- const CMIUtilString &vBroadcasterClass, const MIuint vEventMask) {
- if (vBroadcasterClass.empty()) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER),
- vBroadcasterClass.c_str()));
- return MIstatus::failure;
- }
-
- BroadcasterRemoveMask(vBroadcasterClass);
- MapPairBroadcastClassNameToEventMask_t pr(vBroadcasterClass, vEventMask);
- m_mapBroadcastClassNameToEventMask.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Iterate all the clients who have registered event masks against
-// particular
-// SBBroadcasters and build up the mask that is for all of them.
-// Type: Method.
-// Args: vBroadcasterClass - (R) The broadcaster to retrieve the mask for.
-// Return: MIuint - Event mask.
-// Throws: None.
-//--
-MIuint CMICmnLLDBDebugger::ClientGetMaskForAllClients(
- const CMIUtilString &vBroadcasterClass) const {
- MIuint mask = 0;
- MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin();
- while (it != m_mapIdToEventMask.end()) {
- const CMIUtilString &rId((*it).first);
- if (rId.find(vBroadcasterClass) != std::string::npos) {
- const MIuint clientsMask = (*it).second;
- mask |= clientsMask;
- }
-
- // Next
- ++it;
- }
-
- return mask;
-}
-
-//++
-// Details: Given the client save its particular event requirements.
-// Type: Method.
-// Args: vClientName - (R) The Client's unique ID.
-// vBroadcasterClass - (R) The SBBroadcaster's class name targeted for
-// the events.
-// vEventMask - (R) The mask of events to listen for.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::ClientSaveMask(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass,
- const MIuint vEventMask) {
- if (vClientName.empty()) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
- return MIstatus::failure;
- }
-
- CMIUtilString strId(vBroadcasterClass);
- strId += vClientName;
-
- ClientRemoveTheirMask(vClientName, vBroadcasterClass);
- MapPairIdToEventMask_t pr(strId, vEventMask);
- m_mapIdToEventMask.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Given the client remove it's particular event requirements.
-// Type: Method.
-// Args: vClientName - (R) The Client's unique ID.
-// vBroadcasterClass - (R) The SBBroadcaster's class name.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::ClientRemoveTheirMask(
- const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass) {
- if (vClientName.empty()) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
- return MIstatus::failure;
- }
-
- CMIUtilString strId(vBroadcasterClass);
- strId += vClientName;
-
- const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
- if (it != m_mapIdToEventMask.end()) {
- m_mapIdToEventMask.erase(it);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the client's event mask used for on a particular
-// SBBroadcaster.
-// Type: Method.
-// Args: vClientName - (R) The Client's unique ID.
-// vBroadcasterClass - (R) The SBBroadcaster's class name.
-// vwEventMask - (W) The client's mask.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::ClientGetTheirMask(
- const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass,
- MIuint &vwEventMask) {
- vwEventMask = 0;
-
- if (vClientName.empty()) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME), vClientName.c_str()));
- return MIstatus::failure;
- }
-
- const CMIUtilString strId(vBroadcasterClass + vClientName);
- const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find(strId);
- if (it != m_mapIdToEventMask.end()) {
- vwEventMask = (*it).second;
- }
-
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED), vClientName.c_str()));
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Momentarily wait for an events being broadcast and inspect those
-// that do
-// come this way. Check if the target should exit event if so start
-// shutting
-// down this thread and the application. Any other events pass on to
-// the
-// Out-of-band handler to further determine what kind of event arrived.
-// This function runs in the thread "MI debugger event".
-// Type: Method.
-// Args: vrbIsAlive - (W) False = yes exit event monitoring thread, true =
-// continue.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive) {
- vrbIsAlive = true;
-
- // Lock the mutex of event queue
- // Note that it should be locked while we are in
- // CMICmnLLDBDebugger::MonitorSBListenerEvents to
- // avoid a race condition with CMICmnLLDBDebugger::WaitForHandleEvent
- std::unique_lock<std::mutex> lock(m_mutexEventQueue);
-
- lldb::SBEvent event;
- const bool bGotEvent = m_lldbListener.GetNextEvent(event);
- if (!bGotEvent) {
- // Notify that we are finished and unlock the mutex of event queue before
- // sleeping
- m_conditionEventQueueEmpty.notify_one();
- lock.unlock();
-
- // Wait a bit to reduce CPU load
- const std::chrono::milliseconds time(1);
- std::this_thread::sleep_for(time);
- return MIstatus::success;
- }
- assert(event.IsValid());
- assert(event.GetBroadcaster().IsValid());
-
- // Debugging
- m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s",
- event.GetBroadcasterClass()));
-
- bool bHandledEvent = false;
- bool bOk = false;
- {
- // Lock Mutex before handling events so that we don't disturb a running cmd
- CMIUtilThreadLock lock(
- CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
- bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event,
- bHandledEvent);
- }
-
- if (!bHandledEvent) {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT),
- event.GetBroadcasterClass()));
- m_pLog->WriteLog(msg);
- }
-
- if (!bOk)
- m_pLog->WriteLog(
- CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
-
- return MIstatus::success;
-}
-
-//++
-// Details: The main worker method for this thread.
-// Type: Method.
-// Args: vrbIsAlive - (W) True = *this thread is working, false = thread has
-// exited.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::ThreadRun(bool &vrbIsAlive) {
- return MonitorSBListenerEvents(vrbIsAlive);
-}
-
-//++
-// Details: Let this thread clean up after itself.
-// Type: Method.
-// Args:
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::ThreadFinish() { return MIstatus::success; }
-
-//++
-// Details: Retrieve *this thread object's name.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLLDBDebugger::ThreadGetName() const {
- return m_constStrThisThreadId;
-}
-
-//++
-// Details: Loads lldb-mi formatters
-// Type: Method.
-// Args: None.
-// Return: true - Functionality succeeded.
-// false - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::LoadMIFormatters(lldb::SBTypeCategory miCategory) {
- if (!MI_add_summary(miCategory, "char", MI_char_summary_provider,
- lldb::eTypeOptionHideValue |
- lldb::eTypeOptionSkipPointers))
- return false;
-
- if (!MI_add_summary(miCategory, "unsigned char", MI_char_summary_provider,
- lldb::eTypeOptionHideValue |
- lldb::eTypeOptionSkipPointers))
- return false;
-
- if (!MI_add_summary(miCategory, "signed char", MI_char_summary_provider,
- lldb::eTypeOptionHideValue |
- lldb::eTypeOptionSkipPointers))
- return false;
-
- return true;
-}
-
-//++
-// Details: Registers lldb-mi custom summary providers
-// Type: Method.
-// Args: None.
-// Return: true - Functionality succeeded.
-// false - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebugger::RegisterMISummaryProviders() {
- static const char *miCategoryName = "lldb-mi";
- lldb::SBTypeCategory miCategory =
- m_lldbDebugger.CreateCategory(miCategoryName);
- if (!miCategory.IsValid())
- return false;
-
- if (!LoadMIFormatters(miCategory)) {
- m_lldbDebugger.DeleteCategory(miCategoryName);
- return false;
- }
- miCategory.SetEnabled(true);
- return true;
-}
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.h b/tools/lldb-mi/MICmnLLDBDebugger.h
deleted file mode 100644
index 29cf9416e153..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebugger.h
+++ /dev/null
@@ -1,134 +0,0 @@
-//===-- MICmnLLDBDebugger.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBEvent.h"
-#include "lldb/API/SBListener.h"
-#include <condition_variable>
-#include <map>
-#include <mutex>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilThreadBaseStd.h"
-
-// Declarations:
-class CMIDriverBase;
-class CMICmnLLDBDebuggerHandleEvents;
-
-//++
-//============================================================================
-// Details: MI proxy/adapter for the LLDB public SBDebugger API. The CMIDriver
-// requires *this object. Command classes make calls on *this object
-// to facilitate their work effort. The instance runs in its own worker
-// thread.
-// A singleton class.
-//--
-class CMICmnLLDBDebugger : public CMICmnBase,
- public CMIUtilThreadActiveObjBase,
- public MI::ISingleton<CMICmnLLDBDebugger> {
- friend class MI::ISingleton<CMICmnLLDBDebugger>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
-
- bool SetDriver(const CMIDriverBase &vClientDriver);
- CMIDriverBase &GetDriver() const;
- lldb::SBDebugger &GetTheDebugger();
- lldb::SBListener &GetTheListener();
- void WaitForHandleEvent();
- bool CheckIfNeedToRebroadcastStopEvent();
- void RebroadcastStopEvent();
-
- // MI Commands can use these functions to listen for events they require
- bool RegisterForEvent(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass,
- const MIuint vEventMask);
- bool UnregisterForEvent(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass);
- bool RegisterForEvent(const CMIUtilString &vClientName,
- const lldb::SBBroadcaster &vBroadcaster,
- const MIuint vEventMask);
- bool UnregisterForEvent(const CMIUtilString &vClientName,
- const lldb::SBBroadcaster &vBroadcaster);
-
- // Overridden:
-public:
- // From CMIUtilThreadActiveObjBase
- const CMIUtilString &ThreadGetName() const override;
-
- // Overridden:
-protected:
- // From CMIUtilThreadActiveObjBase
- bool ThreadRun(bool &vrIsAlive) override;
- bool ThreadFinish() override;
-
- // Typedefs:
-private:
- typedef std::map<CMIUtilString, MIuint> MapBroadcastClassNameToEventMask_t;
- typedef std::pair<CMIUtilString, MIuint>
- MapPairBroadcastClassNameToEventMask_t;
- typedef std::map<CMIUtilString, MIuint> MapIdToEventMask_t;
- typedef std::pair<CMIUtilString, MIuint> MapPairIdToEventMask_t;
-
- // Methods:
-private:
- /* ctor */ CMICmnLLDBDebugger();
- /* ctor */ CMICmnLLDBDebugger(const CMICmnLLDBDebugger &);
- void operator=(const CMICmnLLDBDebugger &);
-
- bool InitSBDebugger();
- bool InitSBListener();
- bool InitStdStreams();
- bool MonitorSBListenerEvents(bool &vrbYesExit);
-
- bool BroadcasterGetMask(const CMIUtilString &vBroadcasterClass,
- MIuint &vEventMask) const;
- bool BroadcasterRemoveMask(const CMIUtilString &vBroadcasterClass);
- bool BroadcasterSaveMask(const CMIUtilString &vBroadcasterClass,
- const MIuint vEventMask);
-
- MIuint
- ClientGetMaskForAllClients(const CMIUtilString &vBroadcasterClass) const;
- bool ClientSaveMask(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass,
- const MIuint vEventMask);
- bool ClientRemoveTheirMask(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass);
- bool ClientGetTheirMask(const CMIUtilString &vClientName,
- const CMIUtilString &vBroadcasterClass,
- MIuint &vwEventMask);
- bool LoadMIFormatters(lldb::SBTypeCategory miCategory);
- bool RegisterMISummaryProviders();
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnLLDBDebugger() override;
-
- // Attributes:
-private:
- CMIDriverBase
- *m_pClientDriver; // The driver that wants to use *this LLDB debugger
- lldb::SBDebugger m_lldbDebugger; // SBDebugger is the primordial object that
- // creates SBTargets and provides access to
- // them
- lldb::SBListener m_lldbListener; // API clients can register its own listener
- // to debugger events
- const CMIUtilString m_constStrThisThreadId;
- MapBroadcastClassNameToEventMask_t m_mapBroadcastClassNameToEventMask;
- MapIdToEventMask_t m_mapIdToEventMask;
- std::mutex m_mutexEventQueue;
- std::condition_variable m_conditionEventQueueEmpty;
- uint32_t m_nLastStopId;
-};
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
deleted file mode 100644
index 60cfd3563dae..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
+++ /dev/null
@@ -1,1883 +0,0 @@
-//===-- MICmnLLDBDebuggerHandleEvents.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBAddress.h"
-#include "lldb/API/SBBreakpoint.h"
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include "lldb/API/SBEvent.h"
-#include "lldb/API/SBProcess.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBThread.h"
-#include "lldb/API/SBUnixSignals.h"
-#include "llvm/Support/Compiler.h"
-#ifdef _WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif // _WIN32
-
-// In-house headers:
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLLDBDebuggerHandleEvents.h"
-#include "MICmnLog.h"
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueList.h"
-#include "MICmnResources.h"
-#include "MICmnStreamStderr.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriver.h"
-#include "MIUtilDebug.h"
-#include "Platform.h"
-
-#include <algorithm>
-
-//++
-// Details: CMICmnLLDBDebuggerHandleEvents constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents() {}
-
-//++
-// Details: CMICmnLLDBDebuggerHandleEvents destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents() {
- Shutdown();
-}
-
-//++
-// Details: Initialize resources for *this broadcaster object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = MIstatus::success;
- m_bSignalsInitialized = false;
- m_SIGINT = 0;
- m_SIGSTOP = 0;
- m_SIGSEGV = 0;
- m_SIGTRAP = 0;
-
- return m_bInitialized;
-}
-
-//++
-// Details: Release resources for *this broadcaster object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Interpret the event object to ascertain the action to take or
-// information to
-// to form and put in a MI Out-of-band record object which is given to
-// stdout.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// vrbHandledEvent - (W) True - event handled, false = not handled.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent,
- bool &vrbHandledEvent) {
- bool bOk = MIstatus::success;
- vrbHandledEvent = false;
-
- if (lldb::SBProcess::EventIsProcessEvent(vEvent)) {
- vrbHandledEvent = true;
- bOk = HandleEventSBProcess(vEvent);
- } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent)) {
- vrbHandledEvent = true;
- bOk = HandleEventSBBreakPoint(vEvent);
- } else if (lldb::SBThread::EventIsThreadEvent(vEvent)) {
- vrbHandledEvent = true;
- bOk = HandleEventSBThread(vEvent);
- } else if (lldb::SBTarget::EventIsTargetEvent(vEvent)) {
- vrbHandledEvent = true;
- bOk = HandleEventSBTarget(vEvent);
- } else if (lldb::SBCommandInterpreter::EventIsCommandInterpreterEvent(
- vEvent)) {
- vrbHandledEvent = true;
- bOk = HandleEventSBCommandInterpreter(vEvent);
- }
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBProcess event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(
- const lldb::SBEvent &vEvent) {
- bool bOk = MIstatus::success;
-
- const char *pEventType = "";
- const MIuint nEventType = vEvent.GetType();
- switch (nEventType) {
- case lldb::SBProcess::eBroadcastBitInterrupt:
- pEventType = "eBroadcastBitInterrupt";
- break;
- case lldb::SBProcess::eBroadcastBitProfileData:
- pEventType = "eBroadcastBitProfileData";
- break;
- case lldb::SBProcess::eBroadcastBitStructuredData:
- pEventType = "eBroadcastBitStructuredData";
- break;
- case lldb::SBProcess::eBroadcastBitStateChanged:
- pEventType = "eBroadcastBitStateChanged";
- bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
- break;
- case lldb::SBProcess::eBroadcastBitSTDERR:
- pEventType = "eBroadcastBitSTDERR";
- bOk = GetProcessStderr();
- break;
- case lldb::SBProcess::eBroadcastBitSTDOUT:
- pEventType = "eBroadcastBitSTDOUT";
- bOk = GetProcessStdout();
- break;
- default: {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
- "SBProcess", (MIuint)nEventType));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
- }
- m_pLog->WriteLog(CMIUtilString::Format(
- "##### An SB Process event occurred: %s", pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBBreakpoint event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(
- const lldb::SBEvent &vEvent) {
- bool bOk = MIstatus::success;
-
- const char *pEventType = "";
- const lldb::BreakpointEventType eEvent =
- lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(vEvent);
- switch (eEvent) {
- case lldb::eBreakpointEventTypeThreadChanged:
- pEventType = "eBreakpointEventTypeThreadChanged";
- break;
- case lldb::eBreakpointEventTypeLocationsRemoved:
- pEventType = "eBreakpointEventTypeLocationsRemoved";
- break;
- case lldb::eBreakpointEventTypeInvalidType:
- pEventType = "eBreakpointEventTypeInvalidType";
- break;
- case lldb::eBreakpointEventTypeLocationsAdded:
- pEventType = "eBreakpointEventTypeLocationsAdded";
- bOk = HandleEventSBBreakpointLocationsAdded(vEvent);
- break;
- case lldb::eBreakpointEventTypeAdded:
- pEventType = "eBreakpointEventTypeAdded";
- bOk = HandleEventSBBreakpointAdded(vEvent);
- break;
- case lldb::eBreakpointEventTypeRemoved:
- pEventType = "eBreakpointEventTypeRemoved";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeLocationsResolved:
- pEventType = "eBreakpointEventTypeLocationsResolved";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeEnabled:
- pEventType = "eBreakpointEventTypeEnabled";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeDisabled:
- pEventType = "eBreakpointEventTypeDisabled";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeCommandChanged:
- pEventType = "eBreakpointEventTypeCommandChanged";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeConditionChanged:
- pEventType = "eBreakpointEventTypeConditionChanged";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeIgnoreChanged:
- pEventType = "eBreakpointEventTypeIgnoreChanged";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- case lldb::eBreakpointEventTypeAutoContinueChanged:
- pEventType = "eBreakpointEventTypeAutoContinueChanged";
- bOk = HandleEventSBBreakpointCmn(vEvent);
- break;
- }
- m_pLog->WriteLog(CMIUtilString::Format(
- "##### An SB Breakpoint event occurred: %s", pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBBreakpoint event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointLocationsAdded(
- const lldb::SBEvent &vEvent) {
- const MIuint nLoc =
- lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(vEvent);
- if (nLoc == 0)
- return MIstatus::success;
-
- lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
- const CMIUtilString plural((nLoc == 1) ? "" : "s");
- const CMIUtilString msg(
- CMIUtilString::Format("%d location%s added to breakpoint %d", nLoc,
- plural.c_str(), brkPt.GetID()));
-
- return TextToStdout(msg);
-}
-
-//++
-// Details: Handle a LLDB SBBreakpoint event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn(
- const lldb::SBEvent &vEvent) {
- lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
- if (!brkPt.IsValid())
- return MIstatus::success;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET),
- "HandleEventSBBreakpointCmn()", brkPt.GetID()));
- return MIstatus::failure;
- }
-
- // CODETAG_LLDB_BREAKPOINT_CREATION
- // This is in a worker thread
- // Add more breakpoint information or overwrite existing information
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
- if (!rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND),
- "HandleEventSBBreakpointCmn()", brkPt.GetID()));
- return MIstatus::failure;
- }
- sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
- sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
- sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
- sBrkPtInfo.m_strOptThrdGrp = "";
- sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
- sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
- sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
- sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
- sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
- sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
- sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
- sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
-
- // MI print
- // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
- // PRIx64 "\",
- // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
- CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
- "HandleEventSBBreakpointCmn()"));
- return MIstatus::failure;
- }
-
- const CMICmnMIValueResult miValueResultC("bkpt", miValueTuple);
- const CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResultC);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBBreakpoint added event.
-// Add more breakpoint information or overwrite existing information.
-// Normally a break point session info objects exists by now when an MI
-// command
-// was issued to insert a break so the retrieval would normally always
-// succeed
-// however should a user type "b main" into a console then LLDB will
-// create a
-// breakpoint directly, hence no MI command, hence no previous record
-// of the
-// breakpoint so RecordBrkPtInfoGet() will fail. We still get the event
-// though
-// so need to create a breakpoint info object here and send appropriate
-// MI
-// response.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(
- const lldb::SBEvent &vEvent) {
- lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent(vEvent);
- if (!brkPt.IsValid())
- return MIstatus::success;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.GetBrkPtInfo(brkPt, sBrkPtInfo)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET),
- "HandleEventSBBreakpointAdded()", brkPt.GetID()));
- return MIstatus::failure;
- }
-
- // CODETAG_LLDB_BREAKPOINT_CREATION
- // This is in a worker thread
- CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
- const bool bBrkPtExistAlready =
- rSessionInfo.RecordBrkPtInfoGet(brkPt.GetID(), sBrkPtInfoRec);
- if (bBrkPtExistAlready) {
- // Update breakpoint information object
- sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
- sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
- sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
- sBrkPtInfo.m_strOptThrdGrp.clear();
- sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
- sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
- sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
- sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
- sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
- sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
- sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
- sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
- } else {
- // Create a breakpoint information object
- sBrkPtInfo.m_bDisp = brkPt.IsOneShot();
- sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
- sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
- sBrkPtInfo.m_strOptThrdGrp.clear();
- sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format(
- "%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine);
- sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
- sBrkPtInfo.m_bPending = false;
- const char *pStrCondition = brkPt.GetCondition();
- sBrkPtInfo.m_bCondition = pStrCondition != nullptr;
- sBrkPtInfo.m_strCondition =
- (pStrCondition != nullptr) ? pStrCondition : "??";
- sBrkPtInfo.m_bBrkPtThreadId = brkPt.GetThreadID() != 0;
- sBrkPtInfo.m_nBrkPtThreadId = brkPt.GetThreadID();
- }
-
- CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
- "HandleEventSBBreakpointAdded()"));
- return MIstatus::failure;
- }
-
- bool bOk = MIstatus::success;
- if (bBrkPtExistAlready) {
- // MI print
- // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
- // PRIx64
- // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
- const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
- const CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- } else {
- // CODETAG_LLDB_BRKPT_ID_MAX
- if (brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED),
- "HandleEventSBBreakpointAdded()", rSessionInfo.m_nBrkPointCntMax,
- sBrkPtInfo.m_id));
- return MIstatus::failure;
- }
- if (!rSessionInfo.RecordBrkPtInfo(brkPt.GetID(), sBrkPtInfo)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET),
- "HandleEventSBBreakpointAdded()", sBrkPtInfo.m_id));
- return MIstatus::failure;
- }
-
- // MI print
- // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016"
- // PRIx64
- // "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
- const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
- const CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- }
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBThread event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread(
- const lldb::SBEvent &vEvent) {
- if (!ChkForStateChanges())
- return MIstatus::failure;
-
- bool bOk = MIstatus::success;
- const char *pEventType = "";
- const MIuint nEventType = vEvent.GetType();
- switch (nEventType) {
- case lldb::SBThread::eBroadcastBitStackChanged:
- pEventType = "eBroadcastBitStackChanged";
- bOk = HandleEventSBThreadBitStackChanged(vEvent);
- break;
- case lldb::SBThread::eBroadcastBitThreadSuspended:
- pEventType = "eBroadcastBitThreadSuspended";
- bOk = HandleEventSBThreadSuspended(vEvent);
- break;
- case lldb::SBThread::eBroadcastBitThreadResumed:
- pEventType = "eBroadcastBitThreadResumed";
- break;
- case lldb::SBThread::eBroadcastBitSelectedFrameChanged:
- pEventType = "eBroadcastBitSelectedFrameChanged";
- break;
- case lldb::SBThread::eBroadcastBitThreadSelected:
- pEventType = "eBroadcastBitThreadSelected";
- break;
- default: {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
- "SBThread", (MIuint)nEventType));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
- }
- m_pLog->WriteLog(CMIUtilString::Format("##### An SBThread event occurred: %s",
- pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBThread event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadSuspended(
- const lldb::SBEvent &vEvent) {
- lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
- if (!thread.IsValid())
- return MIstatus::success;
-
- const lldb::StopReason eStopReason = thread.GetStopReason();
- if (eStopReason != lldb::eStopReasonSignal)
- return MIstatus::success;
-
- // MI print "@thread=%d,signal=%lld"
- const MIuint64 nId = thread.GetStopReasonDataAtIndex(0);
- const CMIUtilString strThread(
- CMIUtilString::Format("%d", thread.GetThreadID()));
- const CMICmnMIValueConst miValueConst(strThread);
- const CMICmnMIValueResult miValueResult("thread", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Thread, miValueResult);
- const CMIUtilString strSignal(CMIUtilString::Format("%lld", nId));
- const CMICmnMIValueConst miValueConst2(strSignal);
- const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- return MiOutOfBandRecordToStdout(miOutOfBandRecord);
-}
-
-//++
-// Details: Handle a LLDB SBThread event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged(
- const lldb::SBEvent &vEvent) {
- lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent(vEvent);
- if (!thread.IsValid())
- return MIstatus::success;
-
- lldb::SBStream streamOut;
- const bool bOk = thread.GetStatus(streamOut);
- return bOk && TextToStdout(streamOut.GetData());
-}
-
-//++
-// Details: Handle a LLDB SBTarget event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(
- const lldb::SBEvent &vEvent) {
- if (!ChkForStateChanges())
- return MIstatus::failure;
-
- bool bOk = MIstatus::success;
- const char *pEventType = "";
- const MIuint nEventType = vEvent.GetType();
- switch (nEventType) {
- case lldb::SBTarget::eBroadcastBitBreakpointChanged:
- pEventType = "eBroadcastBitBreakpointChanged";
- break;
- case lldb::SBTarget::eBroadcastBitModulesLoaded:
- pEventType = "eBroadcastBitModulesLoaded";
- bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
- break;
- case lldb::SBTarget::eBroadcastBitModulesUnloaded:
- pEventType = "eBroadcastBitModulesUnloaded";
- bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
- break;
- case lldb::SBTarget::eBroadcastBitWatchpointChanged:
- pEventType = "eBroadcastBitWatchpointChanged";
- break;
- case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
- pEventType = "eBroadcastBitSymbolsLoaded";
- break;
- default: {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
- "SBTarget", (MIuint)nEventType));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
- }
- m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s",
- pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Print to stdout
-// "=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
-// PRIx64"\""
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(
- const lldb::SBEvent &vEvent) {
- bool bOk = MIstatus::failure;
- const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
- for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
- const lldb::SBModule sbModule =
- lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded);
- const bool bWithExtraFields = true;
- bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- if (!bOk)
- break;
- }
-
- return bOk;
-}
-
-//++
-// Details: Print to stdout
-// "=library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
-// PRIx64"\""
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::
- HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent) {
- bool bOk = MIstatus::failure;
- const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
- for (MIuint nIndex = 0; nIndex < nSize; ++nIndex) {
- const lldb::SBModule sbModule =
- lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded);
- const bool bWithExtraFields = false;
- bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- if (!bOk)
- break;
- }
-
- return bOk;
-}
-
-//++
-// Details: Build module information for =library-loaded/=library-unloaded:
-// "id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016"
-// PRIx64"\""
-// Type: Method.
-// Args: vwrMiValueList - (W) MI value list object.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(
- const lldb::SBModule &vModule, const bool vbWithExtraFields,
- CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord) {
- bool bOk = MIstatus::success;
-
- // First, build standard fields:
- // Build "id" field
- std::unique_ptr<char[]> apPath(new char[PATH_MAX]);
- vModule.GetFileSpec().GetPath(apPath.get(), PATH_MAX);
- const CMIUtilString strTargetPath(apPath.get());
- const CMICmnMIValueConst miValueConst(strTargetPath.AddSlashes());
- const CMICmnMIValueResult miValueResult("id", miValueConst);
- vwrMiOutOfBandRecord.Add(miValueResult);
- // Build "target-name" field
- const CMICmnMIValueConst miValueConst2(strTargetPath.AddSlashes());
- const CMICmnMIValueResult miValueResult2("target-name", miValueConst2);
- vwrMiOutOfBandRecord.Add(miValueResult2);
- // Build "host-name" field
- vModule.GetPlatformFileSpec().GetPath(apPath.get(), PATH_MAX);
- const CMIUtilString strHostPath(apPath.get());
- const CMICmnMIValueConst miValueConst3(strHostPath.AddSlashes());
- const CMICmnMIValueResult miValueResult3("host-name", miValueConst3);
- vwrMiOutOfBandRecord.Add(miValueResult3);
-
- // Then build extra fields if needed:
- if (vbWithExtraFields) {
- // Build "symbols-loaded" field
- vModule.GetSymbolFileSpec().GetPath(apPath.get(), PATH_MAX);
- const CMIUtilString strSymbolsPath(apPath.get());
- const bool bSymbolsLoaded =
- !CMIUtilString::Compare(strHostPath, strSymbolsPath);
- const CMICmnMIValueConst miValueConst4(
- CMIUtilString::Format("%d", bSymbolsLoaded));
- const CMICmnMIValueResult miValueResult4("symbols-loaded", miValueConst4);
- vwrMiOutOfBandRecord.Add(miValueResult4);
- // Build "symbols-path" field
- if (bSymbolsLoaded) {
- const CMICmnMIValueConst miValueConst5(strSymbolsPath.AddSlashes());
- const CMICmnMIValueResult miValueResult5("symbols-path", miValueConst5);
- vwrMiOutOfBandRecord.Add(miValueResult5);
- }
- // Build "loaded_addr" field
- lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- const lldb::addr_t nLoadAddress(
- sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
- const CMIUtilString strLoadedAddr(
- nLoadAddress != LLDB_INVALID_ADDRESS
- ? CMIUtilString::Format("0x%016" PRIx64, nLoadAddress)
- : "-");
- const CMICmnMIValueConst miValueConst6(strLoadedAddr);
- const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
- vwrMiOutOfBandRecord.Add(miValueResult6);
-
- // Build "size" field
- lldb::SBSection sbSection = sbAddress.GetSection();
- const CMIUtilString strSize(
- CMIUtilString::Format("%" PRIu64, sbSection.GetByteSize()));
- const CMICmnMIValueConst miValueConst7(strSize);
- const CMICmnMIValueResult miValueResult7("size", miValueConst7);
- vwrMiOutOfBandRecord.Add(miValueResult7);
- }
-
- return bOk;
-}
-
-//++
-// Details: Handle a LLDB SBCommandInterpreter event.
-// Type: Method.
-// Args: vEvent - (R) An LLDB command interpreter event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(
- const lldb::SBEvent &vEvent) {
- // This function is not used
- // *** This function is under development
-
- const char *pEventType = "";
- const MIuint nEventType = vEvent.GetType();
- switch (nEventType) {
- case lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit:
- pEventType = "eBroadcastBitThreadShouldExit";
- // ToDo: IOR: Reminder to maybe handle this here
- // const MIuint nEventType = event.GetType();
- // if (nEventType &
- // lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit)
- //{
- // m_pClientDriver->SetExitApplicationFlag();
- // vrbYesExit = true;
- // return MIstatus::success;
- //}
- break;
- case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
- pEventType = "eBroadcastBitResetPrompt";
- break;
- case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived: {
- pEventType = "eBroadcastBitQuitCommandReceived";
- const bool bForceExit = true;
- CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(
- bForceExit);
- break;
- }
- case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
- pEventType = "eBroadcastBitAsynchronousOutputData";
- break;
- case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData:
- pEventType = "eBroadcastBitAsynchronousErrorData";
- break;
- default: {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
- "SBCommandInterpreter", (MIuint)nEventType));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
- }
- m_pLog->WriteLog(CMIUtilString::Format(
- "##### An SBCommandInterpreter event occurred: %s", pEventType));
-
- return MIstatus::success;
-}
-
-//++
-// Details: Handle SBProcess event eBroadcastBitStateChanged.
-// Type: Method.
-// Args: vEvent - (R) An LLDB event object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(
- const lldb::SBEvent &vEvent) {
- // Make sure the program hasn't been auto-restarted:
- if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
- return MIstatus::success;
-
- bool bOk = ChkForStateChanges();
- bOk = bOk && GetProcessStdout();
- bOk = bOk && GetProcessStderr();
- if (!bOk)
- return MIstatus::failure;
-
- // Something changed in the process; get the event and report the process's
- // current
- // status and location
- const lldb::StateType eEventState =
- lldb::SBProcess::GetStateFromEvent(vEvent);
- if (eEventState == lldb::eStateInvalid)
- return MIstatus::success;
-
- lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(vEvent);
- if (!process.IsValid()) {
- const CMIUtilString msg(CMIUtilString::Format(
- MIRSRC(IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID), "SBProcess",
- "HandleProcessEventBroadcastBitStateChanged()"));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
-
- bool bShouldBrk = true;
- const char *pEventType = "";
- switch (eEventState) {
- case lldb::eStateUnloaded:
- pEventType = "eStateUnloaded";
- break;
- case lldb::eStateConnected:
- pEventType = "eStateConnected";
- break;
- case lldb::eStateAttaching:
- pEventType = "eStateAttaching";
- break;
- case lldb::eStateLaunching:
- pEventType = "eStateLaunching";
- break;
- case lldb::eStateStopped:
- pEventType = "eStateStopped";
- bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk);
- if (bShouldBrk)
- break;
- LLVM_FALLTHROUGH;
- case lldb::eStateCrashed:
- case lldb::eStateSuspended:
- pEventType = "eStateSuspended";
- bOk = HandleProcessEventStateSuspended(vEvent);
- break;
- case lldb::eStateRunning:
- pEventType = "eStateRunning";
- bOk = HandleProcessEventStateRunning();
- break;
- case lldb::eStateStepping:
- pEventType = "eStateStepping";
- break;
- case lldb::eStateDetached:
- pEventType = "eStateDetached";
- break;
- case lldb::eStateExited:
- // Don't exit from lldb-mi here. We should be able to re-run target.
- pEventType = "eStateExited";
- bOk = HandleProcessEventStateExited();
- break;
- default: {
- const CMIUtilString msg(CMIUtilString::Format(
- MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT),
- "SBProcess BroadcastBitStateChanged", (MIuint)eEventState));
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
- }
-
- // ToDo: Remove when finished coding application
- m_pLog->WriteLog(CMIUtilString::Format(
- "##### An SB Process event BroadcastBitStateChanged occurred: %s",
- pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Asynchronous event handler for LLDB Process state suspended.
-// Type: Method.
-// Args: vEvent - (R) An LLDB event object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(
- const lldb::SBEvent &vEvent) {
- bool bOk = MIstatus::success;
- lldb::SBStream streamOut;
- lldb::SBDebugger &rDebugger =
- CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBTarget target = sbProcess.GetTarget();
- if (rDebugger.GetSelectedTarget() == target) {
- if (!UpdateSelectedThread())
- return MIstatus::failure;
- sbProcess.GetDescription(streamOut);
- // Add a delimiter between process' and threads' info.
- streamOut.Printf("\n");
- for (uint32_t i = 0, e = sbProcess.GetNumThreads(); i < e; ++i) {
- const lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
- if (!thread.IsValid())
- continue;
- thread.GetDescription(streamOut);
- }
- bOk = TextToStdout(streamOut.GetData());
- } else {
- const MIuint nTargetIndex = rDebugger.GetIndexOfTarget(target);
- if (nTargetIndex != UINT_MAX)
- streamOut.Printf("Target %" PRIu64 ": (", (uint64_t)nTargetIndex);
- else
- streamOut.Printf("Target <unknown index>: (");
- target.GetDescription(streamOut, lldb::eDescriptionLevelBrief);
- streamOut.Printf(") stopped.\n");
- bOk = TextToStdout(streamOut.GetData());
- }
-
- return bOk;
-}
-
-//++
-// Details: Print to stdout MI formatted text to indicate process stopped.
-// Type: Method.
-// Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(
- const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk) {
- if (!UpdateSelectedThread())
- return MIstatus::failure;
-
- const char *pEventType = "";
- bool bOk = MIstatus::success;
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- const lldb::StopReason eStoppedReason =
- sbProcess.GetSelectedThread().GetStopReason();
- switch (eStoppedReason) {
- case lldb::eStopReasonInvalid:
- pEventType = "eStopReasonInvalid";
- vwrbShouldBrk = false;
- break;
- case lldb::eStopReasonNone:
- pEventType = "eStopReasonNone";
- break;
- case lldb::eStopReasonTrace:
- pEventType = "eStopReasonTrace";
- bOk = HandleProcessEventStopReasonTrace();
- break;
- case lldb::eStopReasonBreakpoint:
- pEventType = "eStopReasonBreakpoint";
- bOk = HandleProcessEventStopReasonBreakpoint();
- break;
- case lldb::eStopReasonWatchpoint:
- pEventType = "eStopReasonWatchpoint";
- break;
- case lldb::eStopReasonSignal:
- pEventType = "eStopReasonSignal";
- bOk = HandleProcessEventStopSignal(vrEvent);
- break;
- case lldb::eStopReasonException:
- pEventType = "eStopReasonException";
- bOk = HandleProcessEventStopException();
- break;
- case lldb::eStopReasonExec:
- pEventType = "eStopReasonExec";
- break;
- case lldb::eStopReasonPlanComplete:
- pEventType = "eStopReasonPlanComplete";
- bOk = HandleProcessEventStopReasonTrace();
- break;
- case lldb::eStopReasonThreadExiting:
- pEventType = "eStopReasonThreadExiting";
- break;
- case lldb::eStopReasonInstrumentation:
- pEventType = "eStopReasonInstrumentation";
- break;
- }
-
- // ToDo: Remove when finished coding application
- m_pLog->WriteLog(CMIUtilString::Format(
- "##### An SB Process event stop state occurred: %s", pEventType));
-
- return bOk;
-}
-
-//++
-// Details: Asynchronous event handler for LLDB Process stop signal.
-// Type: Method.
-// Args: vrEvent - (R) An LLDB broadcast event.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(
- const lldb::SBEvent &vrEvent) {
- bool bOk = MIstatus::success;
-
- InitializeSignals();
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- const MIuint64 nStopReason =
- sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
- const bool bInterrupted = lldb::SBProcess::GetInterruptedFromEvent(vrEvent);
- if (nStopReason == m_SIGINT || (nStopReason == m_SIGSTOP && bInterrupted)) {
- // MI print
- // "*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("SIGINT");
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("Interrupt");
- const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
- const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
- miOutOfBandRecord.Add(miValueResult4);
- const CMIUtilString strThreadId(CMIUtilString::Format(
- "%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
- const CMICmnMIValueConst miValueConst5(strThreadId);
- const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
- miOutOfBandRecord.Add(miValueResult5);
- const CMICmnMIValueConst miValueConst6("all");
- const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
- miOutOfBandRecord.Add(miValueResult6);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- } else if (nStopReason == m_SIGSTOP) {
- // MI print
- // "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("SIGSTOP");
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("Stop");
- const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
- const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
- miOutOfBandRecord.Add(miValueResult4);
- const CMIUtilString strThreadId(CMIUtilString::Format(
- "%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
- const CMICmnMIValueConst miValueConst5(strThreadId);
- const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
- miOutOfBandRecord.Add(miValueResult5);
- const CMICmnMIValueConst miValueConst6("all");
- const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
- miOutOfBandRecord.Add(miValueResult6);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- } else if (nStopReason == m_SIGSEGV) {
- // MI print
- // "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation
- // fault\",thread-id=\"%d\",frame={%s}"
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("SIGSEGV");
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("Segmentation fault");
- const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
- const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
- miOutOfBandRecord.Add(miValueResult4);
- const CMIUtilString strThreadId(CMIUtilString::Format(
- "%d", sbProcess.GetSelectedThread().GetIndexID()));
- const CMICmnMIValueConst miValueConst5(strThreadId);
- const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
- miOutOfBandRecord.Add(miValueResult5);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- // Note no "(gdb)" output here
- } else if (nStopReason == m_SIGTRAP) {
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- const MIuint nFrames = thread.GetNumFrames();
- if (nFrames > 0) {
- lldb::SBFrame frame = thread.GetFrameAtIndex(0);
- const char *pFnName = frame.GetFunctionName();
- if (pFnName != nullptr) {
- const CMIUtilString fnName = CMIUtilString(pFnName);
- static const CMIUtilString threadCloneFn =
- CMIUtilString("__pthread_clone");
-
- if (CMIUtilString::Compare(threadCloneFn, fnName)) {
- if (sbProcess.IsValid())
- sbProcess.Continue();
- }
- }
- }
- } else {
- // MI print
- // "*stopped,reason=\"signal-received\",signal-name=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
- // MI print
- // "*stopped,reason=\"signal-received\",signal=\"%d\",thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- lldb::SBUnixSignals sbUnixSignals = sbProcess.GetUnixSignals();
- const char *pSignal = sbUnixSignals.GetSignalAsCString(nStopReason);
- if (pSignal) {
- const CMICmnMIValueConst miValueConst2(pSignal);
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- } else {
- const CMIUtilString strSignal(
- CMIUtilString::Format("%" PRIu64, nStopReason));
- const CMICmnMIValueConst miValueConst2(strSignal);
- const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- }
- const CMIUtilString strThreadId(CMIUtilString::Format(
- "%d", sbProcess.GetSelectedThread().GetIndexID()));
- const CMICmnMIValueConst miValueConst3(strThreadId);
- const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("all");
- const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
- miOutOfBandRecord.Add(miValueResult4);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- }
- return bOk;
-}
-
-//++
-// Details: Asynchronous event handler for LLDB Process stop exception.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopException() {
- const lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBThread sbThread = sbProcess.GetSelectedThread();
- const size_t nStopDescriptionLen = sbThread.GetStopDescription(nullptr, 0);
- std::unique_ptr<char[]> apStopDescription(new char[nStopDescriptionLen]);
- sbThread.GetStopDescription(apStopDescription.get(), nStopDescriptionLen);
-
- // MI print
- // "*stopped,reason=\"exception-received\",exception=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("exception-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMIUtilString strReason(apStopDescription.get());
- const CMICmnMIValueConst miValueConst2(strReason);
- const CMICmnMIValueResult miValueResult2("exception", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- const CMIUtilString strThreadId(
- CMIUtilString::Format("%d", sbThread.GetIndexID()));
- const CMICmnMIValueConst miValueConst3(strThreadId);
- const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("all");
- const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
- miOutOfBandRecord.Add(miValueResult4);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- return bOk;
-}
-
-//++
-// Details: Form partial MI response in a MI value tuple object.
-// Type: Method.
-// Args: vwrMiValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(
- CMICmnMIValueTuple &vwrMiValueTuple) {
- CMIUtilString strThreadFrame;
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- const MIuint nFrame = thread.GetNumFrames();
- if (nFrame == 0) {
- // MI print
- // "addr=\"??\",func=\"??\",file=\"??\",fullname=\"??\",line=\"??\""
- const CMICmnMIValueConst miValueConst("??");
- const CMICmnMIValueResult miValueResult("addr", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueResult miValueResult2("func", miValueConst);
- miValueTuple.Add(miValueResult2);
- const CMICmnMIValueResult miValueResult4("file", miValueConst);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueResult miValueResult5("fullname", miValueConst);
- miValueTuple.Add(miValueResult5);
- const CMICmnMIValueResult miValueResult6("line", miValueConst);
- miValueTuple.Add(miValueResult6);
-
- vwrMiValueTuple = miValueTuple;
-
- return MIstatus::success;
- }
-
- CMICmnMIValueTuple miValueTuple;
- if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(
- thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
- miValueTuple)) {
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE),
- "MiHelpGetCurrentThreadFrame()"));
- return MIstatus::failure;
- }
-
- vwrMiValueTuple = miValueTuple;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Asynchronous event handler for LLDB Process stop reason breakpoint.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint() {
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) {
- const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE),
- "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str()));
- return MIstatus::failure;
- }
-
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- const MIuint64 brkPtId =
- sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
- lldb::SBBreakpoint brkPt =
- CMICmnLLDBDebugSessionInfo::Instance().GetTarget().GetBreakpointAtIndex(
- (MIuint)brkPtId);
-
- return MiStoppedAtBreakPoint(brkPtId, brkPt);
-}
-
-//++
-// Details: Form the MI Out-of-band response for stopped reason on hitting a
-// break point.
-// Type: Method.
-// Args: vBrkPtId - (R) The LLDB break point's ID
-// vBrkPt - (R) THe LLDB break point object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(
- const MIuint64 vBrkPtId, const lldb::SBBreakpoint &vBrkPt) {
- bool bOk = MIstatus::success;
-
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- const MIuint nFrame = thread.GetNumFrames();
- if (nFrame == 0) {
- // MI print
- // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={},thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("breakpoint-hit");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("del");
- const CMICmnMIValueResult miValueResult2("disp", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
- const CMICmnMIValueConst miValueConst3(strBkp);
- CMICmnMIValueResult miValueResult3("bkptno", miValueConst3);
- miOutOfBandRecord.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("{}");
- const CMICmnMIValueResult miValueResult4("frame", miValueConst4);
- miOutOfBandRecord.Add(miValueResult4);
- const CMIUtilString strThreadId(
- CMIUtilString::Format("%d", vBrkPt.GetThreadIndex()));
- const CMICmnMIValueConst miValueConst5(strThreadId);
- const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
- miOutOfBandRecord.Add(miValueResult5);
- const CMICmnMIValueConst miValueConst6("all");
- const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
- miOutOfBandRecord.Add(miValueResult6);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- return bOk;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- // MI print
- // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016"
- // PRIx64
- // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("breakpoint-hit");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConstA("del");
- const CMICmnMIValueResult miValueResultA("disp", miValueConstA);
- miOutOfBandRecord.Add(miValueResultA);
- const CMIUtilString strBkp(CMIUtilString::Format("%d", vBrkPtId));
- const CMICmnMIValueConst miValueConstB(strBkp);
- CMICmnMIValueResult miValueResultB("bkptno", miValueConstB);
- miOutOfBandRecord.Add(miValueResultB);
-
- // frame={addr=\"0x%016" PRIx64
- // "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
- if (bOk) {
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk &&
- rSessionInfo.MIResponseFormFrameInfo(
- thread, 0,
- CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
- miValueTuple);
- const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
- miOutOfBandRecord.Add(miValueResult8);
- }
-
- // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
- if (bOk) {
- const CMIUtilString strThreadId(
- CMIUtilString::Format("%d", thread.GetIndexID()));
- const CMICmnMIValueConst miValueConst8(strThreadId);
- const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
- miOutOfBandRecord.Add(miValueResult8);
- }
- if (bOk) {
- const CMICmnMIValueConst miValueConst9("all");
- const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
- miOutOfBandRecord.Add(miValueResult9);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Asynchronous event handler for LLDB Process stop reason trace.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace() {
- bool bOk = true;
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- const MIuint nFrame = thread.GetNumFrames();
- if (nFrame == 0) {
- // MI print "*stopped,reason=\"trace\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("trace");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("all");
- const CMICmnMIValueResult miValueResult2("stopped-threads", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- return bOk;
- }
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
-
- // MI print
- // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64
- // "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
-
- // Function args
- CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormFrameInfo(
- thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments,
- miValueTuple))
- return MIstatus::failure;
-
- const CMICmnMIValueConst miValueConst("end-stepping-range");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
- miOutOfBandRecord.Add(miValueResult2);
-
- // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
- const CMIUtilString strThreadId(
- CMIUtilString::Format("%d", thread.GetIndexID()));
- const CMICmnMIValueConst miValueConst8(strThreadId);
- const CMICmnMIValueResult miValueResult8("thread-id", miValueConst8);
- miOutOfBandRecord.Add(miValueResult8);
-
- const CMICmnMIValueConst miValueConst9("all");
- const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
- miOutOfBandRecord.Add(miValueResult9);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- return bOk;
-}
-
-//++
-// Details: Asynchronous function update selected thread.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread() {
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
- .GetDebugger()
- .GetSelectedTarget()
- .GetProcess();
- if (!process.IsValid())
- return MIstatus::success;
-
- lldb::SBThread currentThread = process.GetSelectedThread();
- lldb::SBThread thread;
- const lldb::StopReason eCurrentThreadStoppedReason =
- currentThread.GetStopReason();
- if (!currentThread.IsValid() ||
- (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) ||
- (eCurrentThreadStoppedReason == lldb::eStopReasonNone)) {
- // Prefer a thread that has just completed its plan over another thread as
- // current thread
- lldb::SBThread planThread;
- lldb::SBThread otherThread;
- const size_t nThread = process.GetNumThreads();
- for (MIuint i = 0; i < nThread; i++) {
- // GetThreadAtIndex() uses a base 0 index
- // GetThreadByIndexID() uses a base 1 index
- thread = process.GetThreadAtIndex(i);
- const lldb::StopReason eThreadStopReason = thread.GetStopReason();
- switch (eThreadStopReason) {
- case lldb::eStopReasonTrace:
- case lldb::eStopReasonBreakpoint:
- case lldb::eStopReasonWatchpoint:
- case lldb::eStopReasonSignal:
- case lldb::eStopReasonException:
- if (!otherThread.IsValid())
- otherThread = thread;
- break;
- case lldb::eStopReasonPlanComplete:
- if (!planThread.IsValid())
- planThread = thread;
- break;
- case lldb::eStopReasonInvalid:
- case lldb::eStopReasonNone:
- default:
- break;
- }
- }
- if (planThread.IsValid())
- process.SetSelectedThread(planThread);
- else if (otherThread.IsValid())
- process.SetSelectedThread(otherThread);
- else {
- if (currentThread.IsValid())
- thread = currentThread;
- else
- thread = process.GetThreadAtIndex(0);
-
- if (thread.IsValid())
- process.SetSelectedThread(thread);
- }
- } // if( !currentThread.IsValid() || (eCurrentThreadStoppedReason ==
- // lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason ==
- // lldb::eStopReasonNone) )
-
- return MIstatus::success;
-}
-
-//++
-// Details: Print to stdout "*running,thread-id=\"all\"", "(gdb)".
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning() {
- CMICmnMIValueConst miValueConst("all");
- CMICmnMIValueResult miValueResult("thread-id", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- return bOk;
-}
-
-//++
-// Details: Print to stdout "=thread-exited,id=\"%ld\",group-id=\"i1\"",
-// "=thread-group-exited,id=\"i1\",exit-code=\"0\""),
-// "*stopped,reason=\"exited-normally\"",
-// "(gdb)"
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited() {
- const CMIUtilString strId(CMIUtilString::Format("%ld", 1));
- CMICmnMIValueConst miValueConst(strId);
- CMICmnMIValueResult miValueResult("id", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
- CMICmnMIValueConst miValueConst2("i1");
- CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
- miOutOfBandRecord.Add(miValueResult2);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- if (bOk) {
- CMICmnMIValueConst miValueConst3("i1");
- CMICmnMIValueResult miValueResult3("id", miValueConst3);
- CMICmnMIOutOfBandRecord miOutOfBandRecord2(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult3);
- CMICmnMIValueConst miValueConst2("0");
- CMICmnMIValueResult miValueResult2("exit-code", miValueConst2);
- miOutOfBandRecord2.Add(miValueResult2);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord2);
- }
- if (bOk) {
- CMICmnMIValueConst miValueConst4("exited-normally");
- CMICmnMIValueResult miValueResult4("reason", miValueConst4);
- CMICmnMIOutOfBandRecord miOutOfBandRecord3(
- CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4);
- bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord3);
- }
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- return bOk;
-}
-
-//++
-// Details: Drain all stdout so we don't see any output come after we print our
-// prompts.
-// The process has stuff waiting for stdout; get it and write it out to
-// the
-// appropriate place.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::GetProcessStdout() {
- CMIUtilString text;
- std::unique_ptr<char[]> apStdoutBuffer(new char[1024]);
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
- .GetDebugger()
- .GetSelectedTarget()
- .GetProcess();
- while (1) {
- const size_t nBytes = process.GetSTDOUT(apStdoutBuffer.get(), 1024);
- text.append(apStdoutBuffer.get(), nBytes);
-
- while (1) {
- const size_t nNewLine = text.find('\n');
- if (nNewLine == std::string::npos)
- break;
-
- const CMIUtilString line(text.substr(0, nNewLine + 1));
- text.erase(0, nNewLine + 1);
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
- const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- if (!bOk)
- return MIstatus::failure;
- }
-
- if (nBytes == 0) {
- if (!text.empty()) {
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
- miValueConst);
- return MiOutOfBandRecordToStdout(miOutOfBandRecord);
- }
- break;
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Drain all stderr so we don't see any output come after we print our
-// prompts.
-// The process has stuff waiting for stderr; get it and write it out to
-// the
-// appropriate place.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::GetProcessStderr() {
- CMIUtilString text;
- std::unique_ptr<char[]> apStderrBuffer(new char[1024]);
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance()
- .GetDebugger()
- .GetSelectedTarget()
- .GetProcess();
- while (1) {
- const size_t nBytes = process.GetSTDERR(apStderrBuffer.get(), 1024);
- text.append(apStderrBuffer.get(), nBytes);
-
- while (1) {
- const size_t nNewLine = text.find('\n');
- if (nNewLine == std::string::npos)
- break;
-
- const CMIUtilString line(text.substr(0, nNewLine + 1));
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
- const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- if (!bOk)
- return MIstatus::failure;
- }
-
- if (nBytes == 0) {
- if (!text.empty()) {
- const bool bEscapeQuotes(true);
- CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
- CMICmnMIOutOfBandRecord miOutOfBandRecord(
- CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput,
- miValueConst);
- return MiOutOfBandRecordToStdout(miOutOfBandRecord);
- }
- break;
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Asynchronous event function check for state changes.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges() {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- if (!sbProcess.IsValid())
- return MIstatus::success;
-
- // Check for created threads
- const MIuint nThread = sbProcess.GetNumThreads();
- for (MIuint i = 0; i < nThread; i++) {
- // GetThreadAtIndex() uses a base 0 index
- // GetThreadByIndexID() uses a base 1 index
- lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
- if (!thread.IsValid())
- continue;
-
- const MIuint threadIndexID = thread.GetIndexID();
- const bool bFound =
- std::find(rSessionInfo.m_vecActiveThreadId.cbegin(),
- rSessionInfo.m_vecActiveThreadId.cend(),
- threadIndexID) != rSessionInfo.m_vecActiveThreadId.end();
- if (!bFound) {
- rSessionInfo.m_vecActiveThreadId.push_back(threadIndexID);
-
- // Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
- const CMIUtilString strValue(CMIUtilString::Format("%d", threadIndexID));
- const CMICmnMIValueConst miValueConst(strValue);
- const CMICmnMIValueResult miValueResult("id", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult);
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
- miOutOfBand.Add(miValueResult2);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
- if (!bOk)
- return MIstatus::failure;
- }
- }
-
- lldb::SBThread currentThread = sbProcess.GetSelectedThread();
- if (currentThread.IsValid()) {
- const MIuint currentThreadIndexID = currentThread.GetIndexID();
- if (rSessionInfo.m_currentSelectedThread != currentThreadIndexID) {
- rSessionInfo.m_currentSelectedThread = currentThreadIndexID;
-
- // Form MI "=thread-selected,id=\"%d\""
- const CMIUtilString strValue(
- CMIUtilString::Format("%d", currentThreadIndexID));
- const CMICmnMIValueConst miValueConst(strValue);
- const CMICmnMIValueResult miValueResult("id", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult);
- if (!MiOutOfBandRecordToStdout(miOutOfBand))
- return MIstatus::failure;
- }
- }
-
- // Check for invalid (removed) threads
- CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::iterator it =
- rSessionInfo.m_vecActiveThreadId.begin();
- while (it != rSessionInfo.m_vecActiveThreadId.end()) {
- const MIuint threadIndexID = *it;
- lldb::SBThread thread = sbProcess.GetThreadByIndexID(threadIndexID);
- if (!thread.IsValid()) {
- // Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
- const CMIUtilString strValue(CMIUtilString::Format("%ld", threadIndexID));
- const CMICmnMIValueConst miValueConst(strValue);
- const CMICmnMIValueResult miValueResult("id", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBand(
- CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
- const CMICmnMIValueConst miValueConst2("i1");
- const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
- miOutOfBand.Add(miValueResult2);
- bool bOk = MiOutOfBandRecordToStdout(miOutOfBand);
- if (!bOk)
- return MIstatus::failure;
-
- // Remove current thread from cache and get next
- it = rSessionInfo.m_vecActiveThreadId.erase(it);
- } else
- // Next
- ++it;
- }
-
- return CMICmnStreamStdout::WritePrompt();
-}
-
-//++
-// Details: Take a fully formed MI result record and send to the stdout stream.
-// Also output to the MI Log file.
-// Type: Method.
-// Args: vrMiResultRecord - (R) MI result record object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::MiResultRecordToStdout(
- const CMICmnMIResultRecord &vrMiResultRecord) {
- return TextToStdout(vrMiResultRecord.GetString());
-}
-
-//++
-// Details: Take a fully formed MI Out-of-band record and send to the stdout
-// stream.
-// Also output to the MI Log file.
-// Type: Method.
-// Args: vrMiOutOfBandRecord - (R) MI Out-of-band record object.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout(
- const CMICmnMIOutOfBandRecord &vrMiOutOfBandRecord) {
- return TextToStdout(vrMiOutOfBandRecord.GetString());
-}
-
-//++
-// Details: Take a text data and send to the stdout stream. Also output to the
-// MI Log
-// file.
-// Type: Method.
-// Args: vrTxt - (R) Text.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::TextToStdout(const CMIUtilString &vrTxt) {
- return CMICmnStreamStdout::TextToStdout(vrTxt);
-}
-
-//++
-// Details: Take a text data and send to the stderr stream. Also output to the
-// MI Log
-// file.
-// Type: Method.
-// Args: vrTxt - (R) Text.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBDebuggerHandleEvents::TextToStderr(const CMIUtilString &vrTxt) {
- return CMICmnStreamStderr::TextToStderr(vrTxt);
-}
-
-//++
-// Details: Initialize the member variables with the signal values in this
-// process
-// file.
-// Type: Method.
-// Args: None
-// Return: Noen
-// Throws: None.
-//--
-void CMICmnLLDBDebuggerHandleEvents::InitializeSignals() {
- if (!m_bSignalsInitialized) {
- lldb::SBProcess sbProcess =
- CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- if (sbProcess.IsValid()) {
- lldb::SBUnixSignals unix_signals = sbProcess.GetUnixSignals();
- m_SIGINT = unix_signals.GetSignalNumberFromName("SIGINT");
- m_SIGSTOP = unix_signals.GetSignalNumberFromName("SIGSTOP");
- m_SIGSEGV = unix_signals.GetSignalNumberFromName("SIGSEGV");
- m_SIGTRAP = unix_signals.GetSignalNumberFromName("SIGTRAP");
- m_bSignalsInitialized = true;
- }
- }
-}
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
deleted file mode 100644
index 378d85e6f575..000000000000
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- MICmnLLDBDebuggerHandleEvents.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnMIValueList.h"
-#include "MICmnMIValueTuple.h"
-#include "MIUtilSingletonBase.h"
-#include "lldb/API/SBEvent.h"
-
-// Declarations:
-class CMICmnLLDBDebugSessionInfo;
-class CMICmnMIResultRecord;
-class CMICmnStreamStdout;
-class CMICmnMIOutOfBandRecord;
-
-//++
-//============================================================================
-// Details: MI class to take LLDB SBEvent objects, filter them and form
-// MI Out-of-band records from the information inside the event object.
-// These records are then pushed to stdout.
-// A singleton class.
-//--
-class CMICmnLLDBDebuggerHandleEvents
- : public CMICmnBase,
- public MI::ISingleton<CMICmnLLDBDebuggerHandleEvents> {
- friend class MI::ISingleton<CMICmnLLDBDebuggerHandleEvents>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- //
- bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent);
-
- // Methods:
-private:
- /* ctor */ CMICmnLLDBDebuggerHandleEvents();
- /* ctor */ CMICmnLLDBDebuggerHandleEvents(
- const CMICmnLLDBDebuggerHandleEvents &);
- void operator=(const CMICmnLLDBDebuggerHandleEvents &);
- //
- bool ChkForStateChanges();
- bool GetProcessStdout();
- bool GetProcessStderr();
- bool HandleEventSBBreakPoint(const lldb::SBEvent &vEvent);
- bool HandleEventSBBreakpointCmn(const lldb::SBEvent &vEvent);
- bool HandleEventSBBreakpointAdded(const lldb::SBEvent &vEvent);
- bool HandleEventSBBreakpointLocationsAdded(const lldb::SBEvent &vEvent);
- bool HandleEventSBProcess(const lldb::SBEvent &vEvent);
- bool HandleEventSBTarget(const lldb::SBEvent &vEvent);
- bool HandleEventSBThread(const lldb::SBEvent &vEvent);
- bool HandleEventSBThreadBitStackChanged(const lldb::SBEvent &vEvent);
- bool HandleEventSBThreadSuspended(const lldb::SBEvent &vEvent);
- bool HandleEventSBCommandInterpreter(const lldb::SBEvent &vEvent);
- bool HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent);
- bool HandleProcessEventStateRunning();
- bool HandleProcessEventStateExited();
- bool HandleProcessEventStateStopped(const lldb::SBEvent &vrEvent,
- bool &vwrbShouldBrk);
- bool HandleProcessEventStopReasonTrace();
- bool HandleProcessEventStopReasonBreakpoint();
- bool HandleProcessEventStopSignal(const lldb::SBEvent &vrEvent);
- bool HandleProcessEventStopException();
- bool HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent);
- bool HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent);
- bool
- HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent);
- bool MiHelpGetModuleInfo(const lldb::SBModule &vModule,
- const bool vbWithExtraFields,
- CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord);
- bool MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple);
- bool MiResultRecordToStdout(const CMICmnMIResultRecord &vrMiResultRecord);
- bool
- MiOutOfBandRecordToStdout(const CMICmnMIOutOfBandRecord &vrMiResultRecord);
- bool MiStoppedAtBreakPoint(const MIuint64 vBrkPtId,
- const lldb::SBBreakpoint &vBrkPt);
- bool TextToStdout(const CMIUtilString &vrTxt);
- bool TextToStderr(const CMIUtilString &vrTxt);
- bool UpdateSelectedThread();
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnLLDBDebuggerHandleEvents() override;
- void InitializeSignals();
- bool m_bSignalsInitialized;
- MIuint64 m_SIGINT;
- MIuint64 m_SIGSTOP;
- MIuint64 m_SIGSEGV;
- MIuint64 m_SIGTRAP;
-};
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
deleted file mode 100644
index 14e39cd1f80a..000000000000
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//===-- MICmnLLDBProxySBValue.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 <stdlib.h>
-
-// Third Party Headers:
-#include "lldb/API/SBError.h"
-
-// In-house headers:
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBProxySBValue.h"
-#include "MIUtilString.h"
-
-//++
-// Details: Retrieve the numerical value from the SBValue object. If the
-// function fails
-// it could indicate the SBValue object does not represent an internal
-// type.
-// Type: Static method.
-// Args: vrValue - (R) The SBValue object to get a value from.
-// vwValue - (W) The numerical value.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBProxySBValue::GetValueAsUnsigned(const lldb::SBValue &vrValue,
- MIuint64 &vwValue) {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- bool bCompositeType = true;
- MIuint64 nFailValue = 0;
- MIuint64 nValue = rValue.GetValueAsUnsigned(nFailValue);
- if (nValue == nFailValue) {
- nFailValue = 5; // Some arbitrary number
- nValue = rValue.GetValueAsUnsigned(nFailValue);
- if (nValue != nFailValue) {
- bCompositeType = false;
- vwValue = nValue;
- }
- } else {
- bCompositeType = false;
- vwValue = nValue;
- }
-
- return (bCompositeType ? MIstatus::failure : MIstatus::success);
-}
-
-//++
-// Details: Retrieve the numerical value from the SBValue object. If the
-// function fails
-// it could indicate the SBValue object does not represent an internal
-// type.
-// Type: Static method.
-// Args: vrValue - (R) The SBValue object to get a value from.
-// vwValue - (W) The numerical value.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnLLDBProxySBValue::GetValueAsSigned(const lldb::SBValue &vrValue,
- MIint64 &vwValue) {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- bool bCompositeType = true;
- MIuint64 nFailValue = 0;
- MIuint64 nValue = rValue.GetValueAsSigned(nFailValue);
- if (nValue == nFailValue) {
- nFailValue = 5; // Some arbitrary number
- nValue = rValue.GetValueAsSigned(nFailValue);
- if (nValue != nFailValue) {
- bCompositeType = false;
- vwValue = nValue;
- }
- } else {
- bCompositeType = false;
- vwValue = nValue;
- }
-
- return (bCompositeType ? MIstatus::failure : MIstatus::success);
-}
-
-//++
-// Details: Retrieve the NUL terminated string from the SBValue object if it of
-// the type
-// unsigned char *.
-// Type: Static method.
-// Args: vrValue - (R) The SBValue object to get a value from.
-// vwCString - (W) The text data '\0' terminated.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed, not suitable type.
-// Throws: None.
-//--
-bool CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue,
- CMIUtilString &vwCString) {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- const char *pCType = rValue.GetTypeName();
- if (pCType == nullptr)
- return MIstatus::failure;
-
- const char *pType = "unsigned char *";
- if (!CMIUtilString::Compare(pCType, pType))
- return MIstatus::failure;
-
- const CMIUtilString strAddr(rValue.GetValue());
- MIint64 nNum = 0;
- if (!strAddr.ExtractNumber(nNum))
- return MIstatus::failure;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- MIuint nBufferSize = 64;
- bool bNeedResize = false;
- char *pBuffer = static_cast<char *>(::malloc(nBufferSize));
- do {
- lldb::SBError error;
- const size_t nReadSize = sbProcess.ReadCStringFromMemory(
- (lldb::addr_t)nNum, pBuffer, nBufferSize, error);
- if (nReadSize == (nBufferSize - 1)) {
- bNeedResize = true;
- nBufferSize = nBufferSize << 1;
- pBuffer = static_cast<char *>(::realloc(pBuffer, nBufferSize));
- } else
- bNeedResize = false;
- } while (bNeedResize);
-
- vwCString = pBuffer;
- free((void *)pBuffer);
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.h b/tools/lldb-mi/MICmnLLDBProxySBValue.h
deleted file mode 100644
index 4852b60763ea..000000000000
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- MICmnLLDBProxySBValue.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third Party Headers:
-#include "lldb/API/SBValue.h"
-
-// In-house headers:
-#include "MIDataTypes.h"
-
-// Declarations:
-class CMIUtilString;
-
-//++
-//============================================================================
-// Details: MI proxy wrapper class to lldb::SBValue. The class provides
-// functionality
-// to assist in the use of SBValue's particular function usage.
-//--
-class CMICmnLLDBProxySBValue {
- // Statics:
-public:
- static bool GetValueAsSigned(const lldb::SBValue &vrValue, MIint64 &vwValue);
- static bool GetValueAsUnsigned(const lldb::SBValue &vrValue,
- MIuint64 &vwValue);
- static bool GetCString(const lldb::SBValue &vrValue,
- CMIUtilString &vwCString);
-};
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
deleted file mode 100644
index 0e7df52b7b99..000000000000
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-//===-- MICmnLLDBUtilSBValue.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBTypeSummary.h"
-#include <cinttypes>
-
-// In-house headers:
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBUtilSBValue.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueTuple.h"
-#include "MIUtilString.h"
-
-static const char *kUnknownValue = "??";
-static const char *kUnresolvedCompositeValue = "{...}";
-
-//++
-// Details: CMICmnLLDBUtilSBValue constructor.
-// Type: Method.
-// Args: vrValue - (R) The LLDB value object.
-// vbHandleCharType - (R) True = Yes return text molding to char
-// type,
-// False = just return data.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(
- const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */,
- const bool vbHandleArrayType /* = true */)
- : m_rValue(const_cast<lldb::SBValue &>(vrValue)),
- m_bHandleCharType(vbHandleCharType),
- m_bHandleArrayType(vbHandleArrayType) {
- m_bValidSBValue = m_rValue.IsValid();
-}
-
-//++
-// Details: CMICmnLLDBUtilSBValue destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue() {}
-
-//++
-// Details: Retrieve from the LLDB SB Value object the name of the variable. If
-// the name
-// is invalid (or the SBValue object invalid) then "??" is returned.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Name of the variable or "??" for unknown.
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBUtilSBValue::GetName() const {
- const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
- const CMIUtilString text((pName != nullptr) ? pName : CMIUtilString());
-
- return text;
-}
-
-//++
-// Details: Retrieve from the LLDB SB Value object the value of the variable
-// described in
-// text. If the value is invalid (or the SBValue object invalid) then
-// "??" is
-// returned.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text description of the variable's value or "??".
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBUtilSBValue::GetValue(
- const bool vbExpandAggregates /* = false */) const {
- if (!m_bValidSBValue)
- return kUnknownValue;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- bool bPrintExpandAggregates = false;
- bPrintExpandAggregates = rSessionInfo.SharedDataRetrieve<bool>(
- rSessionInfo.m_constStrPrintExpandAggregates,
- bPrintExpandAggregates) &&
- bPrintExpandAggregates;
-
- const bool bHandleArrayTypeAsSimple =
- m_bHandleArrayType && !vbExpandAggregates && !bPrintExpandAggregates;
- CMIUtilString value;
- const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value);
- if (bIsSimpleValue)
- return value;
-
- if (!vbExpandAggregates && !bPrintExpandAggregates)
- return kUnresolvedCompositeValue;
-
- bool bPrintAggregateFieldNames = false;
- bPrintAggregateFieldNames =
- !rSessionInfo.SharedDataRetrieve<bool>(
- rSessionInfo.m_constStrPrintAggregateFieldNames,
- bPrintAggregateFieldNames) ||
- bPrintAggregateFieldNames;
-
- CMICmnMIValueTuple miValueTuple;
- const bool bOk = GetCompositeValue(bPrintAggregateFieldNames, miValueTuple);
- if (!bOk)
- return kUnknownValue;
-
- value = miValueTuple.GetString();
- return value;
-}
-
-//++
-// Details: Retrieve from the LLDB SB Value object the value of the variable
-// described in
-// text if it has a simple format (not composite).
-// Type: Method.
-// Args: vwrValue - (W) The SBValue in a string format.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType,
- CMIUtilString &vwrValue) const {
- const MIuint nChildren = m_rValue.GetNumChildren();
- if (nChildren == 0) {
- vwrValue = GetValueSummary(!m_bHandleCharType && IsCharType(), kUnknownValue);
- return MIstatus::success;
- } else if (IsPointerType()) {
- vwrValue =
- GetValueSummary(!m_bHandleCharType && IsPointeeCharType(), kUnknownValue);
- return MIstatus::success;
- } else if (IsArrayType()) {
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- bool bPrintCharArrayAsString = false;
- bPrintCharArrayAsString = rSessionInfo.SharedDataRetrieve<bool>(
- rSessionInfo.m_constStrPrintCharArrayAsString,
- bPrintCharArrayAsString) &&
- bPrintCharArrayAsString;
- if (bPrintCharArrayAsString && m_bHandleCharType &&
- IsFirstChildCharType()) {
- vwrValue = GetValueSummary(false);
- return MIstatus::success;
- } else if (vbHandleArrayType) {
- vwrValue = CMIUtilString::Format("[%u]", nChildren);
- return MIstatus::success;
- }
- } else {
- // Treat composite value which has registered summary
- // (for example with AddCXXSummary) as simple value
- vwrValue = GetValueSummary(false);
- if (!vwrValue.empty())
- return MIstatus::success;
- }
-
- // Composite variable type i.e. struct
- return MIstatus::failure;
-}
-
-bool CMICmnLLDBUtilSBValue::GetCompositeValue(
- const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
- const MIuint vnDepth /* = 1 */) const {
- const MIuint nMaxDepth = 10;
- const MIuint nChildren = m_rValue.GetNumChildren();
- for (MIuint i = 0; i < nChildren; ++i) {
- const lldb::SBValue member = m_rValue.GetChildAtIndex(i);
- const CMICmnLLDBUtilSBValue utilMember(member, m_bHandleCharType,
- m_bHandleArrayType);
- const bool bHandleArrayTypeAsSimple = false;
- CMIUtilString value;
- const bool bIsSimpleValue =
- utilMember.GetSimpleValue(bHandleArrayTypeAsSimple, value);
- if (bIsSimpleValue) {
- // OK. Value is simple (not composite) and was successfully got
- } else if (vnDepth < nMaxDepth) {
- // Need to get value from composite type
- CMICmnMIValueTuple miValueTuple;
- const bool bOk = utilMember.GetCompositeValue(vbPrintFieldNames,
- miValueTuple, vnDepth + 1);
- if (!bOk)
- // Can't obtain composite type
- value = kUnknownValue;
- else
- // OK. Value is composite and was successfully got
- value = miValueTuple.GetString();
- } else {
- // Need to get value from composite type, but vnMaxDepth is reached
- value = kUnresolvedCompositeValue;
- }
- const bool bNoQuotes = true;
- const CMICmnMIValueConst miValueConst(value, bNoQuotes);
- if (vbPrintFieldNames) {
- const bool bUseSpacing = true;
- const CMICmnMIValueResult miValueResult(utilMember.GetName(),
- miValueConst, bUseSpacing);
- vwrMiValueTuple.Add(miValueResult, bUseSpacing);
- } else {
- const bool bUseSpacing = false;
- vwrMiValueTuple.Add(miValueConst, bUseSpacing);
- }
- }
-
- return MIstatus::success;
-}
-
-// Returns value or value + summary, depending on valueOnly parameter value.
-// If result is an empty string returns failVal.
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetValueSummary(bool valueOnly,
- const CMIUtilString &failVal) const {
- if (!m_rValue.IsValid())
- return failVal;
-
- CMIUtilString value, valSummary;
- const char *c_value = m_rValue.GetValue();
- if (valueOnly)
- return c_value == nullptr ? failVal : c_value;
-
- const char *c_summary = m_rValue.GetSummary();
- if (c_value)
- value = c_value;
- else if (c_summary == nullptr)
- return failVal;
-
- if (c_summary && c_summary[0]) {
- valSummary = c_summary;
- lldb::SBTypeSummary summary = m_rValue.GetTypeSummary();
- if (summary.IsValid() && summary.DoesPrintValue(m_rValue) &&
- !value.empty()) {
- valSummary.insert(0, value + " ");
- }
- return valSummary;
- }
- // no summary - return just value
- return value;
-}
-
-//++
-// Details: Check that basic type is a char type. Char type can be signed or
-// unsigned.
-// Type: Static.
-// Args: eType - type to check
-// Return: bool - True = Yes is a char type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsCharBasicType(lldb::BasicType eType) {
- switch (eType) {
- case lldb::eBasicTypeChar:
- case lldb::eBasicTypeSignedChar:
- case lldb::eBasicTypeUnsignedChar:
- case lldb::eBasicTypeChar16:
- case lldb::eBasicTypeChar32:
- return true;
- default:
- return false;
- }
-}
-
-//++
-// Details: Retrieve the flag stating whether this value object is a char type
-// or some
-// other type. Char type can be signed or unsigned.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is a char type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsCharType() const {
- const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
- return IsCharBasicType(eType);
-}
-
-//++
-// Details: Retrieve the flag stating whether first child value object of *this
-// object is
-// a char type or some other type. Returns false if there are not
-// children. Char
-// type can be signed or unsigned.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is a char type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsFirstChildCharType() const {
- const MIuint nChildren = m_rValue.GetNumChildren();
-
- // Is it a basic type
- if (nChildren == 0)
- return false;
-
- const lldb::SBValue member = m_rValue.GetChildAtIndex(0);
- const CMICmnLLDBUtilSBValue utilValue(member);
- return utilValue.IsCharType();
-}
-
-//++
-// Details: Retrieve the flag stating whether pointee object of *this object is
-// a char type or some other type. Returns false if there are not
-// children. Char
-// type can be signed or unsigned.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is a char type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsPointeeCharType() const {
- const MIuint nChildren = m_rValue.GetNumChildren();
-
- // Is it a basic type
- if (nChildren == 0)
- return false;
-
- const lldb::BasicType eType =
- m_rValue.GetType().GetPointeeType().GetBasicType();
- return IsCharBasicType(eType);
-}
-
-//++
-// Details: Retrieve the flag stating whether this value object is a integer
-// type or some
-// other type. Char type can be signed or unsigned and short or
-// long/very long.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is a integer type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsIntegerType() const {
- const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
- return ((eType == lldb::eBasicTypeShort) ||
- (eType == lldb::eBasicTypeUnsignedShort) ||
- (eType == lldb::eBasicTypeInt) ||
- (eType == lldb::eBasicTypeUnsignedInt) ||
- (eType == lldb::eBasicTypeLong) ||
- (eType == lldb::eBasicTypeUnsignedLong) ||
- (eType == lldb::eBasicTypeLongLong) ||
- (eType == lldb::eBasicTypeUnsignedLongLong) ||
- (eType == lldb::eBasicTypeInt128) ||
- (eType == lldb::eBasicTypeUnsignedInt128));
-}
-
-//++
-// Details: Retrieve the flag stating whether this value object is a pointer
-// type or some
-// other type.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is a pointer type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsPointerType() const {
- return m_rValue.GetType().IsPointerType();
-}
-
-//++
-// Details: Retrieve the flag stating whether this value object is an array type
-// or some
-// other type.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes is an array type, false = some other type.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsArrayType() const {
- return m_rValue.GetType().IsArrayType();
-}
-
-//++
-// Details: Retrieve the C string data of value object by read the memory where
-// the
-// variable is held.
-// Type: Method.
-// Args: vrValue - (R) LLDB SBValue variable object.
-// Return: CMIUtilString - Text description of the variable's value.
-// Throws: None.
-//--
-template <typename charT>
-CMIUtilString
-CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue,
- const MIuint vnMaxLen) const {
- std::string result;
- lldb::addr_t addr = vrValue.GetLoadAddress(),
- end_addr = addr + vnMaxLen * sizeof(charT);
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
- lldb::SBError error;
- while (addr < end_addr) {
- charT ch;
- const MIuint64 nReadBytes =
- process.ReadMemory(addr, &ch, sizeof(ch), error);
- if (error.Fail() || nReadBytes != sizeof(ch))
- return kUnknownValue;
- else if (ch == 0)
- break;
- result.append(
- CMIUtilString::ConvertToPrintableASCII(ch, true /* bEscapeQuotes */));
- addr += sizeof(ch);
- }
-
- return result;
-}
-
-//++
-// Details: Retrieve the state of the value object's name.
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes name is indeterminate, false = name is valid.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsNameUnknown() const {
- const CMIUtilString name(GetName());
- return (name == kUnknownValue);
-}
-
-//++
-// Details: Retrieve the state of the value object's value data.
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes value is indeterminate, false = value valid.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsValueUnknown() const {
- const CMIUtilString value(GetValue());
- return (value == kUnknownValue);
-}
-
-//++
-// Details: Retrieve the value object's type name if valid.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - The type name or "??".
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBUtilSBValue::GetTypeName() const {
- const char *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
- const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
-
- return text;
-}
-
-//++
-// Details: Retrieve the value object's display type name if valid.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - The type name or "??".
-// Throws: None.
-//--
-CMIUtilString CMICmnLLDBUtilSBValue::GetTypeNameDisplay() const {
- const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
- const CMIUtilString text((pName != nullptr) ? pName : kUnknownValue);
-
- return text;
-}
-
-//++
-// Details: Retrieve whether the value object's is valid or not.
-// Type: Method.
-// Args: None.
-// Return: bool - True = valid, false = not valid.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsValid() const { return m_bValidSBValue; }
-
-//++
-// Details: Retrieve the value object' has a name. A value object can be valid
-// but still
-// have no name which suggest it is not a variable.
-// Type: Method.
-// Args: None.
-// Return: bool - True = valid, false = not valid.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::HasName() const {
- bool bHasAName = false;
-
- const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
- if (pName != nullptr) {
- bHasAName = (CMIUtilString(pName).length() > 0);
- }
-
- return bHasAName;
-}
-
-//++
-// Details: Determine if the value object' represents a LLDB variable i.e. "$0".
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes LLDB variable, false = no.
-// Throws: None.
-//--
-bool CMICmnLLDBUtilSBValue::IsLLDBVariable() const {
- return (GetName().at(0) == '$');
-}
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.h b/tools/lldb-mi/MICmnLLDBUtilSBValue.h
deleted file mode 100644
index 6804402b75d6..000000000000
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- MICmnLLDBUtilSBValue.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third Party Headers:
-#include "lldb/API/SBValue.h"
-
-// In-house headers:
-#include "MICmnMIValueTuple.h"
-#include "MIDataTypes.h"
-
-// Declarations:
-class CMIUtilString;
-
-//++
-//============================================================================
-// Details: Utility helper class to lldb::SBValue. Using a lldb::SBValue extract
-// value object information to help form verbose debug information.
-//--
-class CMICmnLLDBUtilSBValue {
- // Methods:
-public:
- /* ctor */ CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue,
- const bool vbHandleCharType = false,
- const bool vbHandleArrayType = true);
- /* dtor */ ~CMICmnLLDBUtilSBValue();
- //
- CMIUtilString GetName() const;
- CMIUtilString GetValue(const bool vbExpandAggregates = false) const;
- CMIUtilString GetTypeName() const;
- CMIUtilString GetTypeNameDisplay() const;
- bool IsCharType() const;
- bool IsFirstChildCharType() const;
- bool IsPointeeCharType() const;
- bool IsIntegerType() const;
- bool IsPointerType() const;
- bool IsArrayType() const;
- bool IsLLDBVariable() const;
- bool IsNameUnknown() const;
- bool IsValueUnknown() const;
- bool IsValid() const;
- bool HasName() const;
-
- // Methods:
-private:
- template <typename charT>
- CMIUtilString
- ReadCStringFromHostMemory(lldb::SBValue &vrValue,
- const MIuint vnMaxLen = UINT32_MAX) const;
- bool GetSimpleValue(const bool vbHandleArrayType,
- CMIUtilString &vrValue) const;
- bool GetCompositeValue(const bool vbPrintFieldNames,
- CMICmnMIValueTuple &vwrMiValueTuple,
- const MIuint vnDepth = 1) const;
- CMIUtilString
- GetValueSummary(bool valueOnly,
- const CMIUtilString &failVal = CMIUtilString()) const;
-
- // Statics:
-private:
- static bool IsCharBasicType(lldb::BasicType eType);
-
- // Attributes:
-private:
- lldb::SBValue &m_rValue;
- bool m_bValidSBValue; // True = SBValue is a valid object, false = not valid.
- bool m_bHandleCharType; // True = Yes return text molding to char type, false
- // = just return data.
- bool m_bHandleArrayType; // True = Yes return special stub for array type,
- // false = just return data.
-};
diff --git a/tools/lldb-mi/MICmnLog.cpp b/tools/lldb-mi/MICmnLog.cpp
deleted file mode 100644
index fc4c3141915b..000000000000
--- a/tools/lldb-mi/MICmnLog.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-//===-- MICmnLog.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnLog.h"
-#include "MICmnLogMediumFile.h"
-#include "MICmnResources.h"
-#include "MIDriverMgr.h"
-#include "MIUtilDateTimeStd.h"
-
-//++
-// Details: CMICmnLog constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLog::CMICmnLog() : m_bEnabled(false), m_bInitializingATM(false) {
- // Do not use this constructor, use Initialize()
-}
-
-//++
-// Details: CMICmnLog destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLog::~CMICmnLog() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Logger.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- ClrErrorDescription();
-
- // Mediums set inside because explicitly initing in MIDriverMain.cpp causes
- // compile errors with CAtlFile
- CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
- bool bOk = RegisterMedium(rFileLog);
- if (bOk) {
- // Set the Log trace file's header
- const CMIUtilString &rCR(rFileLog.GetLineReturn());
- CMIUtilDateTimeStd date;
- CMIUtilString msg;
- msg = CMIUtilString::Format(
- "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str());
- CMIUtilString logHdr(msg);
- msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE),
- date.GetDate().c_str(), date.GetTime().c_str(),
- rCR.c_str());
- logHdr += msg;
- msg =
- CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH),
- rFileLog.GetFileNamePath().c_str(), rCR.c_str());
- logHdr += msg;
-
- bOk = rFileLog.SetHeaderTxt(logHdr);
-
- // Note log file medium's status is not available until we write at least
- // once to the file (so just write the title 1st line)
- m_bInitializingATM = true;
- CMICmnLog::WriteLog(".");
- if (!rFileLog.IsOk()) {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED),
- rFileLog.GetErrorDescription().c_str()));
- CMICmnLog::WriteLog(msg);
- }
- m_bInitializingATM = false;
- }
-
- m_bInitialized = bOk;
-
- return bOk;
-}
-
-//++
-// Details: Release resources for *this Logger.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- ClrErrorDescription();
-
- const bool bOk = UnregisterMediumAll();
-
- m_bInitialized = bOk;
-
- return bOk;
-}
-
-//++
-// Details: Enabled or disable *this Logger from writing any data to registered
-// clients.
-// Type: Method.
-// Args: vbYes - (R) True = Logger enabled, false = disabled.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::SetEnabled(const bool vbYes) {
- m_bEnabled = vbYes;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve state whether *this Logger is enabled writing data to
-// registered clients.
-// Type: Method.
-// Args: None.
-// Return: True = Logger enable.
-// False = disabled.
-// Throws: None.
-//--
-bool CMICmnLog::GetEnabled() const { return m_bEnabled; }
-
-//++
-// Details: Unregister all the Mediums registered with *this Logger.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::UnregisterMediumAll() {
- MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
- for (; it != m_mapMediumToName.end(); it++) {
- IMedium *pMedium = (*it).first;
- pMedium->Shutdown();
- }
-
- m_mapMediumToName.clear();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Register a Medium with *this Logger.
-// Type: Method.
-// Args: vrMedium - (R) The medium to register.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::RegisterMedium(const IMedium &vrMedium) {
- if (HaveMediumAlready(vrMedium))
- return MIstatus::success;
-
- IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
- if (!pMedium->Initialize()) {
- const CMIUtilString &rStrMedName(pMedium->GetName());
- const CMIUtilString &rStrMedErr(pMedium->GetError());
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LOG_MEDIUM_ERR_INIT),
- rStrMedName.c_str(),
- rStrMedErr.c_str()));
- return MIstatus::failure;
- }
-
- MapPairMediumToName_t pr(pMedium, pMedium->GetName());
- m_mapMediumToName.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Query the Logger to see if a medium is already registered.
-// Type: Method.
-// Args: vrMedium - (R) The medium to query.
-// Return: True - registered.
-// False - not registered.
-// Throws: None.
-//--
-bool CMICmnLog::HaveMediumAlready(const IMedium &vrMedium) const {
- IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
- const MapMediumToName_t::const_iterator it = m_mapMediumToName.find(pMedium);
- return it != m_mapMediumToName.end();
-}
-
-//++
-// Details: Unregister a medium from the Logger.
-// Type: Method.
-// Args: vrMedium - (R) The medium to unregister.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::UnregisterMedium(const IMedium &vrMedium) {
- IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
- m_mapMediumToName.erase(pMedium);
-
- return MIstatus::success;
-}
-
-//++
-// Details: The callee client uses this function to write to the Logger. The
-// data to be
-// written is given out to all the mediums registered. The verbosity
-// type parameter
-// indicates to the medium(s) the type of data or message given to it.
-// The medium has
-// modes of verbosity and depending on the verbosity set determines
-// which writes
-// go in to the logger.
-// The logger must be initialized successfully before a write to any
-// registered
-// can be carried out.
-// Type: Method.
-// Args: vData - (R) The data to write to the logger.
-// veType - (R) Verbosity type.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) {
- if (!m_bInitialized && !m_bInitializingATM)
- return MIstatus::success;
- if (m_bRecursiveDive)
- return MIstatus::success;
- if (!m_bEnabled)
- return MIstatus::success;
-
- m_bRecursiveDive = true;
-
- MIuint cnt = 0;
- MIuint cntErr = 0;
- {
- MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
- while (it != m_mapMediumToName.end()) {
- IMedium *pMedium = (*it).first;
- const CMIUtilString &rNameMedium = (*it).second;
- MIunused(rNameMedium);
- if (pMedium->Write(vData, veType))
- cnt++;
- else
- cntErr++;
-
- // Next
- ++it;
- }
- }
-
- bool bOk = MIstatus::success;
- const MIuint mediumCnt = m_mapMediumToName.size();
- if ((cnt == 0) && (mediumCnt > 0)) {
- SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY));
- bOk = MIstatus::failure;
- }
- if (bOk && (cntErr != 0)) {
- SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL));
- bOk = MIstatus::failure;
- }
-
- m_bRecursiveDive = false;
-
- return bOk;
-}
-
-//++
-// Details: Short cut function call to write only to the Log file.
-// The logger must be initialized successfully before a write to any
-// registered
-// can be carried out.
-// Type: Static.
-// Args: vData - (R) The data to write to the logger.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLog::WriteLog(const CMIUtilString &vData) {
- return CMICmnLog::Instance().Write(vData, CMICmnLog::eLogVerbosity_Log);
-}
-
-//++
-// Details: Retrieve a string detailing the last error.
-// Type: Method.
-// Args: None,
-// Return: CMIUtilString.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLog::GetErrorDescription() const {
- return m_strMILastErrorDescription;
-}
-
-//++
-// Details: Set the internal description of the last error.
-// Type: Method.
-// Args: (R) String containing a description of the last error.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLog::SetErrorDescription(const CMIUtilString &vrTxt) const {
- m_strMILastErrorDescription = vrTxt;
-}
-
-//++
-// Details: Clear the last error.
-// Type: None.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnLog::ClrErrorDescription() const {
- m_strMILastErrorDescription = CMIUtilString("");
-}
diff --git a/tools/lldb-mi/MICmnLog.h b/tools/lldb-mi/MICmnLog.h
deleted file mode 100644
index 909dc613b02e..000000000000
--- a/tools/lldb-mi/MICmnLog.h
+++ /dev/null
@@ -1,138 +0,0 @@
-//===-- MICmnLog.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <map>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code implementation class. Handle application trace
-// activity logging. Medium objects derived from the Medium abstract
-/// class are registered with this logger. The function Write is called
-// by a client callee to log information. That information is given to
-// registered relevant mediums. The medium file is registered during
-// *this logs initialization so it will always have a file log for the
-// application.
-// Singleton class.
-//--
-class CMICmnLog : public MI::ISingleton<CMICmnLog> {
- friend MI::ISingleton<CMICmnLog>;
-
- // Enumeration:
-public:
- //++
- // Description: Data given to the Logger can be of several types. The Logger
- // can be
- // set at levels of verbosity. Can determine how data is sent to
- // one or
- // mediums.
- //--
- enum ELogVerbosity { // Descriptions of what 'may' occur, depends ultimately
- // on the medium itself. See the medium.
- eLogVerbosity_FnTrace = 0x00000004, // Debug function stack call tracing
- eLogVerbosity_DbgOp = 0x00000008, // Send a string to the debugger for
- // display (not implemented)
- eLogVerbosity_ClientMsg = 0x00000010, // A client using MI can insert
- // messages into the log (not
- // implemented)
- eLogVerbosity_Log = 0x00000020 // Send to only the Log file.
- };
-
- // Class:
-public:
- //++
- // Description: Register a medium derived from this interface which will be
- // called writing log trace data i.e. a file or a console.
- // Medium objects registered are not owned by *this logger.
- //--
- class IMedium {
- public:
- virtual bool Initialize() = 0;
- virtual const CMIUtilString &GetName() const = 0;
- virtual bool Write(const CMIUtilString &vData,
- const ELogVerbosity veType) = 0;
- virtual const CMIUtilString &GetError() const = 0;
- virtual bool Shutdown() = 0;
-
- // Not part of the interface, ignore
- // AD: This virtual destructor seems to hit a bug in the stdlib
- // where vector delete is incorrectly called. Workaround is
- // to comment this out while I investigate.
- /* dtor */ virtual ~IMedium() {}
- };
-
- // Statics:
-public:
- static bool WriteLog(const CMIUtilString &vData);
-
- // Methods:
-public:
- bool RegisterMedium(const IMedium &vrMedium);
- bool UnregisterMedium(const IMedium &vrMedium);
- bool Write(const CMIUtilString &vData, const ELogVerbosity veType);
- bool SetEnabled(const bool vbYes);
- bool GetEnabled() const;
-
- // MI common object handling - duplicate of CMICmnBase functions, necessary
- // for LINUX build
- // Done to stop locking on object construction init circular dependency.
- const CMIUtilString &GetErrorDescription() const;
- void SetErrorDescription(const CMIUtilString &vrTxt) const;
- void ClrErrorDescription() const;
-
- // Overridden:
-public:
- // From MI::ISingleton
- bool Initialize() override;
- bool Shutdown() override;
-
- // Methods:
-private:
- /* ctor */ CMICmnLog();
- /* ctor */ CMICmnLog(const CMICmnLog &);
- void operator=(const CMICmnLog &);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnLog() override;
-
- // Typedef:
-private:
- typedef std::map<IMedium *, CMIUtilString> MapMediumToName_t;
- typedef std::pair<IMedium *, CMIUtilString> MapPairMediumToName_t;
-
- // Methods:
-private:
- bool HaveMediumAlready(const IMedium &vrMedium) const;
- bool UnregisterMediumAll();
-
- // Attributes:
-private:
- bool m_bRecursiveDive; // True = yes recursive, false = no
- MapMediumToName_t m_mapMediumToName;
- bool m_bEnabled; // True = Logger enabled for writing to mediums, false =
- // medium not written to
- bool m_bInitializingATM; // True = Yes in process of initing *this logger,
- // false = not initing
- //
- // MI common object handling - duplicate of CMICmnBase functions, necessary
- // for LINUX build
- bool m_bInitialized; // True = yes successfully initialized, false = no yet or
- // failed
- mutable CMIUtilString m_strMILastErrorDescription;
- MIint m_clientUsageRefCnt; // Count of client using *this object so not
- // shutdown() object to early
-};
diff --git a/tools/lldb-mi/MICmnLogMediumFile.cpp b/tools/lldb-mi/MICmnLogMediumFile.cpp
deleted file mode 100644
index 7fbe28f3fe0f..000000000000
--- a/tools/lldb-mi/MICmnLogMediumFile.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-//===-- MICmnLogMediumFile.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnLogMediumFile.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMICmnLogMediumFile constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLogMediumFile::CMICmnLogMediumFile()
- : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)),
- m_constMediumFileNameFormat("lldb-mi-%s.log"),
- m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
- m_strMediumFileDirectory("."),
- m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
- m_eVerbosityType(CMICmnLog::eLogVerbosity_Log),
- m_strDate(CMIUtilDateTimeStd().GetDate()),
- m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) {}
-
-//++
-// Details: CMICmnLogMediumFile destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnLogMediumFile::~CMICmnLogMediumFile() {}
-
-//++
-// Details: Get the singleton instance of *this class.
-// Type: Static.
-// Args: None.
-// Return: CMICmnLogMediumFile - Reference to *this object.
-// Throws: None.
-//--
-CMICmnLogMediumFile &CMICmnLogMediumFile::Instance() {
- static CMICmnLogMediumFile instance;
-
- return instance;
-}
-
-//++
-// Details: Initialize setup *this medium ready for use.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::Initialize() {
- m_bInitialized = true;
- return FileFormFileNamePath();
-}
-
-//++
-// Details: Unbind detach or release resources used by *this medium.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::Shutdown() {
- if (m_bInitialized) {
- m_bInitialized = false;
- m_file.Close();
- }
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the name of *this medium.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString - Text data.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLogMediumFile::GetName() const {
- return m_constThisMediumName;
-}
-
-//++
-// Details: The callee client calls the write function on the Logger. The data
-// to be
-// written is given out to all the mediums registered. The verbosity
-// type parameter
-// indicates to the medium the type of data or message given to it. The
-// medium has
-// modes of verbosity and depending on the verbosity set determines
-// which data is
-// sent to the medium's output.
-// Type: Method.
-// Args: vData - (R) The data to write to the logger.
-// veType - (R) Verbosity type.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::Write(const CMIUtilString &vData,
- const CMICmnLog::ELogVerbosity veType) {
- if (m_bInitialized && m_file.IsOk()) {
- const bool bDoWrite = (m_eVerbosityType & veType);
- if (bDoWrite) {
- bool bNewCreated = false;
- bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
- if (bOk) {
- if (bNewCreated)
- bOk = FileWriteHeader();
- bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
- }
- return bOk;
- }
- }
-
- return MIstatus::failure;
-}
-
-//++
-// Details: Retrieve *this medium's last error condition.
-// Type: Method.
-// Args: None.
-// Return: CString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLogMediumFile::GetError() const {
- return m_strMILastErrorDescription;
-}
-
-//++
-// Details: Set the verbosity mode for this medium.
-// Type: Method.
-// Args: veType - (R) Mask value.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::SetVerbosity(const MIuint veType) {
- m_eVerbosityType = veType;
- return MIstatus::success;
-}
-
-//++
-// Details: Get the verbosity mode for this medium.
-// Type: Method.
-// Args: veType - (R) Mask value.
-// Return: CMICmnLog::ELogVerbosity - Mask value.
-// Throws: None.
-//--
-MIuint CMICmnLogMediumFile::GetVerbosity() const { return m_eVerbosityType; }
-
-//++
-// Details: Write data to a file English font.
-// Type: Method.
-// Args: vData - (R) The data to write to the logger.
-// Return: None.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData) {
- return m_file.Write(vData);
-}
-
-//++
-// Details: Determine and form the medium file's directory path and name.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::FileFormFileNamePath() {
- ClrErrorDescription();
-
- m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
-
- CMIUtilDateTimeStd date;
- m_strMediumFileName =
- CMIUtilString::Format(m_constMediumFileNameFormat.c_str(),
- date.GetDateTimeLogFilename().c_str());
-
-#if defined(_MSC_VER)
- m_fileNamePath = CMIUtilString::Format(
- "%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
-#else
- m_fileNamePath = CMIUtilString::Format(
- "%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
-#endif // defined ( _MSC_VER )
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the medium file's directory path and name.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - File path.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLogMediumFile::GetFileNamePath() const {
- return m_fileNamePath;
-}
-
-//++
-// Details: Retrieve the medium file's name.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - File name.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLogMediumFile::GetFileName() const {
- return m_strMediumFileName;
-}
-
-//++
-// Details: Massage the data to behave correct when submitted to file. Insert
-// extra log
-// specific text. The veType is there to allow in the future to parse
-// the log and
-// filter in out specific types of message to make viewing the log more
-// manageable.
-// Type: Method.
-// Args: vData - (R) Raw data.
-// veType - (R) Message type.
-// Return: CMIUtilString - Massaged data.
-// Throws: None.
-//--
-CMIUtilString
-CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData,
- const CMICmnLog::ELogVerbosity veType) {
- const CMIUtilString strCr("\n");
- CMIUtilString data;
- const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
- const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(),
- m_dateTime.GetTime().c_str()));
-
- data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(),
- vData.c_str());
- data = ConvertCr(data);
-
- // Look for EOL...
- const size_t pos = vData.rfind(strCr);
- if (pos == vData.size())
- return data;
-
- // ... did not have an EOL so add one
- data += GetLineReturn();
-
- return data;
-}
-
-//++
-// Details: Convert the Log's verbosity type number into a single char
-// character.
-// Type: Method.
-// Args: veType - (R) Message type.
-// Return: wchar_t - A letter.
-// Throws: None.
-//--
-char CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(
- const CMICmnLog::ELogVerbosity veType) const {
- char c = 0;
- if (veType != 0) {
- MIuint cnt = 0;
- MIuint number(veType);
- while (1 != number) {
- number = number >> 1;
- ++cnt;
- }
- c = 'A' + cnt;
- } else {
- c = '*';
- }
-
- return c;
-}
-
-//++
-// Details: Retrieve state of whether the file medium is ok.
-// Type: Method.
-// Args: None.
-// Return: True - file ok.
-// False - file has a problem.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::IsOk() const { return m_file.IsOk(); }
-
-//++
-// Details: Status on the file log medium existing already.
-// Type: Method.
-// Args: None.
-// Return: True - Exists.
-// False - Not found.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::IsFileExist() const {
- return m_file.IsFileExist(GetFileNamePath());
-}
-
-//++
-// Details: Write the header text the logger file.
-// Type: Method.
-// Args: vText - (R) Text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::FileWriteHeader() {
- return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
-}
-
-//++
-// Details: Convert any carriage line returns to be compatible with the platform
-// the
-// Log file is being written to.
-// Type: Method.
-// Args: vData - (R) Text data.
-// Return: CMIUtilString - Converted string data.
-// Throws: None.
-//--
-CMIUtilString CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const {
- const CMIUtilString strCr("\n");
- const CMIUtilString &rCrCmpat(GetLineReturn());
-
- if (strCr == rCrCmpat)
- return vData;
-
- const size_t nSizeCmpat(rCrCmpat.size());
- const size_t nSize(strCr.size());
- CMIUtilString strConv(vData);
- size_t pos = strConv.find(strCr);
- while (pos != CMIUtilString::npos) {
- strConv.replace(pos, nSize, rCrCmpat);
- pos = strConv.find(strCr, pos + nSizeCmpat);
- }
-
- return strConv;
-}
-
-//++
-// Details: Set the header text that is written to the logger file at the
-// beginning.
-// Type: Method.
-// Args: vText - (R) Text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText) {
- m_fileHeaderTxt = vText;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the file current carriage line return characters used.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnLogMediumFile::GetLineReturn() const {
- return m_file.GetLineReturn();
-}
-
-//++
-// Details: Set the directory to place the log file.
-// Type: Method.
-// Args: vPath - (R) Path to log.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath) {
- m_strMediumFileDirectory = vPath;
-
- return FileFormFileNamePath();
-}
diff --git a/tools/lldb-mi/MICmnLogMediumFile.h b/tools/lldb-mi/MICmnLogMediumFile.h
deleted file mode 100644
index 85b0a9d4f581..000000000000
--- a/tools/lldb-mi/MICmnLogMediumFile.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- MICmnLogMediumFile.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnLog.h"
-#include "MIUtilDateTimeStd.h"
-#include "MIUtilFileStd.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code implementation class. Logs application fn
-// trace/message/
-// error messages to a file. Used as part of the CMICmnLog Logger
-// system. When instantiated *this object is register with the Logger
-// which the Logger when given data to write to registered medium comes
-// *this medium.
-// Singleton class.
-//--
-class CMICmnLogMediumFile : public CMICmnBase, public CMICmnLog::IMedium {
- // Statics:
-public:
- static CMICmnLogMediumFile &Instance();
-
- // Methods:
-public:
- bool SetHeaderTxt(const CMIUtilString &vText);
- bool SetVerbosity(const MIuint veType);
- MIuint GetVerbosity() const;
- const CMIUtilString &GetFileName() const;
- const CMIUtilString &GetFileNamePath() const;
- bool IsOk() const;
- bool IsFileExist() const;
- const CMIUtilString &GetLineReturn() const;
- bool SetDirectory(const CMIUtilString &vPath);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnLogMediumFile() override;
- // From CMICmnLog::IMedium
- bool Initialize() override;
- const CMIUtilString &GetName() const override;
- bool Write(const CMIUtilString &vData,
- const CMICmnLog::ELogVerbosity veType) override;
- const CMIUtilString &GetError() const override;
- bool Shutdown() override;
-
- // Methods:
-private:
- /* ctor */ CMICmnLogMediumFile();
- /* ctor */ CMICmnLogMediumFile(const CMICmnLogMediumFile &);
- void operator=(const CMICmnLogMediumFile &);
-
- bool FileWriteEnglish(const CMIUtilString &vData);
- bool FileFormFileNamePath();
- CMIUtilString MassagedData(const CMIUtilString &vData,
- const CMICmnLog::ELogVerbosity veType);
- bool FileWriteHeader();
- char ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const;
- CMIUtilString ConvertCr(const CMIUtilString &vData) const;
-
- // Attributes:
-private:
- const CMIUtilString m_constThisMediumName;
- const CMIUtilString m_constMediumFileNameFormat;
- //
- CMIUtilString m_strMediumFileName;
- CMIUtilString m_strMediumFileDirectory;
- CMIUtilString m_fileNamePath;
- MIuint m_eVerbosityType;
- CMIUtilString m_strDate;
- CMIUtilString m_fileHeaderTxt;
- CMIUtilFileStd m_file;
- CMIUtilDateTimeStd m_dateTime;
-};
diff --git a/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp b/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp
deleted file mode 100644
index 59856a6f165e..000000000000
--- a/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-//===-- MICmnMIOutOfBandRecord.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third Party Headers:
-#include <assert.h>
-
-// In-house headers:
-#include "MICmnMIOutOfBandRecord.h"
-#include "MICmnResources.h"
-
-// Instantiations:
-static const char *
-MapOutOfBandToText(CMICmnMIOutOfBandRecord::OutOfBand_e veType) {
- switch (veType) {
- case CMICmnMIOutOfBandRecord::eOutOfBand_Running:
- return "running";
- case CMICmnMIOutOfBandRecord::eOutOfBand_Stopped:
- return "stopped";
- case CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated:
- return "breakpoint-created";
- case CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified:
- return "breakpoint-modified";
- case CMICmnMIOutOfBandRecord::eOutOfBand_Thread:
- return ""; // "" Meant to be empty
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupAdded:
- return "thread-group-added";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited:
- return "thread-group-exited";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupRemoved:
- return "thread-group-removed";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted:
- return "thread-group-started";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated:
- return "thread-created";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited:
- return "thread-exited";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected:
- return "thread-selected";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded:
- return "library-loaded";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded:
- return "library-unloaded";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput:
- return "";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput:
- return "";
- case CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput:
- return "";
- }
- assert(false && "unknown CMICmnMIOutofBandRecord::OutOfBand_e");
- return nullptr;
-}
-
-static const char *
-MapOutOfBandToToken(CMICmnMIOutOfBandRecord::OutOfBand_e veType) {
- switch (veType) {
- case CMICmnMIOutOfBandRecord::eOutOfBand_Running:
- return "*";
- case CMICmnMIOutOfBandRecord::eOutOfBand_Stopped:
- return "*";
- case CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_Thread:
- return "@";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupAdded:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupRemoved:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded:
- return "=";
- case CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput:
- return "@";
- case CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput:
- return "~";
- case CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput:
- return "&";
- }
- assert(false && "unknown CMICmnMIOutofBandRecord::OutOfBand_e");
- return nullptr;
-}
-
-//++
-// Details: Build the Out-of-band record's mandatory data part. The part up to
-// the first
-// (additional) result i.e. async-record ==> "*" type.
-// Args: veType - (R) A MI Out-of-Band enumeration.
-// Return: CMIUtilString - The async record text.
-// Throws: None.
-//--
-static CMIUtilString
-BuildAsyncRecord(CMICmnMIOutOfBandRecord::OutOfBand_e veType) {
- auto Token = MapOutOfBandToToken(veType);
- auto Text = MapOutOfBandToText(veType);
- return CMIUtilString::Format("%s%s", CMIUtilString::WithNullAsEmpty(Token),
- CMIUtilString::WithNullAsEmpty(Text));
-}
-
-//++
-// Details: CMICmnMIOutOfBandRecord constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord()
- : m_strAsyncRecord(MIRSRC(IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION)) {}
-
-//++
-// Details: CMICmnMIOutOfBandRecord constructor.
-// Type: Method.
-// Args: veType - (R) A MI Out-of-Bound enumeration.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(OutOfBand_e veType)
- : m_strAsyncRecord(BuildAsyncRecord(veType)) {}
-
-//++
-// Details: CMICmnMIOutOfBandRecord constructor.
-// Type: Method.
-// Args: veType - (R) A MI Out-of-Bound enumeration.
-// vConst - (R) A MI const object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(
- OutOfBand_e veType, const CMICmnMIValueConst &vConst)
- : m_strAsyncRecord(BuildAsyncRecord(veType)) {
- m_strAsyncRecord += vConst.GetString();
-}
-
-//++
-// Details: CMICmnMIOutOfBandRecord constructor.
-// Type: Method.
-// Args: veType - (R) A MI Out-of-Bound enumeration.
-// vResult - (R) A MI result object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(
- OutOfBand_e veType, const CMICmnMIValueResult &vResult)
- : m_strAsyncRecord(BuildAsyncRecord(veType)) {
- Add(vResult);
-}
-
-//++
-// Details: CMICmnMIOutOfBandRecord destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIOutOfBandRecord::~CMICmnMIOutOfBandRecord() {}
-
-//++
-// Details: Return the MI Out-of-band record as a string. The string is a direct
-// result of
-// work done on *this Out-of-band record so if not enough data is added
-// then it is
-// possible to return a malformed Out-of-band record. If nothing has
-// been set or
-// added to *this MI Out-of-band record object then text "<Invalid>"
-// will be returned.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - MI output text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnMIOutOfBandRecord::GetString() const {
- return m_strAsyncRecord;
-}
-
-//++
-// Details: Add to *this Out-of-band record additional information.
-// Type: Method.
-// Args: vResult - (R) A MI result object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIOutOfBandRecord::Add(const CMICmnMIValueResult &vResult) {
- m_strAsyncRecord += ",";
- m_strAsyncRecord += vResult.GetString();
-}
diff --git a/tools/lldb-mi/MICmnMIOutOfBandRecord.h b/tools/lldb-mi/MICmnMIOutOfBandRecord.h
deleted file mode 100644
index ab1faab8bc46..000000000000
--- a/tools/lldb-mi/MICmnMIOutOfBandRecord.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//===-- MICmnMIOutOfBandRecord.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueResult.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Out-of-band (Async) Record class. A class that
-// encapsulates
-// MI result record data and the forming/format of data added to it.
-// Out-of-band records are used to notify the GDB/MI client of
-// additional
-// changes that have occurred. Those changes can either be a
-// consequence
-// of GDB/MI (e.g., a breakpoint modified) or a result of target
-// activity
-// (e.g., target stopped).
-// The syntax is as follows:
-// "*" type ( "," result )*
-// type ==> running | stopped
-//
-// The Out-of-band record can be retrieve at any time *this object is
-// instantiated so unless work is done on *this Out-of-band record then
-// it is
-// possible to return a malformed Out-of-band record. If nothing has
-// been set
-// or added to *this MI Out-of-band record object then text "<Invalid>"
-// will
-// be returned.
-//
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html//
-//--
-class CMICmnMIOutOfBandRecord : public CMICmnBase {
- // Enumerations:
-public:
- //++
- // Details: Enumeration of the type of Out-of-band for *this Out-of-band
- // record
- //--
- enum OutOfBand_e {
- eOutOfBand_Running = 0,
- eOutOfBand_Stopped,
- eOutOfBand_BreakPointCreated,
- eOutOfBand_BreakPointModified,
- eOutOfBand_Thread,
- eOutOfBand_ThreadGroupAdded,
- eOutOfBand_ThreadGroupExited,
- eOutOfBand_ThreadGroupRemoved,
- eOutOfBand_ThreadGroupStarted,
- eOutOfBand_ThreadCreated,
- eOutOfBand_ThreadExited,
- eOutOfBand_ThreadSelected,
- eOutOfBand_TargetModuleLoaded,
- eOutOfBand_TargetModuleUnloaded,
- eOutOfBand_TargetStreamOutput,
- eOutOfBand_ConsoleStreamOutput,
- eOutOfBand_LogStreamOutput
- };
-
- // Methods:
-public:
- /* ctor */ CMICmnMIOutOfBandRecord();
- /* ctor */ CMICmnMIOutOfBandRecord(OutOfBand_e veType);
- /* ctor */ CMICmnMIOutOfBandRecord(OutOfBand_e veType,
- const CMICmnMIValueConst &vConst);
- /* ctor */ CMICmnMIOutOfBandRecord(OutOfBand_e veType,
- const CMICmnMIValueResult &vResult);
- //
- const CMIUtilString &GetString() const;
- void Add(const CMICmnMIValueResult &vResult);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIOutOfBandRecord() override;
-
- // Attributes:
-private:
- CMIUtilString
- m_strAsyncRecord; // Holds the text version of the result record to date
-};
diff --git a/tools/lldb-mi/MICmnMIResultRecord.cpp b/tools/lldb-mi/MICmnMIResultRecord.cpp
deleted file mode 100644
index 93bb5a60ec3d..000000000000
--- a/tools/lldb-mi/MICmnMIResultRecord.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-//===-- MICmnMIResultRecord.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third Party Headers:
-#include <assert.h>
-
-// In-house headers:
-#include "MICmnMIResultRecord.h"
-#include "MICmnResources.h"
-
-//++
-// Details: Map a result class to the corresponding string.
-// Args: veType - (R) A MI result class enumeration.
-// Return: const char* - The string corresponding to the result class.
-// Throws: None.
-//--
-static const char *
-MapResultClassToResultClassText(CMICmnMIResultRecord::ResultClass_e veType) {
- switch (veType) {
- case CMICmnMIResultRecord::eResultClass_Done:
- return "done";
- case CMICmnMIResultRecord::eResultClass_Running:
- return "running";
- case CMICmnMIResultRecord::eResultClass_Connected:
- return "connected";
- case CMICmnMIResultRecord::eResultClass_Error:
- return "error";
- case CMICmnMIResultRecord::eResultClass_Exit:
- return "exit";
- }
- assert(false && "unknown CMICmnMIResultRecord::ResultClass_e");
- return nullptr;
-}
-
-//++
-// Details: Build the result record's mandatory data part. The part up to the
-// first
-// (additional) result i.e. result-record ==> [ token ] "^"
-// result-class.
-// Args: vrToken - (R) The command's transaction ID or token.
-// veType - (R) A MI result class enumeration.
-// Return: CMIUtilString & - MI result record mandatory data
-// Throws: None.
-//--
-static const CMIUtilString
-BuildResultRecord(const CMIUtilString &vrToken,
- CMICmnMIResultRecord::ResultClass_e veType) {
- const char *pStrResultRecord = MapResultClassToResultClassText(veType);
- return CMIUtilString::Format("%s^%s", vrToken.c_str(),
- CMIUtilString::WithNullAsEmpty(pStrResultRecord));
-}
-
-//++
-// Details: CMICmnMIResultRecord constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIResultRecord::CMICmnMIResultRecord()
- : m_strResultRecord(MIRSRC(IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION)) {}
-
-//++
-// Details: CMICmnMIResultRecord constructor.
-// Type: Method.
-// Args: vrToken - (R) The command's transaction ID or token.
-// veType - (R) A MI result class enumeration.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIResultRecord::CMICmnMIResultRecord(const CMIUtilString &vrToken,
- ResultClass_e veType)
- : m_strResultRecord(BuildResultRecord(vrToken, veType)) {}
-
-//++
-// Details: CMICmnMIResultRecord constructor.
-// Type: Method.
-// Args: vrToken - (R) The command's transaction ID or token.
-// veType - (R) A MI result class enumeration.
-// vMIResult - (R) A MI result object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIResultRecord::CMICmnMIResultRecord(const CMIUtilString &vrToken,
- ResultClass_e veType,
- const CMICmnMIValueResult &vValue)
- : m_strResultRecord(BuildResultRecord(vrToken, veType)) {
- Add(vValue);
-}
-
-//++
-// Details: CMICmnMIResultRecord destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIResultRecord::~CMICmnMIResultRecord() {}
-
-//++
-// Details: Return the MI result record as a string. The string is a direct
-// result of
-// work done on *this result record so if not enough data is added then
-// it is
-// possible to return a malformed result record. If nothing has been
-// set or
-// added to *this MI result record object then text "<Invalid>" will be
-// returned.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - MI output text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnMIResultRecord::GetString() const {
- return m_strResultRecord;
-}
-
-//++
-// Details: Add to *this result record additional information.
-// Type: Method.
-// Args: vMIValue - (R) A MI value derived object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIResultRecord::Add(const CMICmnMIValue &vMIValue) {
- m_strResultRecord += ",";
- m_strResultRecord += vMIValue.GetString();
-}
diff --git a/tools/lldb-mi/MICmnMIResultRecord.h b/tools/lldb-mi/MICmnMIResultRecord.h
deleted file mode 100644
index ae57007257c3..000000000000
--- a/tools/lldb-mi/MICmnMIResultRecord.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- MICmnMIResultRecord.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnMIValueResult.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result Record class. A class that encapsulates
-// MI result record data and the forming/format of data added to it.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content) i.e. "all" inc
-// quotes
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-//
-// The result record can be retrieve at any time *this object is
-// instantiated so unless work is done on *this result record then it
-// is
-// possible to return a malformed result record. If nothing has been
-// set
-// or added to *this MI result record object then text "<Invalid>" will
-// be returned.
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//--
-class CMICmnMIResultRecord : public CMICmnBase {
- // Enumerations:
-public:
- //++
- // Details: Enumeration of the result class for *this result record
- //--
- enum ResultClass_e {
- eResultClass_Done = 0,
- eResultClass_Running,
- eResultClass_Connected,
- eResultClass_Error,
- eResultClass_Exit
- };
-
- // Methods:
-public:
- /* ctor */ CMICmnMIResultRecord();
- /* ctor */ CMICmnMIResultRecord(const CMIUtilString &vrToken,
- ResultClass_e veType);
- /* ctor */ CMICmnMIResultRecord(const CMIUtilString &vrToken,
- ResultClass_e veType,
- const CMICmnMIValueResult &vValue);
- //
- const CMIUtilString &GetString() const;
- void Add(const CMICmnMIValue &vMIValue);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIResultRecord() override;
-
- // Attributes:
-private:
- CMIUtilString
- m_strResultRecord; // Holds the text version of the result record to date
-};
diff --git a/tools/lldb-mi/MICmnMIValue.cpp b/tools/lldb-mi/MICmnMIValue.cpp
deleted file mode 100644
index 05ed71e584e0..000000000000
--- a/tools/lldb-mi/MICmnMIValue.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- MICmnMIValue.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnMIValue.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMICmnMIValue constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValue::CMICmnMIValue()
- : m_strValue(MIRSRC(IDS_WORD_INVALIDBRKTS)), m_bJustConstructed(true) {}
-
-//++
-// Details: CMICmnMIValue destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValue::~CMICmnMIValue() {}
-
-//++
-// Details: Return the MI value as a string. The string is a direct result of
-// work done on *this value so if not enough data is added then it is
-// possible to return a malformed value. If nothing has been set or
-// added to *this MI value object then text "<Invalid>" will be
-// returned.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - MI output text.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnMIValue::GetString() const { return m_strValue; }
diff --git a/tools/lldb-mi/MICmnMIValue.h b/tools/lldb-mi/MICmnMIValue.h
deleted file mode 100644
index 8f10c6793616..000000000000
--- a/tools/lldb-mi/MICmnMIValue.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- MICmnMIValue.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result class. Part of the CMICmnMIValueRecord
-// set of objects.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content)
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//--
-class CMICmnMIValue : public CMICmnBase {
- // Methods:
-public:
- /* ctor */ CMICmnMIValue();
- //
- const CMIUtilString &GetString() const;
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIValue() override;
-
- // Attributes:
-protected:
- CMIUtilString m_strValue;
- bool m_bJustConstructed; // True = *this just constructed with no value, false
- // = *this has had value added to it
-};
diff --git a/tools/lldb-mi/MICmnMIValueConst.cpp b/tools/lldb-mi/MICmnMIValueConst.cpp
deleted file mode 100644
index 1cdbc6487b29..000000000000
--- a/tools/lldb-mi/MICmnMIValueConst.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- MICmnMIValueConst.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnMIValueConst.h"
-
-// Instantiations:
-const CMIUtilString CMICmnMIValueConst::ms_constStrDblQuote("\"");
-
-//++
-// Details: CMICmnMIValueConst constructor.
-// Type: Method.
-// Args: vString - (R) MI Const c-string value.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueConst::CMICmnMIValueConst(const CMIUtilString &vString)
- : m_strPartConst(vString), m_bNoQuotes(false) {
- BuildConst();
-}
-
-//++
-// Details: CMICmnMIValueConst constructor.
-// Type: Method.
-// Args: vString - (R) MI Const c-string value.
-// vbNoQuotes - (R) True = return string not surrounded with quotes,
-// false = use quotes.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueConst::CMICmnMIValueConst(const CMIUtilString &vString,
- const bool vbNoQuotes)
- : m_strPartConst(vString), m_bNoQuotes(vbNoQuotes) {
- BuildConst();
-}
-
-//++
-// Details: CMICmnMIValueConst destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueConst::~CMICmnMIValueConst() {}
-
-//++
-// Details: Build the Value Const data.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnMIValueConst::BuildConst() {
- if (m_strPartConst.length() != 0) {
- const CMIUtilString strValue(m_strPartConst.StripCREndOfLine());
- if (m_bNoQuotes) {
- m_strValue = strValue;
- } else {
- const char *pFormat = "%s%s%s";
- m_strValue =
- CMIUtilString::Format(pFormat, ms_constStrDblQuote.c_str(),
- strValue.c_str(), ms_constStrDblQuote.c_str());
- }
- } else {
- const char *pFormat = "%s%s";
- m_strValue = CMIUtilString::Format(pFormat, ms_constStrDblQuote.c_str(),
- ms_constStrDblQuote.c_str());
- }
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnMIValueConst.h b/tools/lldb-mi/MICmnMIValueConst.h
deleted file mode 100644
index 4bac0864c9cf..000000000000
--- a/tools/lldb-mi/MICmnMIValueConst.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- MICmnMIValueConst.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnMIValue.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result class. Part of the CMICmnMIValueConstRecord
-// set of objects.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content)
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//
-// The text formed in *this Result class is stripped of any '\n'
-// characters.
-//--
-class CMICmnMIValueConst : public CMICmnMIValue {
- // Methods:
-public:
- /* ctor */ CMICmnMIValueConst(const CMIUtilString &vString);
- /* ctor */ CMICmnMIValueConst(const CMIUtilString &vString,
- const bool vbNoQuotes);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIValueConst() override;
-
- // Methods:
-private:
- bool BuildConst();
-
- // Attributes:
-private:
- static const CMIUtilString ms_constStrDblQuote;
- //
- CMIUtilString m_strPartConst;
- bool m_bNoQuotes; // True = return string not surrounded with quotes, false =
- // use quotes
-};
diff --git a/tools/lldb-mi/MICmnMIValueList.cpp b/tools/lldb-mi/MICmnMIValueList.cpp
deleted file mode 100644
index 038d3ae36f02..000000000000
--- a/tools/lldb-mi/MICmnMIValueList.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-//===-- MICmnMIValueList.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnMIValueList.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMICmnMIValueList constructor.
-// Type: Method.
-// Args: vbValueTypeList - (R) True = yes value type list, false = result
-// type list.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueList::CMICmnMIValueList(const bool vbValueTypeList) {
- m_strValue = "[]";
-}
-
-//++
-// Details: CMICmnMIValueList constructor.
-// Construct a results only list.
-// return MIstatus::failure.
-// Type: Method.
-// Args: vResult - (R) MI result object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueList::CMICmnMIValueList(const CMICmnMIValueResult &vResult) {
- m_strValue = vResult.GetString();
- BuildList();
- m_bJustConstructed = false;
-}
-
-//++
-// Details: CMICmnMIValueList constructor.
-// Construct a value only list.
-// Type: Method.
-// Args: vValue - (R) MI value object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueList::CMICmnMIValueList(const CMICmnMIValue &vValue) {
- m_strValue = vValue.GetString();
- BuildList();
- m_bJustConstructed = false;
-}
-
-//++
-// Details: CMICmnMIValueList destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueList::~CMICmnMIValueList() {}
-
-//++
-// Details: Build the result value's mandatory data part, one tuple
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueList::BuildList() {
- const char *pFormat = "[%s]";
- m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str());
-}
-
-//++
-// Details: Add another MI result object to the value list's of list is
-// results.
-// Only result objects can be added to a list of result otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vResult - (R) The MI result object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueList::Add(const CMICmnMIValueResult &vResult) {
- BuildList(vResult);
-}
-
-//++
-// Details: Add another MI value object to the value list's of list is values.
-// Only values objects can be added to a list of values otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vValue - (R) The MI value object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueList::Add(const CMICmnMIValue &vValue) { BuildList(vValue); }
-
-//++
-// Details: Add another MI result object to the value list's of list is
-// results.
-// Only result objects can be added to a list of result otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vResult - (R) The MI result object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueList::BuildList(const CMICmnMIValueResult &vResult) {
- // Clear out the default "<Invalid>" text
- if (m_bJustConstructed) {
- m_bJustConstructed = false;
- m_strValue = vResult.GetString();
- BuildList();
- return;
- }
-
- const CMIUtilString data(ExtractContentNoBrackets());
- const char *pFormat = "[%s,%s]";
- m_strValue =
- CMIUtilString::Format(pFormat, data.c_str(), vResult.GetString().c_str());
-}
-
-//++
-// Details: Add another MI value object to the value list's of list is values.
-// Only values objects can be added to a list of values otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vValue - (R) The MI value object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueList::BuildList(const CMICmnMIValue &vValue) {
- // Clear out the default "<Invalid>" text
- if (m_bJustConstructed) {
- m_bJustConstructed = false;
- m_strValue = vValue.GetString();
- BuildList();
- return;
- }
-
- // Remove already present '[' and ']' from the start and end
- m_strValue = m_strValue.Trim();
- size_t len = m_strValue.size();
- if ((len > 1) && (m_strValue[0] == '[') && (m_strValue[len - 1] == ']'))
- m_strValue = m_strValue.substr(1, len - 2);
- const char *pFormat = "[%s,%s]";
- m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str(),
- vValue.GetString().c_str());
-}
-
-//++
-// Details: Retrieve the contents of *this value object but without the outer
-// most
-// brackets.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Data within the object.
-// Throws: None.
-//--
-CMIUtilString CMICmnMIValueList::ExtractContentNoBrackets() const {
- CMIUtilString data(m_strValue);
-
- if (data[0] == '[') {
- data = data.substr(1, data.length() - 1);
- }
- if (data[data.size() - 1] == ']') {
- data = data.substr(0, data.length() - 1);
- }
-
- return data;
-}
diff --git a/tools/lldb-mi/MICmnMIValueList.h b/tools/lldb-mi/MICmnMIValueList.h
deleted file mode 100644
index 76062d0b28d2..000000000000
--- a/tools/lldb-mi/MICmnMIValueList.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- MICmnMIValueList.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnMIValue.h"
-#include "MICmnMIValueResult.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result class. Part of the CMICmnMIValueListRecord
-// set of objects.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content)
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//--
-class CMICmnMIValueList : public CMICmnMIValue {
- // Methods:
-public:
- /* ctor */ CMICmnMIValueList(const bool vbValueTypeList);
- /* ctor */ CMICmnMIValueList(const CMICmnMIValueResult &vResult);
- /* ctor */ CMICmnMIValueList(const CMICmnMIValue &vValue);
- //
- void Add(const CMICmnMIValueResult &vResult);
- void Add(const CMICmnMIValue &vValue);
- CMIUtilString ExtractContentNoBrackets() const;
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIValueList() override;
-
- // Methods:
-private:
- void BuildList();
- void BuildList(const CMICmnMIValueResult &vResult);
- void BuildList(const CMICmnMIValue &vResult);
-};
diff --git a/tools/lldb-mi/MICmnMIValueResult.cpp b/tools/lldb-mi/MICmnMIValueResult.cpp
deleted file mode 100644
index 5ef60741342b..000000000000
--- a/tools/lldb-mi/MICmnMIValueResult.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//===-- MICmnMIValueResult.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnMIValueResult.h"
-#include "MICmnResources.h"
-
-// Instantiations:
-const CMIUtilString CMICmnMIValueResult::ms_constStrEqual("=");
-
-//++
-// Details: CMICmnMIValueResult constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueResult::CMICmnMIValueResult() : m_bEmptyConstruction(true) {}
-
-//++
-// Details: CMICmnMIValueResult constructor.
-// Type: Method.
-// Args: vrVariable - (R) MI value's name.
-// vrValue - (R) The MI value.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueResult::CMICmnMIValueResult(const CMIUtilString &vrVariable,
- const CMICmnMIValue &vrValue)
- : m_strPartVariable(vrVariable), m_partMIValue(vrValue),
- m_bEmptyConstruction(false), m_bUseSpacing(false) {
- BuildResult();
-}
-
-//++
-// Details: CMICmnMIValueResult constructor.
-// Type: Method.
-// Args: vrVariable - (R) MI value's name.
-// vrValue - (R) The MI value.
-// vbUseSpacing - (R) True = put space separators into the string,
-// false = no spaces used.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueResult::CMICmnMIValueResult(const CMIUtilString &vrVariable,
- const CMICmnMIValue &vrValue,
- const bool vbUseSpacing)
- : m_strPartVariable(vrVariable), m_partMIValue(vrValue),
- m_bEmptyConstruction(false), m_bUseSpacing(vbUseSpacing) {
- BuildResult();
-}
-
-//++
-// Details: CMICmnMIValueResult destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueResult::~CMICmnMIValueResult() {}
-
-//++
-// Details: Build the MI value result string.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueResult::BuildResult() {
- const char *pFormat = m_bUseSpacing ? "%s %s %s" : "%s%s%s";
- m_strValue = CMIUtilString::Format(pFormat, m_strPartVariable.c_str(),
- ms_constStrEqual.c_str(),
- m_partMIValue.GetString().c_str());
-}
-
-//++
-// Details: Build the MI value result string.
-// Type: Method.
-// Args: vrVariable - (R) MI value's name.
-// vrValue - (R) The MI value.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueResult::BuildResult(const CMIUtilString &vVariable,
- const CMICmnMIValue &vValue) {
- const char *pFormat = m_bUseSpacing ? "%s, %s %s %s" : "%s,%s%s%s";
- m_strValue = CMIUtilString::Format(
- pFormat, m_strValue.c_str(), vVariable.c_str(), ms_constStrEqual.c_str(),
- vValue.GetString().c_str());
-}
-
-//++
-// Details: Append another MI value object to *this MI value result.
-// Type: Method.
-// Args: vrVariable - (R) MI value's name.
-// vrValue - (R) The MI value.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void CMICmnMIValueResult::Add(const CMIUtilString &vrVariable,
- const CMICmnMIValue &vrValue) {
- if (!m_bEmptyConstruction)
- BuildResult(vrVariable, vrValue);
- else {
- m_bEmptyConstruction = false;
- m_strPartVariable = vrVariable;
- m_partMIValue = vrValue;
- BuildResult();
- }
-}
diff --git a/tools/lldb-mi/MICmnMIValueResult.h b/tools/lldb-mi/MICmnMIValueResult.h
deleted file mode 100644
index cfa101b86a5e..000000000000
--- a/tools/lldb-mi/MICmnMIValueResult.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- MICmnMIValueResult.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnMIValue.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result class. Part of the
-// CMICmnMIValueResultRecord
-// set of objects.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content)
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//--
-class CMICmnMIValueResult : public CMICmnMIValue {
- // Methods:
-public:
- /* ctor */ CMICmnMIValueResult();
- /* ctor */ CMICmnMIValueResult(const CMIUtilString &vVariable,
- const CMICmnMIValue &vValue);
- /* ctor */ CMICmnMIValueResult(const CMIUtilString &vVariable,
- const CMICmnMIValue &vValue,
- const bool vbUseSpacing);
- //
- void Add(const CMIUtilString &vVariable, const CMICmnMIValue &vValue);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIValueResult() override;
-
- // Methods:
-private:
- void BuildResult();
- void BuildResult(const CMIUtilString &vVariable, const CMICmnMIValue &vValue);
-
- // Attributes:
-private:
- static const CMIUtilString ms_constStrEqual;
- //
- CMIUtilString m_strPartVariable;
- CMICmnMIValue m_partMIValue;
- bool m_bEmptyConstruction; // True = *this object used constructor with no
- // parameters, false = constructor with parameters
- bool m_bUseSpacing; // True = put space separators into the string, false = no
- // spaces used
-};
diff --git a/tools/lldb-mi/MICmnMIValueTuple.cpp b/tools/lldb-mi/MICmnMIValueTuple.cpp
deleted file mode 100644
index 2f05d219d4fc..000000000000
--- a/tools/lldb-mi/MICmnMIValueTuple.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//===-- MICmnMIValueTuple.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnMIValueTuple.h"
-
-//++
-// Details: CMICmnMIValueTuple constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueTuple::CMICmnMIValueTuple() : m_bSpaceAfterComma(false) {
- m_strValue = "{}";
-}
-
-//++
-// Details: CMICmnMIValueTuple constructor.
-// Type: Method.
-// Args: vResult - (R) MI result object.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueTuple::CMICmnMIValueTuple(const CMICmnMIValueResult &vResult)
- : m_bSpaceAfterComma(false) {
- m_strValue = vResult.GetString();
- BuildTuple();
- m_bJustConstructed = false;
-}
-
-//++
-// Details: CMICmnMIValueTuple constructor.
-// Type: Method.
-// Args: vResult - (R) MI result object.
-// vbUseSpacing - (R) True = put space separators into the string,
-// false = no spaces used.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueTuple::CMICmnMIValueTuple(const CMICmnMIValueResult &vResult,
- const bool vbUseSpacing)
- : m_bSpaceAfterComma(vbUseSpacing) {
- m_strValue = vResult.GetString();
- BuildTuple();
- m_bJustConstructed = false;
-}
-
-//++
-// Details: CMICmnMIValueTuple destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnMIValueTuple::~CMICmnMIValueTuple() {}
-
-//++
-// Details: Build the result value's mandatory data part, one tuple
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::BuildTuple() {
- const char *pFormat = "{%s}";
- m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str());
-}
-
-//++
-// Details: Add another MI result object to the value's list of tuples.
-// Type: Method.
-// Args: vResult - (R) The MI result object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::BuildTuple(const CMICmnMIValueResult &vResult) {
- // Clear out the default "<Invalid>" text
- if (m_bJustConstructed) {
- m_bJustConstructed = false;
- m_strValue = vResult.GetString();
- BuildTuple();
- return;
- }
-
- if (m_strValue[0] == '{') {
- m_strValue = m_strValue.substr(1, m_strValue.size() - 1);
- }
- if (m_strValue[m_strValue.size() - 1] == '}') {
- m_strValue = m_strValue.substr(0, m_strValue.size() - 1);
- }
-
- const char *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
- m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str(),
- vResult.GetString().c_str());
-}
-
-//++
-// Details: Add string value to the value's list of tuples.
-// Type: Method.
-// Args: vValue - (R) The string object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::BuildTuple(const CMIUtilString &vValue) {
- // Clear out the default "<Invalid>" text
- if (m_bJustConstructed) {
- m_bJustConstructed = false;
- m_strValue = vValue;
- BuildTuple();
- return;
- }
-
- const CMIUtilString data(ExtractContentNoBrackets());
- const char *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
- m_strValue = CMIUtilString::Format(pFormat, data.c_str(), vValue.c_str());
-}
-
-//++
-// Details: Add another MI value object to the value list's of list is values.
-// Only values objects can be added to a list of values otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vValue - (R) The MI value object.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::Add(const CMICmnMIValueResult &vResult) {
- BuildTuple(vResult);
-}
-
-//++
-// Details: Add another MI value object to the value list's of list is values.
-// Only values objects can be added to a list of values otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vValue - (R) The MI value object.
-// vbUseSpacing - (R) True = put space separators into the string,
-// false = no spaces used.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::Add(const CMICmnMIValueResult &vResult,
- const bool vbUseSpacing) {
- m_bSpaceAfterComma = vbUseSpacing;
- BuildTuple(vResult);
-}
-
-//++
-// Details: Add another MI value object to the value list's of list is values.
-// Only values objects can be added to a list of values otherwise this
-// function
-// will return MIstatus::failure.
-// Type: Method.
-// Args: vValue - (R) The MI value object.
-// vbUseSpacing - (R) True = put space separators into the string,
-// false = no spaces used.
-// Return: None.
-// Throws: None.
-//--
-void CMICmnMIValueTuple::Add(const CMICmnMIValueConst &vValue,
- const bool vbUseSpacing) {
- m_bSpaceAfterComma = vbUseSpacing;
- BuildTuple(vValue.GetString());
-}
-
-//++
-// Details: Retrieve the contents of *this value object but without the outer
-// most
-// brackets.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Data within the object.
-// Throws: None.
-//--
-CMIUtilString CMICmnMIValueTuple::ExtractContentNoBrackets() const {
- CMIUtilString data(m_strValue);
-
- if (data[0] == '{') {
- data = data.substr(1, data.length() - 1);
- }
- if (data[data.size() - 1] == '}') {
- data = data.substr(0, data.length() - 1);
- }
-
- return data;
-}
diff --git a/tools/lldb-mi/MICmnMIValueTuple.h b/tools/lldb-mi/MICmnMIValueTuple.h
deleted file mode 100644
index 4a04fd9214e6..000000000000
--- a/tools/lldb-mi/MICmnMIValueTuple.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- MICmnMIValueTuple.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnMIValue.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnMIValueResult.h"
-
-//++
-//============================================================================
-// Details: MI common code MI Result class. Part of the CMICmnMIValueTupleRecord
-// set of objects.
-// The syntax is as follows:
-// result-record ==> [ token ] "^" result-class ( "," result )* nl
-// token = any sequence of digits
-// * = 0 to many
-// nl = CR | CR_LF
-// result-class ==> "done" | "running" | "connected" | "error" | "exit"
-// result ==> variable "=" value
-// value ==> const | tuple | list
-// const ==> c-string (7 bit iso c string content)
-// tuple ==> "{}" | "{" result ( "," result )* "}"
-// list ==> "[]" | "[" value ( "," value )* "]" | "[" result ( ","
-// result )* "]"
-// More information see:
-// http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_22.html
-//--
-class CMICmnMIValueTuple : public CMICmnMIValue {
- // Methods:
-public:
- /* ctor */ CMICmnMIValueTuple();
- /* ctor */ CMICmnMIValueTuple(const CMICmnMIValueResult &vResult);
- /* ctor */ CMICmnMIValueTuple(const CMICmnMIValueResult &vResult,
- const bool vbUseSpacing);
- //
- void Add(const CMICmnMIValueResult &vResult);
- void Add(const CMICmnMIValueResult &vResult, const bool vbUseSpacing);
- void Add(const CMICmnMIValueConst &vValue, const bool vbUseSpacing);
- CMIUtilString ExtractContentNoBrackets() const;
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMICmnMIValueTuple() override;
-
- // Methods:
-private:
- void BuildTuple();
- void BuildTuple(const CMICmnMIValueResult &vResult);
- void BuildTuple(const CMIUtilString &vValue);
-
- // Attributes:
-private:
- bool m_bSpaceAfterComma; // True = put space separators into the string, false
- // = no spaces used
-};
diff --git a/tools/lldb-mi/MICmnResources.cpp b/tools/lldb-mi/MICmnResources.cpp
deleted file mode 100644
index 3925f0b01dc5..000000000000
--- a/tools/lldb-mi/MICmnResources.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-//===-- MICmnResources.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers
-#include "assert.h"
-#include <inttypes.h>
-
-// In-house headers:
-#include "MICmnResources.h"
-
-// Instantiations:
-const CMICmnResources::SRsrcTextData
- CMICmnResources::ms_pResourceId2TextData[] = {
- {IDS_PROJNAME,
- "LLDB Machine Interface Driver (MI) All rights reserved"},
- {IDS_MI_VERSION_DESCRIPTION_DEBUG,
- "Version: 1.0.0.9 (Debug)"}, // See version history in MIDriverMain.cpp
- {IDS_MI_VERSION_DESCRIPTION, "Version: 1.0.0.9"},
- {IDS_MI_APPNAME_SHORT, "MI"},
- {IDS_MI_APPNAME_LONG, "Machine Interface Driver"},
- {IDS_MI_APP_FILEPATHNAME, "Application: %s"},
- {IDS_MI_APP_ARGS, "Command line args: "},
- {IDE_MI_VERSION_GDB, "Version: GNU gdb (GDB) 7.4 \n(This is a MI stub "
- "on top of LLDB and not GDB)\nAll rights "
- "reserved.\n"}, // *** Eclipse needs this
- // exactly!!
- {IDS_UTIL_FILE_ERR_INVALID_PATHNAME,
- "File Handler. Invalid file name path"},
- {IDS_UTIL_FILE_ERR_OPENING_FILE, "File Handler. Error %s opening '%s'"},
- {IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN,
- "File Handler. Unknown error opening '%s'"},
- {IDE_UTIL_FILE_ERR_WRITING_FILE, "File Handler. Error %s writing '%s'"},
- {IDE_UTIL_FILE_ERR_WRITING_NOTOPEN,
- "File Handler. File '%s' not open for write"},
- {IDS_RESOURCES_ERR_STRING_NOT_FOUND,
- "Resources. String (%d) not found in resources"},
- {IDS_RESOURCES_ERR_STRING_TABLE_INVALID,
- "Resources. String resource table is not set up"},
- {IDS_MI_CLIENT_MSG, "Client message: \"%s\""},
- {IDS_LOG_MSG_CREATION_DATE, "Creation date %s time %s%s"},
- {IDS_LOG_MSG_FILE_LOGGER_PATH, "File logger path: %s%s"},
- {IDS_LOG_MSG_VERSION, "Version: %s%s"},
- {IDS_LOG_ERR_FILE_LOGGER_DISABLED,
- "Log. File logger temporarily disabled due to file error '%s'"},
- {IDS_LOG_MEDIUM_ERR_INIT, "Log. Medium '%s' initialise failed. %s"},
- {IDS_LOG_MEDIUM_ERR_WRITE_ANY,
- "Log. Failed to write log data to any medium."},
- {IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL,
- "Log. One or mediums failed writing log data."},
- {IDS_MEDIUMFILE_NAME, "File"},
- {IDS_MEDIUMFILE_ERR_INVALID_PATH, "<Invalid - not set>"},
- {IDS_MEDIUMFILE_ERR_FILE_HEADER, "<Invalid - header not set>"},
- {IDS_MEDIUMFILE_NAME_LOG, "File medium. %s"},
- {IDE_OS_ERR_UNKNOWN, "Unknown OS error"},
- {IDE_OS_ERR_RETRIEVING, "Unabled to retrieve OS error message"},
- {IDS_DRIVERMGR_DRIVER_ERR_INIT,
- "Driver Manager. Driver '%s' (ID:'%s') initialise failed. %s"},
- {IDE_MEDIUMSTDERR_NAME, "Stderr"},
- {IDE_MEDIUMSTDOUT_NAME, "Stdout"},
- {IDE_MI_APP_DESCRIPTION,
- "Description:\nThe Machine Interface Driver (MI Driver) is a stand "
- "alone executable\nthat either be used via "
- "a client i.e. Eclipse or directly from the command\nline. It "
- "processes MI commands, actions those commands "
- "using the internal\ndebugger then forms MI response formatted text "
- "which is returned to the\nclient."},
- {IDE_MI_APP_INFORMATION,
- "Information:\nCurrent limitations. The MI Driver currently only "
- "handles remote target\ndebugging. Local "
- "debugging has not been implemented. The MI Driver has\nbeen designed "
- "primarily to be used with Eclipse Juno "
- "and a custom plugin.\nThe custom plugin is not necessary to operate "
- "the MI Driver."},
- {IDE_MI_APP_ARG_USAGE, "\nMI driver usage:\n\n\tlldb-mi [--longOption] "
- "[-s hortOption] [executable]\n\n[] = optional "
- "argument."},
- {IDE_MI_APP_ARG_HELP, "-h\n--help\n\tPrints out usage information for "
- "the MI debugger. Exit the MI\n\tDriver "
- "immediately."},
- {IDE_MI_APP_ARG_VERSION, "--version\n\tPrints out GNU (gdb) version "
- "information. Exit the MI "
- "Driver\n\timmediately."},
- {IDE_MI_APP_ARG_VERSION_LONG, "--versionLong\n\tPrints out MI Driver "
- "version information. Exit the MI "
- "Driver\n\timmediately."},
- {IDE_MI_APP_ARG_INTERPRETER, "--interpreter\n\t This option is kept "
- "for backward compatibility. This "
- "executable always run in MI mode"},
- {IDE_MI_APP_ARG_EXECUTEABLE, "--executable\n\tUse the MI Driver in MI "
- "mode for the debugging the specified "
- "executable."},
- {IDE_MI_APP_ARG_SOURCE, "-s <filename>\n--source <filename>\n\t"
- "Tells the debugger to read in and execute the "
- "lldb commands in the\n\t"
- "given file, after any file provided on the "
- "command line has been\n\tloaded."},
- {IDE_MI_APP_ARG_APP_LOG, "--log\n\tUse this argument to tell the MI "
- "Driver to update it's log\n\tfile '%s'."},
- {IDE_MI_APP_ARG_APP_LOG_DIR,
- "--log-dir\n\tUse this argument to specify the directory the MI "
- "Driver\n\twill place the log file in, i.e --log-dir=/tmp."},
- {IDE_MI_APP_ARG_EXAMPLE, "Example MI command:\n\t3-info-gdb-mi-command "
- "gdb-set\n\t3^done,command={exists=\"true\"}"},
- {IDE_MI_APP_ARG_EXECUTABLE, "executable (NOT IMPLEMENTED)\n\tThe file "
- "path to the executable i.e. '\"C:\\My "
- "Dev\\foo.exe\"'."},
- {IDE_MI_APP_ARG_SYNCHRONOUS, "--synchronous\n\tBlock until each command "
- "has finished executing.\n\tUsed for testing only."},
- {IDS_STDIN_ERR_INVALID_PROMPT,
- "Stdin. Invalid prompt description '%s'"},
- {IDS_STDIN_ERR_THREAD_CREATION_FAILED,
- "Stdin. Thread creation failed '%s'"},
- {IDS_STDIN_ERR_THREAD_DELETE, "Stdin. Thread failed to delete '%s'"},
- {IDS_STDIN_ERR_CHKING_BYTE_AVAILABLE,
- "Stdin. Peeking on stdin stream '%s'"},
- {IDS_STDIN_INPUT_CTRL_CHARS,
- "Stdin. Receive characters not handled as a command: "},
- {IDS_CMD_QUIT_HELP,
- "MI Driver Command: quit\n\tExit the MI Driver application."},
- {IDS_THREADMGR_ERR_THREAD_ID_INVALID,
- "Thread Mgr. Thread ID '%s' is not valid"},
- {IDS_THREADMGR_ERR_THREAD_FAIL_CREATE,
- "Thread Mgr: Failed to create thread '%s'"},
- {IDS_THREADMGR_ERR_THREAD_ID_NOT_FOUND,
- "Thread Mgr: Thread with ID '%s' not found"},
- {IDS_THREADMGR_ERR_THREAD_STILL_ALIVE, "Thread Mgr: The thread(s) are "
- "still alive at Thread Mgr "
- "shutdown: %s"},
- {IDS_FALLTHRU_DRIVER_CMD_RECEIVED,
- "Fall Thru Driver. Received command '%s'. Is was %shandled"},
- {IDS_CMDFACTORY_ERR_INVALID_CMD_NAME,
- "Command factory. MI command name '%s' is invalid"},
- {IDS_CMDFACTORY_ERR_INVALID_CMD_CR8FN,
- "Command factory. Command creation function invalid for command '%s'. "
- "Does function exist? Pointer assigned to it?"},
- {IDS_CMDFACTORY_ERR_CMD_NOT_REGISTERED,
- "Command factory. Command '%s' not registered"},
- {IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED,
- "Command factory. Command '%s' by that name already registered"},
- {IDS_CMDMGR_ERR_CMD_FAILED_CREATE,
- "Command manager. Command creation failed. %s"},
- {IDS_CMDMGR_ERR_CMD_INVOKER, "Command manager. %s "},
- {IDS_MI_INIT_ERR_LOG, "Log. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_RESOURCES,
- "Resources. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_INIT,
- "Driver. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_STREAMSTDIN,
- "Stdin. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER, "Stdin. The OS specific stdin "
- "stream handler has not been "
- "specified for this OS"},
- {IDS_MI_INIT_ERR_OS_STDIN_HANDLER,
- "Stdin handler. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_STREAMSTDOUT,
- "Stdout. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_STREAMSTDERR,
- "Stderr. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_FALLTHRUDRIVER,
- "Fall Through Driver. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_THREADMGR,
- "Thread Mgr. Error occurred during initialisation %s"},
- {IDS_MI_INIT_ERR_CMDINTERPRETER, "Command interpreter. %s"},
- {IDS_MI_INIT_ERR_CMDMGR, "Command manager. %s"},
- {IDS_MI_INIT_ERR_CMDFACTORY, "Command factory. %s"},
- {IDS_MI_INIT_ERR_CMDINVOKER, "Command invoker. %s"},
- {IDS_MI_INIT_ERR_CMDMONITOR, "Command monitor. %s"},
- {IDS_MI_INIT_ERR_LLDBDEBUGGER, "LLDB Debugger. %s"},
- {IDS_MI_INIT_ERR_DRIVERMGR, "Driver manager. %s"},
- {IDS_MI_INIT_ERR_DRIVER, "Driver. %s"},
- {IDS_MI_INIT_ERR_OUTOFBANDHANDLER, "Out-of-band handler. %s "},
- {IDS_MI_INIT_ERR_DEBUGSESSIONINFO, "LLDB debug session info. %s "},
- {IDS_MI_INIT_ERR_THREADMANAGER, "Unable to init thread manager."},
- {IDS_MI_INIT_ERR_CLIENT_USING_DRIVER,
- "Initialising the client to this driver failed."},
- {IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION,
- "Initialising a local debug session failed."},
- {IDS_CODE_ERR_INVALID_PARAMETER_VALUE,
- "Code. Invalid parameter passed to function '%s'"},
- {IDS_CODE_ERR_INVALID_PARAM_NULL_POINTER,
- "Code. NULL pointer passes as a parameter to function '%s'"},
- {IDS_CODE_ERR_INVALID_ENUMERATION_VALUE,
- "Code. Invalid enumeration value encountered in function '%s'"},
- {
- IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER,
- "LLDB Debugger. LLDB Listener is not valid",
- },
- {
- IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER,
- "LLDB Debugger. LLDB Debugger is not valid",
- },
- {IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER,
- "LLDB Debugger. CMIDriverBase derived driver needs to be set prior to "
- "CMICmnLLDBDDebugger initialisation"},
- {IDS_LLDBDEBUGGER_ERR_STARTLISTENER,
- "LLDB Debugger. Starting listening events for '%s' failed"},
- {IDS_LLDBDEBUGGER_ERR_THREADCREATIONFAIL,
- "LLDB Debugger. Thread creation failed '%s'"},
- {IDS_LLDBDEBUGGER_ERR_THREAD_DELETE,
- "LLDB Debugger. Thread failed to delete '%s'"},
- {IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER,
- "LLDB Debugger. Invalid SB broadcaster class name '%s' "},
- {IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME,
- "LLDB Debugger. Invalid client name '%s' "},
- {IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED,
- "LLDB Debugger. Client name '%s' not registered for listening events"},
- {IDS_LLDBDEBUGGER_ERR_STOPLISTENER, "LLDB Debugger. Failure occurred "
- "stopping event for client '%s' "
- "SBBroadcaster '%s'"},
- {IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME,
- "LLDB Debugger. Broadcaster's name '%s' is not valid"},
- {IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT,
- "LLDB Debugger. Unhandled event '%s'"},
- {IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT,
- "LLDB Out-of-band. Handling event for '%s', an event enumeration '%d' "
- "not recognised"},
- {IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID,
- "LLDB Out-of-band. Invalid '%s' in '%s'"},
- {IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND, "LLDB Out-of-band. %s. "
- "Breakpoint information for "
- "breakpoint ID %d not found"},
- {IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET,
- "LLDB Out-of-band. %s. Failed to retrieve breakpoint information for "
- "for breakpoint ID %d"},
- {IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET, "LLDB Out-of-band. %s. Failed "
- "to set breakpoint information "
- "for for breakpoint ID %d"},
- {IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE,
- "LLDB Out-of-band. %s. Failed to form the MI Out-of-band response"},
- {IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET,
- "LLDB Out-of-band. %s. Failed to retrieve frame information"},
- {IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE,
- "LLDB Out-of-band. %s. Event handler tried to set new MI Driver "
- "running state and failed. %s"},
- {IDS_LLDBOUTOFBAND_ERR_BRKPT_CNT_EXCEEDED,
- "LLDB Out-of-band. '%s'. Number of valid breakpoint exceeded %d. "
- "Cannot create new breakpoint with ID %d"},
- {IDS_DBGSESSION_ERR_SHARED_DATA_ADD, "LLDB debug session info. Failed "
- "to add '%s' data to the shared "
- "data command container"},
- {IDS_MI_SHTDWN_ERR_LOG, "Log. Error occurred during shutdown. %s"},
- {IDS_MI_SHUTDOWN_ERR, "Server shutdown failure. %s"},
- {IDE_MI_SHTDWN_ERR_RESOURCES,
- "Resources. Error occurred during shutdown. %s"},
- {IDE_MI_SHTDWN_ERR_STREAMSTDIN,
- "Stdin. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER,
- "Stdin handler. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_STREAMSTDOUT,
- "Stdout. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_STREAMSTDERR,
- "Stderr. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_THREADMGR,
- "Thread Mgr. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_CMDINTERPRETER,
- "Command interpreter. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_CMDMGR,
- "Command manager. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_CMDFACTORY,
- "Command factory. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_CMDMONITOR,
- "Command invoker. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_CMDINVOKER,
- "Command monitor. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_LLDBDEBUGGER,
- "LLDB Debugger. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_DRIVERMGR,
- "Driver manager. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_DRIVER,
- "Driver. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_OUTOFBANDHANDLER,
- "Out-of-band handler. Error occurred during shutdown. %s"},
- {IDS_MI_SHTDWN_ERR_DEBUGSESSIONINFO,
- "LLDB debug session info. Error occurred during shutdown. %s"},
- {IDE_MI_SHTDWN_ERR_THREADMANAGER, "Unable to shutdown thread manager"},
- {IDS_DRIVER_ERR_PARSE_ARGS,
- "Driver. Driver '%s'. Parse args error '%s'"},
- {IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN,
- "Driver. Driver '%s'. Parse args error unknown"},
- {IDS_DRIVER_ERR_CURRENT_NOT_SET,
- "Driver. Current working driver has not been set. Call "
- "CMIDriverMgr::SetUseThisDriverToDoWork()"},
- {IDS_DRIVER_ERR_NON_REGISTERED, "Driver. No suitable drivers "
- "registered with the CMIDriverMgr to "
- "do work"},
- {IDS_DRIVER_SAY_DRIVER_USING, "Driver. Using driver '%s' internally"},
- {IDS_DRIVER_ERR_ID_INVALID, "Driver. Driver '%s' invalid ID '%s'"},
- {IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR,
- "Driver. Fall through driver '%s' (ID:'%s') error '%s'"},
- {IDS_DRIVER_CMD_RECEIVED,
- "Driver. Received command '%s'. It was %shandled%s"},
- {IDS_DRIVER_CMD_NOT_IN_FACTORY,
- ". Command '%s' not in Command Factory"},
- {
- IDS_DRIVER_ERR_DRIVER_STATE_ERROR,
- "Driver. Driver running state error. Cannot go to next state from "
- "present state as not allowed",
- },
- {IDS_DRIVER_WAITING_STDIN_DATA, "Driver. Main thread suspended waiting "
- "on Stdin Monitor to resume main "
- "thread"},
- {IDS_DRIVER_ERR_MAINLOOP, "Driver. Error in do main loop. %s"},
- {IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL, "Driver. --executable argument "
- "given. Local debugging is not "
- "implemented."},
- {IDS_DRIVER_ERR_LOCAL_DEBUG_INIT, "Driver. --executable argument "
- "given. Initialising local debugging "
- "failed."},
- {IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN,
- "Stderr. Not all data was written to stream. The data '%s'"},
- {IDS_CMD_ARGS_ERR_OPTION_NOT_FOUND,
- "Command Args. Option '%s' not found"},
- {IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY, "Mandatory args not found: %s"},
- {IDS_CMD_ARGS_ERR_VALIDATION_INVALID, "Invalid args: %s"},
- {IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID,
- "Mandatory args not found: %s. Invalid args: %s"},
- {IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF,
- "Args missing additional information: %s"},
- {IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN,
- "Not all arguments or options were recognised: %s"},
- {IDS_CMD_ARGS_ERR_PREFIX_MSG, "Command Args. Validation failed. "},
- {IDS_VARIANT_ERR_USED_BASECLASS, "Variant container: Variant object "
- "used the base class. See "
- "CMIUtilVariant"},
- {IDS_VARIANT_ERR_MAP_KEY_INVALID, "Variant container: Invalid ID '%s'"},
- {IDS_WORD_INVALIDBRKTS, "<Invalid>"},
- {IDS_WORD_NONE, "None"},
- {IDS_WORD_NOT, "not"},
- {IDS_WORD_INVALIDEMPTY, "<empty>"},
- {IDS_WORD_INVALIDNULLPTR, "<NULL ptr>"},
- {IDS_WORD_UNKNOWNBRKTS, "<unknown>"},
- {IDS_WORD_NOT_IMPLEMENTED, "Not implemented"},
- {IDS_WORD_NOT_IMPLEMENTED_BRKTS, "<not implemented>"},
- {IDS_WORD_UNKNOWNTYPE_BRKTS, "<unknowntype>"},
- {IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS,
- "<error message not implemented>"},
- {IDS_CMD_ERR_N_OPTIONS_REQUIRED,
- "Command '%s'. Missing options, %d required"},
- {IDS_CMD_ERR_OPTION_NOT_FOUND, "Command '%s'. Option '%s' not found"},
- {IDS_CMD_ERR_ARGS, "Command '%s'. %s"},
- {IDS_CMD_WRN_ARGS_NOT_HANDLED, "Command '%s'. Warning the following "
- "options not handled by the command: "
- "%s"},
- {IDS_CMD_ERR_FNFAILED, "Command '%s'. Fn '%s' failed"},
- {IDS_CMD_ERR_SHARED_DATA_NOT_FOUND,
- "Command '%s'. Shared data '%s' not found"},
- {IDS_CMD_ERR_LLDBPROCESS_DETACH,
- "Command '%s'. Process detach failed. '%s'"},
- {IDS_CMD_ERR_LLDBPROCESS_DESTROY,
- "Command '%s'. Process destroy failed. '%s'"},
- {IDS_CMD_ERR_SETWKDIR,
- "Command '%s'. Failed to set working directory '%s'"},
- {IDS_CMD_ERR_INVALID_TARGET,
- "Command '%s'. Target binary '%s' is invalid. %s"},
- {IDS_CMD_ERR_INVALID_TARGET_CURRENT,
- "Command '%s'. Current SBTarget is invalid"},
- {IDS_CMD_ERR_INVALID_TARGET_TYPE,
- "Command '%s'. Target type '%s' is not recognised"},
- {IDS_CMD_ERR_INVALID_TARGET_PLUGIN,
- "Command '%s'. Target plugin is invalid. %s"},
- {IDS_CMD_ERR_CONNECT_TO_TARGET,
- "Command '%s'. Error connecting to target: '%s'"},
- {IDS_CMD_ERR_INVALID_TARGETPLUGINCURRENT,
- "Command '%s'. Current target plugin is invalid"},
- {IDS_CMD_ERR_NOT_IMPLEMENTED, "Command '%s'. Command not implemented"},
- {IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED,
- "Command '%s'. Command not implemented as it has been deprecated"},
- {IDS_CMD_ERR_CREATE_TARGET, "Command '%s'. Create target failed: %s"},
- {IDS_CMD_ERR_BRKPT_LOCATION_FORMAT,
- "Command '%s'. Incorrect format for breakpoint location '%s'"},
- {IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND,
- "Command '%s'. Breakpoint location '%s' not found"},
- {IDS_CMD_ERR_BRKPT_INVALID, "Command '%s'. Breakpoint '%s' invalid"},
- {IDS_CMD_ERR_BRKPT_CNT_EXCEEDED, "Command '%s'. Number of valid "
- "breakpoint exceeded %d. Cannot "
- "create new breakpoint '%s'"},
- {IDS_CMD_ERR_SOME_ERROR, "Command '%s'. Error: %s"},
- {IDS_CMD_ERR_THREAD_INVALID, "Command '%s'. Thread ID invalid"},
- {IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID,
- "Command '%s'. Thread frame range invalid"},
- {IDS_CMD_ERR_FRAME_INVALID, "Command '%s'. Frame ID invalid"},
- {IDS_CMD_ERR_VARIABLE_DOESNOTEXIST,
- "Command '%s'. Variable '%s' does not exist"},
- {IDS_CMD_ERR_VARIABLE_ENUM_INVALID, "Command '%s'. Invalid enumeration "
- "for variable '%s' formatted "
- "string '%s'"},
- {IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH,
- "Command '%s'. Failed to get expression for variable '%s'"},
- {IDS_CMD_ERR_VARIABLE_CREATION_FAILED,
- "Failed to create variable object for '%s'"},
- {IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID,
- "Command '%s'. Variable children range invalid"},
- {IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION, "<Error: Command run but command "
- "did not do anything useful. No MI "
- "response formed>"},
- {IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION,
- "<Error: Command run and event caught, did nothing useful. No MI "
- "Out-of-Bound formed>"},
- {IDS_CMD_ERR_DISASM_ADDR_START_INVALID,
- "Command '%s'. Invalid start value '%s'"},
- {IDS_CMD_ERR_DISASM_ADDR_END_INVALID,
- "Command '%s'. Invalid end value '%s'"},
- {IDS_CMD_ERR_MEMORY_ALLOC_FAILURE,
- "Command '%s'. Failed to allocate memory %d bytes"},
- {IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK,
- "Command '%s'. LLDB unable to read entire memory block of %u bytes at "
- "address 0x%016" PRIx64},
- {IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to read "
- "memory block of %u bytes at "
- "address 0x%016" PRIx64 ": %s "},
- {IDS_CMD_ERR_INVALID_PROCESS,
- "Command '%s'. Invalid process during debug session"},
- {IDS_CMD_ERR_INVALID_PRINT_VALUES,
- "Command '%s'. Unknown value for PRINT_VALUES: must be: 0 or "
- "\"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\""},
- {IDS_CMD_ERR_INVALID_LOCATION_FORMAT,
- "Command '%s'. Invalid location format '%s'"},
- {IDS_CMD_ERR_INVALID_FORMAT_TYPE,
- "Command '%s'. Invalid var format type '%s'"},
- {IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND,
- "Command '%s'. Breakpoint information for breakpoint ID %d not found"},
- {IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES, "Command '%s'. Unable to write "
- "memory block of %u bytes at "
- "address 0x%016" PRIx64 ": %s "},
- {IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK,
- "Command '%s'. LLDB unable to write entire memory block of %u bytes "
- "at address 0x%016" PRIX64},
- {IDS_CMD_ERR_SET_NEW_DRIVER_STATE, "Command '%s'. Command tried to set "
- "new MI Driver running state and "
- "failed. %s"},
- {IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND,
- "The request '%s' was not recognised, not implemented"},
- {IDS_CMD_ERR_INFO_PRINTFN_FAILED, "The request '%s' failed."},
- {IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC,
- "'target-async' expects \"on\" or \"off\""},
- {IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT,
- "'breakpoint' expects \"pending on\" or \"pending off\""},
- {IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH,
- "'solib-search-path' requires at least one argument"},
- {IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS,
- "'print' expects option-name and \"on\" or \"off\""},
- {IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION,
- "'print' error. The option '%s' not found"},
- {IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS,
- "'print' expects option-name and \"on\" or \"off\""},
- {IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION,
- "'print' error. The option '%s' not found"},
- {IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS,
- "'breakpoint' expects option-name"},
- {IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION,
- "'breakpoint' error. The option '%s' not found"},
- {IDS_CMD_ERR_EXPR_INVALID, "Failed to evaluate expression: %s"},
- {IDS_CMD_ERR_ATTACH_FAILED,
- "Command '%s'. Attach to process failed: %s"},
- {IDS_CMD_ERR_ATTACH_BAD_ARGS,
- "Command '%s'. Must specify either a PID or a Name"}};
-
-//++
-// Details: CMICmnResources constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnResources::CMICmnResources() : m_nResourceId2TextDataSize(0) {
- // Do not use this constructor, use Initialize()
-}
-
-//++
-// Details: CMICmnResources destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnResources::~CMICmnResources() {
- // Do not use this destructor, use Shutdown()
-}
-
-//++
-// Details: Initialize the resources and set locality for the server.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnResources::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = ReadResourceStringData();
-
- return m_bInitialized;
-}
-
-//++
-// Details: Release resources for *this object.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnResources::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- // Tear down resource explicitly
- m_mapRscrIdToTextData.clear();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Initialize the resources and set locality for the server.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnResources::ReadResourceStringData() {
- m_nResourceId2TextDataSize =
- sizeof ms_pResourceId2TextData / sizeof ms_pResourceId2TextData[0];
- for (MIuint i = 0; i < m_nResourceId2TextDataSize; i++) {
- const SRsrcTextData *pRscrData = &ms_pResourceId2TextData[i];
- MapPairRscrIdToTextData_t pr(pRscrData->id, pRscrData->pTextData);
- m_mapRscrIdToTextData.insert(pr);
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the corresponding text assigned to the resource ID.
-// Type: Method.
-// Args: vResourceId - (R) MI resource ID.
-// Return: CMIUtilString - Resource text.
-// Throws: None.
-//--
-CMIUtilString CMICmnResources::GetString(const MIuint vResourceId) const {
- CMIUtilString str;
- const bool bFound = GetStringFromResource(vResourceId, str);
- MIunused(bFound);
- assert(bFound);
-
- return str;
-}
-
-//++
-// Details: Determine the MI resource ID existings.
-// Type: Method.
-// Args: vResourceId - (R) MI resource ID.
-// Return: True - Exists.
-// False - Not found.
-// Throws: None.
-//--
-bool CMICmnResources::HasString(const MIuint vResourceId) const {
- CMIUtilString str;
- return GetStringFromResource(vResourceId, str);
-}
-
-//++
-// Details: Retrieve the resource text data for the given resource ID. If a
-// resource ID
-// cannot be found and error is given returning the ID of the resource
-// that
-// cannot be located.
-// Type: Method.
-// Args: vResourceId - (R) MI resource ID.
-// vrwResourceString - (W) Text.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnResources::GetStringFromResource(
- const MIuint vResourceId, CMIUtilString &vrwResourceString) const {
- MapRscrIdToTextData_t::const_iterator it =
- m_mapRscrIdToTextData.find(vResourceId);
- if (it == m_mapRscrIdToTextData.end()) {
- // Check this is a static variable init that needs this before we are ready
- if (!m_bInitialized) {
- (const_cast<CMICmnResources *>(this))->Initialize();
- it = m_mapRscrIdToTextData.find(vResourceId);
- if (it == m_mapRscrIdToTextData.end()) {
- vrwResourceString = MIRSRC(IDS_RESOURCES_ERR_STRING_TABLE_INVALID);
- return MIstatus::failure;
- }
- }
-
- if (it == m_mapRscrIdToTextData.end()) {
- vrwResourceString = CMIUtilString::Format(
- MIRSRC(IDS_RESOURCES_ERR_STRING_NOT_FOUND), vResourceId);
- return MIstatus::failure;
- }
- }
-
- const MIuint nRsrcId((*it).first);
- MIunused(nRsrcId);
- const char *pRsrcData((*it).second);
-
- // Return result
- vrwResourceString = pRsrcData;
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnResources.h b/tools/lldb-mi/MICmnResources.h
deleted file mode 100644
index 111b0c33899d..000000000000
--- a/tools/lldb-mi/MICmnResources.h
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- MICmnResources.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <map>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI string test data resource definitions. These IDs match up with
-// actual string data in a map internal to CMICmnResources.
-// *** Be sure to update ms_pResourceId2TextData[] array ****
-enum {
- IDS_PROJNAME = 1,
- IDS_MI_VERSION_DESCRIPTION_DEBUG,
- IDS_MI_VERSION_DESCRIPTION,
- IDS_MI_APPNAME_SHORT,
- IDS_MI_APPNAME_LONG,
- IDS_MI_APP_FILEPATHNAME,
- IDS_MI_APP_ARGS,
- IDE_MI_VERSION_GDB,
-
- IDS_UTIL_FILE_ERR_INVALID_PATHNAME,
- IDS_UTIL_FILE_ERR_OPENING_FILE,
- IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN,
- IDE_UTIL_FILE_ERR_WRITING_FILE,
- IDE_UTIL_FILE_ERR_WRITING_NOTOPEN,
-
- IDS_RESOURCES_ERR_STRING_NOT_FOUND,
- IDS_RESOURCES_ERR_STRING_TABLE_INVALID,
-
- IDS_MI_CLIENT_MSG,
-
- IDS_LOG_MSG_CREATION_DATE,
- IDS_LOG_MSG_FILE_LOGGER_PATH,
- IDS_LOG_MSG_VERSION,
- IDS_LOG_ERR_FILE_LOGGER_DISABLED,
- IDS_LOG_MEDIUM_ERR_INIT,
- IDS_LOG_MEDIUM_ERR_WRITE_ANY,
- IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL,
-
- IDS_MEDIUMFILE_NAME,
- IDS_MEDIUMFILE_ERR_INVALID_PATH,
- IDS_MEDIUMFILE_ERR_FILE_HEADER,
- IDS_MEDIUMFILE_NAME_LOG,
-
- IDE_OS_ERR_UNKNOWN,
- IDE_OS_ERR_RETRIEVING,
-
- IDS_DRIVERMGR_DRIVER_ERR_INIT,
-
- IDE_MEDIUMSTDERR_NAME,
- IDE_MEDIUMSTDOUT_NAME,
-
- IDE_MI_APP_DESCRIPTION,
- IDE_MI_APP_INFORMATION,
- IDE_MI_APP_ARG_USAGE,
- IDE_MI_APP_ARG_HELP,
- IDE_MI_APP_ARG_VERSION,
- IDE_MI_APP_ARG_VERSION_LONG,
- IDE_MI_APP_ARG_INTERPRETER,
- IDE_MI_APP_ARG_EXECUTEABLE,
- IDE_MI_APP_ARG_SOURCE,
- IDE_MI_APP_ARG_APP_LOG,
- IDE_MI_APP_ARG_APP_LOG_DIR,
- IDE_MI_APP_ARG_EXAMPLE,
- IDE_MI_APP_ARG_EXECUTABLE,
- IDE_MI_APP_ARG_SYNCHRONOUS,
-
- IDS_STDIN_ERR_INVALID_PROMPT,
- IDS_STDIN_ERR_THREAD_CREATION_FAILED,
- IDS_STDIN_ERR_THREAD_DELETE,
- IDS_STDIN_ERR_CHKING_BYTE_AVAILABLE,
- IDS_STDIN_INPUT_CTRL_CHARS,
-
- IDS_CMD_QUIT_HELP,
-
- IDS_THREADMGR_ERR_THREAD_ID_INVALID,
- IDS_THREADMGR_ERR_THREAD_FAIL_CREATE,
- IDS_THREADMGR_ERR_THREAD_ID_NOT_FOUND,
- IDS_THREADMGR_ERR_THREAD_STILL_ALIVE,
-
- IDS_FALLTHRU_DRIVER_CMD_RECEIVED,
-
- IDS_CMDFACTORY_ERR_INVALID_CMD_NAME,
- IDS_CMDFACTORY_ERR_INVALID_CMD_CR8FN,
- IDS_CMDFACTORY_ERR_CMD_NOT_REGISTERED,
- IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED,
-
- IDS_CMDMGR_ERR_CMD_FAILED_CREATE,
- IDS_CMDMGR_ERR_CMD_INVOKER,
-
- IDS_MI_INIT_ERR_LOG,
- IDS_MI_INIT_ERR_RESOURCES,
- IDS_MI_INIT_ERR_INIT,
- IDS_MI_INIT_ERR_STREAMSTDIN,
- IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER,
- IDS_MI_INIT_ERR_OS_STDIN_HANDLER,
- IDS_MI_INIT_ERR_STREAMSTDOUT,
- IDS_MI_INIT_ERR_STREAMSTDERR,
- IDS_MI_INIT_ERR_FALLTHRUDRIVER,
- IDS_MI_INIT_ERR_THREADMGR,
- IDS_MI_INIT_ERR_CMDINTERPRETER,
- IDS_MI_INIT_ERR_CMDMGR,
- IDS_MI_INIT_ERR_CMDFACTORY,
- IDS_MI_INIT_ERR_CMDINVOKER,
- IDS_MI_INIT_ERR_CMDMONITOR,
- IDS_MI_INIT_ERR_LLDBDEBUGGER,
- IDS_MI_INIT_ERR_DRIVERMGR,
- IDS_MI_INIT_ERR_DRIVER,
- IDS_MI_INIT_ERR_OUTOFBANDHANDLER,
- IDS_MI_INIT_ERR_DEBUGSESSIONINFO,
- IDS_MI_INIT_ERR_THREADMANAGER,
- IDS_MI_INIT_ERR_CLIENT_USING_DRIVER,
- IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION,
-
- IDS_CODE_ERR_INVALID_PARAMETER_VALUE,
- IDS_CODE_ERR_INVALID_PARAM_NULL_POINTER,
- IDS_CODE_ERR_INVALID_ENUMERATION_VALUE,
-
- IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER,
- IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER,
- IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER,
- IDS_LLDBDEBUGGER_ERR_STARTLISTENER,
- IDS_LLDBDEBUGGER_ERR_THREADCREATIONFAIL,
- IDS_LLDBDEBUGGER_ERR_THREAD_DELETE,
- IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER,
- IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME,
- IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED,
- IDS_LLDBDEBUGGER_ERR_STOPLISTENER,
- IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME,
- IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT,
-
- IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT,
- IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID,
- IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND,
- IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET,
- IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET,
- IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE,
- IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET,
- IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE,
- IDS_LLDBOUTOFBAND_ERR_BRKPT_CNT_EXCEEDED,
-
- IDS_DBGSESSION_ERR_SHARED_DATA_ADD,
-
- IDS_MI_SHTDWN_ERR_LOG,
- IDS_MI_SHUTDOWN_ERR,
- IDE_MI_SHTDWN_ERR_RESOURCES,
- IDE_MI_SHTDWN_ERR_STREAMSTDIN,
- IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER,
- IDS_MI_SHTDWN_ERR_STREAMSTDOUT,
- IDS_MI_SHTDWN_ERR_STREAMSTDERR,
- IDS_MI_SHTDWN_ERR_THREADMGR,
- IDS_MI_SHTDWN_ERR_CMDINTERPRETER,
- IDS_MI_SHTDWN_ERR_CMDMGR,
- IDS_MI_SHTDWN_ERR_CMDFACTORY,
- IDS_MI_SHTDWN_ERR_CMDINVOKER,
- IDS_MI_SHTDWN_ERR_CMDMONITOR,
- IDS_MI_SHTDWN_ERR_LLDBDEBUGGER,
- IDS_MI_SHTDWN_ERR_DRIVERMGR,
- IDS_MI_SHTDWN_ERR_DRIVER,
- IDS_MI_SHTDWN_ERR_OUTOFBANDHANDLER,
- IDS_MI_SHTDWN_ERR_DEBUGSESSIONINFO,
- IDE_MI_SHTDWN_ERR_THREADMANAGER,
-
- IDS_DRIVER_ERR_PARSE_ARGS,
- IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN,
- IDS_DRIVER_ERR_CURRENT_NOT_SET,
- IDS_DRIVER_ERR_NON_REGISTERED,
- IDS_DRIVER_SAY_DRIVER_USING,
- IDS_DRIVER_ERR_ID_INVALID,
- IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR,
- IDS_DRIVER_CMD_RECEIVED,
- IDS_DRIVER_CMD_NOT_IN_FACTORY,
- IDS_DRIVER_ERR_DRIVER_STATE_ERROR,
- IDS_DRIVER_ERR_MAINLOOP,
- IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL,
- IDS_DRIVER_ERR_LOCAL_DEBUG_INIT,
-
- IDS_DRIVER_WAITING_STDIN_DATA,
-
- IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN,
-
- IDS_CMD_ARGS_ERR_OPTION_NOT_FOUND,
- IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY,
- IDS_CMD_ARGS_ERR_VALIDATION_INVALID,
- IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID,
- IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF,
- IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN,
- IDS_CMD_ARGS_ERR_PREFIX_MSG,
-
- IDS_VARIANT_ERR_USED_BASECLASS,
- IDS_VARIANT_ERR_MAP_KEY_INVALID,
-
- IDS_WORD_INVALIDBRKTS,
- IDS_WORD_NONE,
- IDS_WORD_NOT,
- IDS_WORD_INVALIDEMPTY,
- IDS_WORD_INVALIDNULLPTR,
- IDS_WORD_UNKNOWNBRKTS,
- IDS_WORD_NOT_IMPLEMENTED,
- IDS_WORD_NOT_IMPLEMENTED_BRKTS,
- IDS_WORD_UNKNOWNTYPE_BRKTS,
- IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS,
-
- IDS_CMD_ERR_N_OPTIONS_REQUIRED,
- IDS_CMD_ERR_OPTION_NOT_FOUND,
- IDS_CMD_ERR_ARGS,
- IDS_CMD_WRN_ARGS_NOT_HANDLED,
- IDS_CMD_ERR_FNFAILED,
- IDS_CMD_ERR_SHARED_DATA_NOT_FOUND,
- IDS_CMD_ERR_LLDBPROCESS_DETACH,
- IDS_CMD_ERR_LLDBPROCESS_DESTROY,
- IDS_CMD_ERR_SETWKDIR,
- IDS_CMD_ERR_INVALID_TARGET,
- IDS_CMD_ERR_INVALID_TARGET_CURRENT,
- IDS_CMD_ERR_INVALID_TARGET_TYPE,
- IDS_CMD_ERR_INVALID_TARGET_PLUGIN,
- IDS_CMD_ERR_CONNECT_TO_TARGET,
- IDS_CMD_ERR_INVALID_TARGETPLUGINCURRENT,
- IDS_CMD_ERR_NOT_IMPLEMENTED,
- IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED,
- IDS_CMD_ERR_CREATE_TARGET,
- IDS_CMD_ERR_BRKPT_LOCATION_FORMAT,
- IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND,
- IDS_CMD_ERR_BRKPT_INVALID,
- IDS_CMD_ERR_BRKPT_CNT_EXCEEDED,
- IDS_CMD_ERR_SOME_ERROR,
- IDS_CMD_ERR_THREAD_INVALID,
- IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID,
- IDS_CMD_ERR_FRAME_INVALID,
- IDS_CMD_ERR_VARIABLE_DOESNOTEXIST,
- IDS_CMD_ERR_VARIABLE_ENUM_INVALID,
- IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH,
- IDS_CMD_ERR_VARIABLE_CREATION_FAILED,
- IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID,
- IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION,
- IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION,
- IDS_CMD_ERR_DISASM_ADDR_START_INVALID,
- IDS_CMD_ERR_DISASM_ADDR_END_INVALID,
- IDS_CMD_ERR_MEMORY_ALLOC_FAILURE,
- IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK,
- IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES,
- IDS_CMD_ERR_INVALID_PROCESS,
- IDS_CMD_ERR_INVALID_PRINT_VALUES,
- IDS_CMD_ERR_INVALID_LOCATION_FORMAT,
- IDS_CMD_ERR_INVALID_FORMAT_TYPE,
- IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND,
- IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES,
- IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK,
- IDS_CMD_ERR_SET_NEW_DRIVER_STATE,
- IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND,
- IDS_CMD_ERR_INFO_PRINTFN_FAILED,
- IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC,
- IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT,
- IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH,
- IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS,
- IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION,
- IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS,
- IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION,
- IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS,
- IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION,
- IDS_CMD_ERR_EXPR_INVALID,
- IDS_CMD_ERR_ATTACH_FAILED,
- IDS_CMD_ERR_ATTACH_BAD_ARGS
-};
-
-//++
-//============================================================================
-// Details: MI common code implementation class. Handle application resources
-// and locality.
-// Singleton class.
-//--
-class CMICmnResources : public CMICmnBase,
- public MI::ISingleton<CMICmnResources> {
- friend class MI::ISingleton<CMICmnResources>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
-
- CMIUtilString GetString(const MIuint vResourceId) const;
- bool HasString(const MIuint vResourceId) const;
-
- // Typedef:
-private:
- typedef std::map<MIuint, const char *> MapRscrIdToTextData_t;
- typedef std::pair<MIuint, const char *> MapPairRscrIdToTextData_t;
-
- // Enumerations:
-private:
- enum Buffer_e { eBufferSize = 2048 };
-
- // Structs:
-private:
- struct SRsrcTextData {
- MIuint id;
- const char *pTextData;
- };
-
- // Methods:
-private:
- /* ctor */ CMICmnResources();
- /* ctor */ CMICmnResources(const CMICmnResources &);
- void operator=(const CMICmnResources &);
-
- bool GetStringFromResource(const MIuint vResourceId,
- CMIUtilString &vrwResourceString) const;
- bool ReadResourceStringData();
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnResources() override;
-
- // Attributes:
-private:
- static const SRsrcTextData ms_pResourceId2TextData[];
- //
- MIuint m_nResourceId2TextDataSize;
- MapRscrIdToTextData_t m_mapRscrIdToTextData;
-};
-
-//++ =========================================================================
-// Details: Macro short cut for retrieving a text data resource
-//--
-#define MIRSRC(x) CMICmnResources::Instance().GetString(x).c_str()
diff --git a/tools/lldb-mi/MICmnStreamStderr.cpp b/tools/lldb-mi/MICmnStreamStderr.cpp
deleted file mode 100644
index f4f6a3ab8fe9..000000000000
--- a/tools/lldb-mi/MICmnStreamStderr.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//===-- MICmnStreamStderr.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnStreamStderr.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIDriver.h"
-
-//++
-// Details: CMICmnStreamStderr constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStderr::CMICmnStreamStderr() {}
-
-//++
-// Details: CMICmnStreamStderr destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStderr::~CMICmnStreamStderr() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this stderr stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
-
-#ifdef _MSC_VER
-// Debugging / I/O issues with client.
-// This is only required on Windows if you do not use ::flush(stderr). MI uses
-// ::flush(stderr)
-// It trys to ensure the process attached to the stderr steam gets ALL the data.
-//::setbuf( stderr, NULL );
-#endif // _MSC_VER
-
- m_bInitialized = bOk;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this stderr stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- ClrErrorDescription();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Write text data to stderr. Prefix the message with "MI:". The text
-// data does
-// not need to include a carriage line return as this is added to the
-// text. The
-// function also then passes the text data into the CMICmnLog logger.
-// Type: Method.
-// Args: vText - (R) Text data.
-// vbSendToLog - (R) True = Yes send to the Log file too, false = do
-// not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::Write(const CMIUtilString &vText,
- const bool vbSendToLog /* = true */) {
- if (vText.length() == 0)
- return MIstatus::failure;
-
- const CMIUtilString strPrefixed(CMIUtilString::Format(
- "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(),
- vText.c_str()));
-
- return WritePriv(strPrefixed, vText, vbSendToLog);
-}
-
-//++
-// Details: Write an LLDB text message to stderr.
-// The text data does not need to include a carriage line return as
-// this is added
-// to the text. The function also then passes the text data into the
-// CMICmnLog
-// logger.
-// Type: Method.
-// Args: vText - (R) Text data.
-// vbSendToLog - (R) True = Yes send to the Log file too, false = do
-// not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::WriteLLDBMsg(const CMIUtilString &vText,
- const bool vbSendToLog /* = true */) {
- if (vText.length() == 0)
- return MIstatus::failure;
-
- const CMIUtilString strPrefixed(
- CMIUtilString::Format("LLDB: %s", vText.c_str()));
-
- return WritePriv(vText, strPrefixed, vbSendToLog);
-}
-
-//++
-// Details: Write text data to stderr. The text data does not need to
-// include a carriage line return as this is added to the text. The
-// function also
-// then passes the text data into the CMICmnLog logger.
-// Type: Method.
-// Args: vText - (R) Text data. May be prefixed with MI app's short
-// name.
-// vTxtForLogFile - (R) Text data.
-// vbSendToLog - (R) True = Yes send to the Log file too, false =
-// do not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::WritePriv(const CMIUtilString &vText,
- const CMIUtilString &vTxtForLogFile,
- const bool vbSendToLog /* = true */) {
- if (vText.length() == 0)
- return MIstatus::failure;
-
- bool bOk = MIstatus::success;
- {
- // Grab the stderr thread lock while we print
- CMIUtilThreadLock _lock(m_mutex);
-
- // Send this text to stderr
- const MIint status = ::fputs(vText.c_str(), stderr);
- if (status == EOF) {
- const CMIUtilString errMsg(CMIUtilString::Format(
- MIRSRC(IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN), vText.c_str()));
- SetErrorDescription(errMsg);
- bOk = MIstatus::failure;
- } else {
- ::fprintf(stderr, "\n");
- ::fflush(stderr);
- }
-
- // Send this text to the log
- if (bOk && vbSendToLog)
- bOk &= m_pLog->WriteLog(vTxtForLogFile);
- }
-
- return bOk;
-}
-
-//++
-// Details: Lock the availability of the stream stderr. Other users of *this
-// stream will
-// be stalled until it is available (Unlock()).
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::Lock() {
- m_mutex.Lock();
- return MIstatus::success;
-}
-
-//++
-// Details: Release a previously locked stderr.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::Unlock() {
- m_mutex.Unlock();
- return MIstatus::success;
-}
-
-//++
-// Details: Take MI Driver text message and send to the stderr stream. Also
-// output to the
-// MI Log file.
-// Type: Static method.
-// Args: vrTxt - (R) Text.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::TextToStderr(const CMIUtilString &vrTxt) {
- const bool bLock = CMICmnStreamStderr::Instance().Lock();
- const bool bOk = bLock && CMICmnStreamStderr::Instance().Write(vrTxt);
- bLock &&CMICmnStreamStderr::Instance().Unlock();
-
- return bOk;
-}
-
-//++
-// Details: Take an LLDB message and send to the stderr stream. The message is
-// not always
-// an error message. The user has typed a command in to the Eclipse
-// console (by-
-// passing Eclipse) and this is the result message from LLDB back to
-// the user.
-// Also output to the MI Log file.
-// Type: Static method.
-// Args: vrTxt - (R) Text.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnStreamStderr::LLDBMsgToConsole(const CMIUtilString &vrTxt) {
- const bool bLock = CMICmnStreamStderr::Instance().Lock();
- const bool bOk = bLock && CMICmnStreamStderr::Instance().WriteLLDBMsg(vrTxt);
- bLock &&CMICmnStreamStderr::Instance().Unlock();
-
- return bOk;
-}
diff --git a/tools/lldb-mi/MICmnStreamStderr.h b/tools/lldb-mi/MICmnStreamStderr.h
deleted file mode 100644
index 65eea440dd7f..000000000000
--- a/tools/lldb-mi/MICmnStreamStderr.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//===-- MICmnStreamStderr.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-#include "MIUtilThreadBaseStd.h"
-
-//++
-//============================================================================
-// Details: MI common code class. The MI driver requires this object.
-// CMICmnStreamStderr sets up and tears downs stderr for the driver.
-//
-// Singleton class.
-//--
-class CMICmnStreamStderr : public CMICmnBase,
- public MI::ISingleton<CMICmnStreamStderr> {
- friend class MI::ISingleton<CMICmnStreamStderr>;
-
- // Statics:
-public:
- static bool TextToStderr(const CMIUtilString &vrTxt);
- static bool LLDBMsgToConsole(const CMIUtilString &vrTxt);
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- //
- bool Lock();
- bool Unlock();
- bool Write(const CMIUtilString &vText, const bool vbSendToLog = true);
- bool WriteLLDBMsg(const CMIUtilString &vText, const bool vbSendToLog = true);
-
- // Methods:
-private:
- /* ctor */ CMICmnStreamStderr();
- /* ctor */ CMICmnStreamStderr(const CMICmnStreamStderr &);
- void operator=(const CMICmnStreamStderr &);
- //
- bool WritePriv(const CMIUtilString &vText,
- const CMIUtilString &vTxtForLogFile,
- const bool vbSendToLog = true);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnStreamStderr() override;
-
- // Attributes:
-private:
- CMIUtilThreadMutex m_mutex; // Mutex object for sync during Write()
-};
diff --git a/tools/lldb-mi/MICmnStreamStdin.cpp b/tools/lldb-mi/MICmnStreamStdin.cpp
deleted file mode 100644
index 4084b36a8916..000000000000
--- a/tools/lldb-mi/MICmnStreamStdin.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-//===-- MICmnStreamStdin.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third Party Headers
-#ifdef _MSC_VER
-#include <windows.h>
-#endif
-#include <string.h>
-
-// In-house headers:
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MICmnStreamStdin.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriver.h"
-#include "MIUtilSingletonHelper.h"
-
-//++
-// Details: CMICmnStreamStdin constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdin::CMICmnStreamStdin()
- : m_strPromptCurrent("(gdb)"), m_bShowPrompt(true), m_pCmdBuffer(nullptr) {}
-
-//++
-// Details: CMICmnStreamStdin destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdin::~CMICmnStreamStdin() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdin::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on
- // previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
-
- if (bOk) {
- m_pCmdBuffer = new char[m_constBufferSize];
- } else {
- CMIUtilString strInitError(CMIUtilString::Format(
- MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
- SetErrorDescription(strInitError);
-
- return MIstatus::failure;
- }
- m_bInitialized = bOk;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdin::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- if (m_pCmdBuffer != nullptr) {
- delete[] m_pCmdBuffer;
- m_pCmdBuffer = nullptr;
- }
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Validate and set the text that forms the prompt on the command line.
-// Type: Method.
-// Args: vNewPrompt - (R) Text description.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt) {
- if (vNewPrompt.empty()) {
- const CMIUtilString msg(CMIUtilString::Format(
- MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
- CMICmnStreamStdout::Instance().Write(msg);
- return MIstatus::failure;
- }
-
- m_strPromptCurrent = vNewPrompt;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the command line prompt text currently being used.
-// Type: Method.
-// Args: None.
-// Return: const CMIUtilString & - Functional failed.
-// Throws: None.
-//--
-const CMIUtilString &CMICmnStreamStdin::GetPrompt() const {
- return m_strPromptCurrent;
-}
-
-//++
-// Details: Set whether to display optional command line prompt. The prompt is
-// output to
-// stdout. Disable it when this may interfere with the client reading
-// stdout as
-// input and it tries to interpret the prompt text to.
-// Type: Method.
-// Args: vbYes - (R) True = Yes prompt is shown/output to the user
-// (stdout), false = no prompt.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void CMICmnStreamStdin::SetEnablePrompt(const bool vbYes) {
- m_bShowPrompt = vbYes;
-}
-
-//++
-// Details: Get whether to display optional command line prompt. The prompt is
-// output to
-// stdout. Disable it when this may interfere with the client reading
-// stdout as
-// input and it tries to interpret the prompt text to.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes prompt is shown/output to the user (stdout), false
-// = no prompt.
-// Throws: None.
-//--
-bool CMICmnStreamStdin::GetEnablePrompt() const { return m_bShowPrompt; }
-
-//++
-// Details: Wait on new line of data from stdin stream (completed by '\n' or
-// '\r').
-// Type: Method.
-// Args: vwErrMsg - (W) Empty string ok or error description.
-// Return: char * - text buffer pointer or NULL on failure.
-// Throws: None.
-//--
-const char *CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg) {
- vwErrMsg.clear();
-
- // Read user input
- const char *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
- if (pText == nullptr) {
-#ifdef _MSC_VER
- // Was Ctrl-C hit?
- // On Windows, Ctrl-C gives an ERROR_OPERATION_ABORTED as error on the
- // command-line.
- // The end-of-file indicator is also set, so without this check we will exit
- // next if statement.
- if (::GetLastError() == ERROR_OPERATION_ABORTED)
- return nullptr;
-#endif
- if (::feof(stdin)) {
- const bool bForceExit = true;
- CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
- } else if (::ferror(stdin) != 0)
- vwErrMsg = ::strerror(errno);
- return nullptr;
- }
-
- // Strip off new line characters
- for (char *pI = m_pCmdBuffer; *pI != '\0'; pI++) {
- if ((*pI == '\n') || (*pI == '\r')) {
- *pI = '\0';
- break;
- }
- }
-
- return pText;
-}
diff --git a/tools/lldb-mi/MICmnStreamStdin.h b/tools/lldb-mi/MICmnStreamStdin.h
deleted file mode 100644
index b193757eb747..000000000000
--- a/tools/lldb-mi/MICmnStreamStdin.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===-- MICmnStreamStdin.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-#include "MIUtilThreadBaseStd.h"
-
-//++
-//============================================================================
-// Details: MI common code class. Used to handle stream data from Stdin.
-// Singleton class using the Visitor pattern. A driver using the
-// interface
-// provide can receive callbacks when a new line of data is received.
-// Each line is determined by a carriage return.
-// A singleton class.
-//--
-class CMICmnStreamStdin : public CMICmnBase,
- public MI::ISingleton<CMICmnStreamStdin> {
- // Give singleton access to private constructors
- friend MI::ISingleton<CMICmnStreamStdin>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- //
- const CMIUtilString &GetPrompt() const;
- bool SetPrompt(const CMIUtilString &vNewPrompt);
- void SetEnablePrompt(const bool vbYes);
- bool GetEnablePrompt() const;
- const char *ReadLine(CMIUtilString &vwErrMsg);
-
- // Methods:
-private:
- /* ctor */ CMICmnStreamStdin();
- /* ctor */ CMICmnStreamStdin(const CMICmnStreamStdin &);
- void operator=(const CMICmnStreamStdin &);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnStreamStdin() override;
-
- // Attributes:
-private:
- CMIUtilString m_strPromptCurrent; // Command line prompt as shown to the user
- bool m_bShowPrompt; // True = Yes prompt is shown/output to the user (stdout),
- // false = no prompt
- static const int m_constBufferSize = 2048;
- char *m_pCmdBuffer;
-};
diff --git a/tools/lldb-mi/MICmnStreamStdout.cpp b/tools/lldb-mi/MICmnStreamStdout.cpp
deleted file mode 100644
index 4a0e2d16adc1..000000000000
--- a/tools/lldb-mi/MICmnStreamStdout.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-//===-- MICmnStreamStdout.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnStreamStdout.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIDriver.h"
-
-//++
-// Details: CMICmnStreamStdout constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdout::CMICmnStreamStdout() {}
-
-//++
-// Details: CMICmnStreamStdout destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdout::~CMICmnStreamStdout() { Shutdown(); }
-
-//++
-// Details: Initialize resources for *this Stdout stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
-
-#ifdef _MSC_VER
-// Debugging / I/O issues with client.
-// This is only required on Windows if you do not use ::flush(stdout). MI uses
-// ::flush(stdout)
-// It trys to ensure the process attached to the stdout steam gets ALL the data.
-//::setbuf( stdout, NULL );
-#endif // _MSC_VER
-
- m_bInitialized = bOk;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release resources for *this Stdout stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- ClrErrorDescription();
-
- m_bInitialized = false;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Write an MI format type response to stdout. The text data does not
-// need to
-// include a carriage line return as this is added to the text. The
-// function also
-// then passes the text data into the CMICmnLog logger.
-// Type: Method.
-// Args: vText - (R) MI formatted text.
-// vbSendToLog - (R) True = Yes send to the Log file too, false = do
-// not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::WriteMIResponse(const CMIUtilString &vText,
- const bool vbSendToLog /* = true */) {
- return WritePriv(vText, vText, vbSendToLog);
-}
-
-//++
-// Details: Write text data to stdout. The text data does not need to
-// include a carriage line return as this is added to the text. The
-// function also
-// then passes the text data into the CMICmnLog logger.
-// Type: Method.
-// Args: vText - (R) Text data.
-// vbSendToLog - (R) True = Yes send to the Log file too, false = do
-// not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::Write(const CMIUtilString &vText,
- const bool vbSendToLog /* = true */) {
- if (vText.length() == 0)
- return MIstatus::failure;
-
- const CMIUtilString strPrefixed(CMIUtilString::Format(
- "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(),
- vText.c_str()));
-
- return WritePriv(strPrefixed, vText, vbSendToLog);
-}
-
-//++
-// Details: Write text data to stdout. The text data does not need to
-// include a carriage line return as this is added to the text. The
-// function also
-// then passes the text data into the CMICmnLog logger.
-// Type: Method.
-// Args: vText - (R) Text data prefixed with MI app's short name.
-// vTxtForLogFile - (R) Text data.
-// vbSendToLog - (R) True = Yes send to the Log file too, false =
-// do not. (Dflt = true)
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::WritePriv(const CMIUtilString &vText,
- const CMIUtilString &vTxtForLogFile,
- const bool vbSendToLog /* = true */) {
- if (vText.length() == 0)
- return MIstatus::failure;
-
- bool bOk = MIstatus::success;
- {
- // Grab the stdout thread lock while we print
- CMIUtilThreadLock _lock(m_mutex);
-
- // Send this text to stdout
- const MIint status = ::fputs(vText.c_str(), stdout);
- if (status == EOF)
- // Don't call the CMICmnBase::SetErrorDescription() because it will cause
- // a stack overflow:
- // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write ->
- // CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription
- bOk = MIstatus::failure;
- else {
- ::fprintf(stdout, "\n");
- ::fflush(stdout);
- }
-
- // Send this text to the log
- if (bOk && vbSendToLog)
- bOk &= m_pLog->WriteLog(vTxtForLogFile);
- }
-
- return bOk;
-}
-
-//++
-// Details: Lock the availability of the stream stdout. Other users of *this
-// stream will
-// be stalled until it is available (Unlock()).
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::Lock() {
- m_mutex.Lock();
- return MIstatus::success;
-}
-
-//++
-// Details: Release a previously locked stdout.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::Unlock() {
- m_mutex.Unlock();
- return MIstatus::success;
-}
-
-//++
-// Details: Take a text data and send to the stdout stream. Also output to the
-// MI Log
-// file.
-// Type: Static method.
-// Args: vrTxt - (R) Text.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::TextToStdout(const CMIUtilString &vrTxt) {
- const bool bSendToLog = true;
- return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog);
-}
-
-//++
-// Details: Write prompt to stdout if it's enabled.
-// Type: Static method.
-// Args: None.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMICmnStreamStdout::WritePrompt() {
- const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance();
- if (rStdinMan.GetEnablePrompt())
- return TextToStdout(rStdinMan.GetPrompt());
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnStreamStdout.h b/tools/lldb-mi/MICmnStreamStdout.h
deleted file mode 100644
index f73b56ca2ee4..000000000000
--- a/tools/lldb-mi/MICmnStreamStdout.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===-- MICmnStreamStdout.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-#include "MIUtilThreadBaseStd.h"
-
-//++
-//============================================================================
-// Details: MI common code class. The MI driver requires this object.
-// CMICmnStreamStdout sets up and tears downs stdout for the driver.
-//
-// Singleton class.
-//--
-class CMICmnStreamStdout : public CMICmnBase,
- public MI::ISingleton<CMICmnStreamStdout> {
- friend class MI::ISingleton<CMICmnStreamStdout>;
-
- // Statics:
-public:
- static bool TextToStdout(const CMIUtilString &vrTxt);
- static bool WritePrompt();
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- //
- bool Lock();
- bool Unlock();
- bool Write(const CMIUtilString &vText, const bool vbSendToLog = true);
- bool WriteMIResponse(const CMIUtilString &vText,
- const bool vbSendToLog = true);
-
- // Methods:
-private:
- /* ctor */ CMICmnStreamStdout();
- /* ctor */ CMICmnStreamStdout(const CMICmnStreamStdout &);
- void operator=(const CMICmnStreamStdout &);
- //
- bool WritePriv(const CMIUtilString &vText,
- const CMIUtilString &vTxtForLogFile,
- const bool vbSendToLog = true);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnStreamStdout() override;
-
- // Attributes:
-private:
- CMIUtilThreadMutex m_mutex; // Mutex object for sync during writing to stream
-};
diff --git a/tools/lldb-mi/MICmnThreadMgrStd.cpp b/tools/lldb-mi/MICmnThreadMgrStd.cpp
deleted file mode 100644
index 25afbbcb5d1c..000000000000
--- a/tools/lldb-mi/MICmnThreadMgrStd.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//===-- MICmnThreadMgrStd.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnThreadMgrStd.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIUtilSingletonHelper.h"
-
-//++
-// Details: CMICmnThreadMgr constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnThreadMgrStd::CMICmnThreadMgrStd() {}
-
-//++
-// Details: CMICmnThreadMgr destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnThreadMgrStd::~CMICmnThreadMgrStd() { Shutdown(); }
-
-//++
-// Details: Initialise resources for *this thread manager.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnThreadMgrStd::Initialize() {
- m_clientUsageRefCnt++;
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
-
- ClrErrorDescription();
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on
- // previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
-
- m_bInitialized = bOk;
-
- if (!bOk) {
- CMIUtilString strInitError(CMIUtilString::Format(
- MIRSRC(IDS_MI_INIT_ERR_THREADMGR), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
-
- return bOk;
-}
-
-//++
-// Details: Release resources for *this thread manager.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnThreadMgrStd::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Tidy up
- ThreadAllTerminate();
-
- // Note shutdown order is important here
- MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
- }
-
- return bOk;
-}
-
-//++
-// Details: Ask the thread manager to kill all threads and wait until they have
-// died
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnThreadMgrStd::ThreadAllTerminate() {
- ThreadList_t::const_iterator it = m_threadList.begin();
- for (; it != m_threadList.end(); ++it) {
- // If the thread is still running
- CMIUtilThreadActiveObjBase *pThread = *it;
- if (pThread->ThreadIsActive()) {
- // Ask this thread to kill itself
- pThread->ThreadKill();
-
- // Wait for this thread to die
- pThread->ThreadJoin();
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Add a thread object to *this manager's list of thread objects. The
-// list to
-// used to manage thread objects centrally.
-// Type: Method.
-// Args: vrObj - (R) A thread object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMICmnThreadMgrStd::AddThread(const CMIUtilThreadActiveObjBase &vrObj) {
- m_threadList.push_back(const_cast<CMIUtilThreadActiveObjBase *>(&vrObj));
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MICmnThreadMgrStd.h b/tools/lldb-mi/MICmnThreadMgrStd.h
deleted file mode 100644
index ce8dd70525f3..000000000000
--- a/tools/lldb-mi/MICmnThreadMgrStd.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//===-- MICmnThreadMgrStd.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <vector>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnResources.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilThreadBaseStd.h"
-
-//++
-//============================================================================
-// Details: MI's worker thread (active thread) manager.
-// The manager creates threads and behalf of clients. Client are
-// responsible for their threads and can delete them when necessary.
-// This manager will stop and delete all threads on *this manager's
-// shutdown.
-// Singleton class.
-//--
-class CMICmnThreadMgrStd : public CMICmnBase,
- public MI::ISingleton<CMICmnThreadMgrStd> {
- friend MI::ISingleton<CMICmnThreadMgrStd>;
-
- // Methods:
-public:
- bool Initialize() override;
- bool Shutdown() override;
- bool ThreadAllTerminate(); // Ask all threads to stop (caution)
- template <typename T> // Ask the thread manager to start and stop threads on
- // our behalf
- bool ThreadStart(T &vrwObject);
-
- // Typedef:
-private:
- typedef std::vector<CMIUtilThreadActiveObjBase *> ThreadList_t;
-
- // Methods:
-private:
- /* ctor */ CMICmnThreadMgrStd();
- /* ctor */ CMICmnThreadMgrStd(const CMICmnThreadMgrStd &);
- void operator=(const CMICmnThreadMgrStd &);
- //
- bool AddThread(const CMIUtilThreadActiveObjBase &
- vrObj); // Add a thread for monitoring by the threadmanager
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMICmnThreadMgrStd() override;
-
- // Attributes:
-private:
- CMIUtilThreadMutex m_mutex;
- ThreadList_t m_threadList;
-};
-
-//++
-// Details: Given a thread object start its (worker) thread to do work. The
-// object is
-// added to the *this manager for housekeeping and deletion of all
-// thread objects.
-// Type: Template method.
-// Args: vrwThreadObj - (RW) A CMIUtilThreadActiveObjBase derived
-// object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-template <typename T> bool CMICmnThreadMgrStd::ThreadStart(T &vrwThreadObj) {
- bool bOk = MIstatus::success;
-
- // Grab a reference to the base object type
- CMIUtilThreadActiveObjBase &rObj =
- static_cast<CMIUtilThreadActiveObjBase &>(vrwThreadObj);
-
- // Add to the thread managers internal database
- bOk &= AddThread(rObj);
- if (!bOk) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- vrwThreadObj.ThreadGetName().c_str()));
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- // Grab a reference on behalf of the caller
- bOk &= vrwThreadObj.Acquire();
- if (!bOk) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- vrwThreadObj.ThreadGetName().c_str()));
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- // Thread is already started
- // This call must come after the reference count increment
- if (vrwThreadObj.ThreadIsActive()) {
- // Early exit on thread already running condition
- return MIstatus::success;
- }
-
- // Start the thread running
- bOk &= vrwThreadObj.ThreadExecute();
- if (!bOk) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- vrwThreadObj.ThreadGetName().c_str()));
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MIDataTypes.h b/tools/lldb-mi/MIDataTypes.h
deleted file mode 100644
index c1ed764e46c6..000000000000
--- a/tools/lldb-mi/MIDataTypes.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===-- MIDataTypes.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: Common global switches, macros, etc.
-//
-// This file contains common data types required by applications
-// generally. If supported by the compiler, this file should be
-// #include'd as part of the project's PCH (precompiled header).
-
-#pragma once
-
-// Windows headers:
-#ifdef _WIN32
-
-// Debugging:
-#ifdef _DEBUG
-#include <crtdbg.h>
-#endif // _DEBUG
-
-#endif // _WIN32
-
-// Common definitions:
-
-// Function return status
-namespace MIstatus {
-const bool success = true;
-const bool failure = false;
-}
-
-// Use to avoid "unused parameter" compiler warnings:
-#define MIunused(x) (void)x;
-
-// Portability issues
-#ifdef _WIN64
-typedef unsigned __int64 size_t;
-typedef __int64 MIint;
-typedef unsigned __int64 MIuint;
-#else
-#ifdef _WIN32
-typedef unsigned int size_t;
-typedef int MIint;
-typedef unsigned int MIuint;
-#else
-typedef int MIint;
-typedef unsigned int MIuint;
-
-#define MAX_PATH 4096
-#endif // _WIN32
-#endif // _WIN64
-
-// Common types:
-
-// Fundamentals:
-typedef long long MIint64; // 64bit signed integer.
-typedef unsigned long long MIuint64; // 64bit unsigned integer.
diff --git a/tools/lldb-mi/MIDriver.cpp b/tools/lldb-mi/MIDriver.cpp
deleted file mode 100644
index 3bf888e303d4..000000000000
--- a/tools/lldb-mi/MIDriver.cpp
+++ /dev/null
@@ -1,1318 +0,0 @@
-//===-- MIDriver.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBError.h"
-#include <cassert>
-#include <csignal>
-#include <fstream>
-
-// In-house headers:
-#include "MICmdArgValFile.h"
-#include "MICmdArgValString.h"
-#include "MICmdMgr.h"
-#include "MICmnConfig.h"
-#include "MICmnLLDBDebugSessionInfo.h"
-#include "MICmnLLDBDebugger.h"
-#include "MICmnLog.h"
-#include "MICmnMIResultRecord.h"
-#include "MICmnMIValueConst.h"
-#include "MICmnResources.h"
-#include "MICmnStreamStderr.h"
-#include "MICmnStreamStdout.h"
-#include "MICmnThreadMgrStd.h"
-#include "MIDriver.h"
-#include "MIUtilDebug.h"
-#include "MIUtilSingletonHelper.h"
-
-// Instantiations:
-#if _DEBUG
-const CMIUtilString CMIDriver::ms_constMIVersion =
- MIRSRC(IDS_MI_VERSION_DESCRIPTION_DEBUG);
-#else
-const CMIUtilString CMIDriver::ms_constMIVersion =
- MIRSRC(IDS_MI_VERSION_DESCRIPTION); // Matches version in resources file
-#endif // _DEBUG
-const CMIUtilString
- CMIDriver::ms_constAppNameShort(MIRSRC(IDS_MI_APPNAME_SHORT));
-const CMIUtilString CMIDriver::ms_constAppNameLong(MIRSRC(IDS_MI_APPNAME_LONG));
-
-//++
-// Details: CMIDriver constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriver::CMIDriver()
- : m_bFallThruToOtherDriverEnabled(false), m_bDriverIsExiting(false),
- m_handleMainThread(nullptr), m_rStdin(CMICmnStreamStdin::Instance()),
- m_rLldbDebugger(CMICmnLLDBDebugger::Instance()),
- m_rStdOut(CMICmnStreamStdout::Instance()),
- m_eCurrentDriverState(eDriverState_NotRunning),
- m_bHaveExecutableFileNamePathOnCmdLine(false),
- m_bDriverDebuggingArgExecutable(false),
- m_bHaveCommandFileNamePathOnCmdLine(false) {}
-
-//++
-// Details: CMIDriver destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriver::~CMIDriver() {}
-
-//++
-// Details: Set whether *this driver (the parent) is enabled to pass a command
-// to its
-// fall through (child) driver to interpret the command and do work
-// instead
-// (if *this driver decides it can't handle the command).
-// Type: Method.
-// Args: vbYes - (R) True = yes fall through, false = do not pass on
-// command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::SetEnableFallThru(const bool vbYes) {
- m_bFallThruToOtherDriverEnabled = vbYes;
- return MIstatus::success;
-}
-
-//++
-// Details: Get whether *this driver (the parent) is enabled to pass a command
-// to its
-// fall through (child) driver to interpret the command and do work
-// instead
-// (if *this driver decides it can't handle the command).
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes fall through, false = do not pass on command.
-// Throws: None.
-//--
-bool CMIDriver::GetEnableFallThru() const {
- return m_bFallThruToOtherDriverEnabled;
-}
-
-//++
-// Details: Retrieve MI's application name of itself.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetAppNameShort() const {
- return ms_constAppNameShort;
-}
-
-//++
-// Details: Retrieve MI's application name of itself.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetAppNameLong() const {
- return ms_constAppNameLong;
-}
-
-//++
-// Details: Retrieve MI's version description of itself.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetVersionDescription() const {
- return ms_constMIVersion;
-}
-
-//++
-// Details: Initialize setup *this driver ready for use.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::Initialize() {
- m_eCurrentDriverState = eDriverState_Initialising;
- m_clientUsageRefCnt++;
-
- ClrErrorDescription();
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Initialize all of the modules we depend on
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnStreamStdout>(IDS_MI_INIT_ERR_STREAMSTDOUT, bOk, errMsg);
- MI::ModuleInit<CMICmnStreamStderr>(IDS_MI_INIT_ERR_STREAMSTDERR, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMANAGER, bOk,
- errMsg);
- MI::ModuleInit<CMICmnStreamStdin>(IDS_MI_INIT_ERR_STREAMSTDIN, bOk, errMsg);
- MI::ModuleInit<CMICmdMgr>(IDS_MI_INIT_ERR_CMDMGR, bOk, errMsg);
- bOk &= m_rLldbDebugger.SetDriver(*this);
- MI::ModuleInit<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk, errMsg);
-
- m_bExitApp = false;
-
- m_bInitialized = bOk;
-
- if (!bOk) {
- const CMIUtilString msg =
- CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_DRIVER), errMsg.c_str());
- SetErrorDescription(msg);
- return MIstatus::failure;
- }
-
- m_eCurrentDriverState = eDriverState_RunningNotDebugging;
-
- return bOk;
-}
-
-//++
-// Details: Unbind detach or release resources used by *this driver.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::Shutdown() {
- if (--m_clientUsageRefCnt > 0)
- return MIstatus::success;
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_eCurrentDriverState = eDriverState_ShuttingDown;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Shutdown all of the modules we depend on
- MI::ModuleShutdown<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmdMgr>(IDS_MI_INIT_ERR_CMDMGR, bOk, errMsg);
- MI::ModuleShutdown<CMICmnStreamStdin>(IDS_MI_INIT_ERR_STREAMSTDIN, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMANAGER, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnStreamStderr>(IDS_MI_INIT_ERR_STREAMSTDERR, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmnStreamStdout>(IDS_MI_INIT_ERR_STREAMSTDOUT, bOk,
- errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str());
- }
-
- m_eCurrentDriverState = eDriverState_NotRunning;
-
- return bOk;
-}
-
-//++
-// Details: Work function. Client (the driver's user) is able to append their
-// own message
-// in to the MI's Log trace file.
-// Type: Method.
-// Args: vMessage - (R) Client's text message.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::WriteMessageToLog(const CMIUtilString &vMessage) {
- CMIUtilString msg;
- msg = CMIUtilString::Format(MIRSRC(IDS_MI_CLIENT_MSG), vMessage.c_str());
- return m_pLog->Write(msg, CMICmnLog::eLogVerbosity_ClientMsg);
-}
-
-//++
-// Details: CDriverMgr calls *this driver initialize setup ready for use.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::DoInitialize() { return CMIDriver::Instance().Initialize(); }
-
-//++
-// Details: CDriverMgr calls *this driver to unbind detach or release resources
-// used by
-// *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::DoShutdown() { return CMIDriver::Instance().Shutdown(); }
-
-//++
-// Details: Retrieve the name for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Driver name.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetName() const {
- const CMIUtilString &rName = GetAppNameLong();
- const CMIUtilString &rVsn = GetVersionDescription();
- static CMIUtilString strName =
- CMIUtilString::Format("%s %s", rName.c_str(), rVsn.c_str());
-
- return strName;
-}
-
-//++
-// Details: Retrieve *this driver's last error condition.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString CMIDriver::GetError() const { return GetErrorDescription(); }
-
-//++
-// Details: Call *this driver to return it's debugger.
-// Type: Overridden.
-// Args: None.
-// Return: lldb::SBDebugger & - LLDB debugger object reference.
-// Throws: None.
-//--
-lldb::SBDebugger &CMIDriver::GetTheDebugger() {
- return m_rLldbDebugger.GetTheDebugger();
-}
-
-//++
-// Details: Specify another driver *this driver can call should this driver not
-// be able
-// to handle the client data input. DoFallThruToAnotherDriver() makes
-// the call.
-// Type: Overridden.
-// Args: vrOtherDriver - (R) Reference to another driver object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver) {
- m_pDriverFallThru = const_cast<CMIDriverBase *>(&vrOtherDriver);
-
- return m_pDriverFallThru->SetDriverParent(*this);
-}
-
-//++
-// Details: Proxy function CMIDriverMgr IDriver interface implementation. *this
-// driver's
-// implementation called from here to match the existing function name
-// of the
-// original LLDB driver class (the extra indirection is not necessarily
-// required).
-// Check the arguments that were passed to this program to make sure
-// they are
-// valid and to get their argument values (if any).
-// Type: Overridden.
-// Args: argc - (R) An integer that contains the count of arguments
-// that follow in
-// argv. The argc parameter is always greater than
-// or equal to 1.
-// argv - (R) An array of null-terminated strings representing
-// command-line
-// arguments entered by the user of the program. By
-// convention,
-// argv[0] is the command with which the program is
-// invoked.
-// vpStdOut - (R) Pointer to a standard output stream.
-// vwbExiting - (W) True = *this want to exit, Reasons: help,
-// invalid arg(s),
-// version information only.
-// False = Continue to work, start debugger i.e.
-// Command
-// interpreter.
-// Return: lldb::SBError - LLDB current error status.
-// Throws: None.
-//--
-lldb::SBError CMIDriver::DoParseArgs(const int argc, const char *argv[],
- FILE *vpStdOut, bool &vwbExiting) {
- return ParseArgs(argc, argv, vpStdOut, vwbExiting);
-}
-
-//++
-// Details: Check the arguments that were passed to this program to make sure
-// they are
-// valid and to get their argument values (if any). The following are
-// options
-// that are only handled by *this driver:
-// --executable <file>
-// --source <file> or -s <file>
-// --synchronous
-// The application's options --interpreter and --executable in code act
-// very similar.
-// The --executable is necessary to differentiate whether the MI Driver
-// is being
-// used by a client (e.g. Eclipse) or from the command line. Eclipse
-// issues the option
-// --interpreter and also passes additional arguments which can be
-// interpreted as an
-// executable if called from the command line. Using --executable tells
-// the MI Driver
-// it is being called from the command line and to prepare to launch
-// the executable
-// argument for a debug session. Using --interpreter on the command
-// line does not
-// issue additional commands to initialise a debug session.
-// Option --synchronous disables an asynchronous mode in the lldb-mi driver.
-// Type: Overridden.
-// Args: argc - (R) An integer that contains the count of arguments
-// that follow in
-// argv. The argc parameter is always greater than
-// or equal to 1.
-// argv - (R) An array of null-terminated strings representing
-// command-line
-// arguments entered by the user of the program. By
-// convention,
-// argv[0] is the command with which the program is
-// invoked.
-// vpStdOut - (R) Pointer to a standard output stream.
-// vwbExiting - (W) True = *this want to exit, Reasons: help,
-// invalid arg(s),
-// version information only.
-// False = Continue to work, start debugger i.e.
-// Command
-// interpreter.
-// Return: lldb::SBError - LLDB current error status.
-// Throws: None.
-//--
-lldb::SBError CMIDriver::ParseArgs(const int argc, const char *argv[],
- FILE *vpStdOut, bool &vwbExiting) {
- lldb::SBError errStatus;
- const bool bHaveArgs(argc >= 2);
-
- // *** Add any args handled here to GetHelpOnCmdLineArgOptions() ***
-
- // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
- // Look for the command line options
- bool bHaveExecutableFileNamePath = false;
- bool bHaveExecutableLongOption = false;
-
- if (bHaveArgs) {
- // Search right to left to look for filenames
- for (MIint i = argc - 1; i > 0; i--) {
- const CMIUtilString strArg(argv[i]);
- const CMICmdArgValFile argFile;
-
- // Check for a filename
- if (argFile.IsFilePath(strArg) ||
- CMICmdArgValString(true, false, true).IsStringArg(strArg)) {
- // Is this the command file for the '-s' or '--source' options?
- const CMIUtilString strPrevArg(argv[i - 1]);
- if (strPrevArg == "-s" || strPrevArg == "--source") {
- m_strCmdLineArgCommandFileNamePath = strArg;
- m_bHaveCommandFileNamePathOnCmdLine = true;
- i--; // skip '-s' on the next loop
- continue;
- }
- // Else, must be the executable
- bHaveExecutableFileNamePath = true;
- m_strCmdLineArgExecuteableFileNamePath = strArg;
- m_bHaveExecutableFileNamePathOnCmdLine = true;
- }
- // Report error if no command file was specified for the '-s' or
- // '--source' options
- else if (strArg == "-s" || strArg == "--source") {
- vwbExiting = true;
- const CMIUtilString errMsg = CMIUtilString::Format(
- MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF), strArg.c_str());
- errStatus.SetErrorString(errMsg.c_str());
- break;
- }
- // This argument is also checked for in CMIDriverMgr::ParseArgs()
- else if (strArg == "--executable") // Used to specify that
- // there is executable
- // argument also on the
- // command line
- { // See fn description.
- bHaveExecutableLongOption = true;
- } else if (strArg == "--synchronous") {
- CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().SetAsync(false);
- }
- }
- }
-
- if (bHaveExecutableFileNamePath && bHaveExecutableLongOption) {
- SetDriverDebuggingArgExecutable();
- }
-
- return errStatus;
-}
-
-//++
-// Details: A client can ask if *this driver is GDB/MI compatible.
-// Type: Overridden.
-// Args: None.
-// Return: True - GBD/MI compatible LLDB front end.
-// False - Not GBD/MI compatible LLDB front end.
-// Throws: None.
-//--
-bool CMIDriver::GetDriverIsGDBMICompatibleDriver() const { return true; }
-
-//++
-// Details: Start worker threads for the driver.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::StartWorkerThreads() {
- bool bOk = MIstatus::success;
-
- // Grab the thread manager
- CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();
-
- // Start the event polling thread
- if (bOk && !rThreadMgr.ThreadStart<CMICmnLLDBDebugger>(m_rLldbDebugger)) {
- const CMIUtilString errMsg = CMIUtilString::Format(
- MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
- SetErrorDescription(errMsg);
- return MIstatus::failure;
- }
-
- return bOk;
-}
-
-//++
-// Details: Stop worker threads for the driver.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::StopWorkerThreads() {
- CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();
- return rThreadMgr.ThreadAllTerminate();
-}
-
-//++
-// Details: Call this function puts *this driver to work.
-// This function is used by the application's main thread.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::DoMainLoop() {
- if (!InitClientIDEToMIDriver()) // Init Eclipse IDE
- {
- SetErrorDescriptionn(MIRSRC(IDS_MI_INIT_ERR_CLIENT_USING_DRIVER));
- return MIstatus::failure;
- }
-
- if (!StartWorkerThreads())
- return MIstatus::failure;
-
- bool bOk = MIstatus::success;
-
- if (HaveExecutableFileNamePathOnCmdLine()) {
- if (!LocalDebugSessionStartupExecuteCommands()) {
- SetErrorDescription(MIRSRC(IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION));
- bOk = MIstatus::failure;
- }
- }
-
- // App is not quitting currently
- m_bExitApp = false;
-
- // Handle source file
- if (m_bHaveCommandFileNamePathOnCmdLine) {
- const bool bAsyncMode = false;
- ExecuteCommandFile(bAsyncMode);
- }
-
- // While the app is active
- while (bOk && !m_bExitApp) {
- CMIUtilString errorText;
- const char *pCmd = m_rStdin.ReadLine(errorText);
- if (pCmd != nullptr) {
- CMIUtilString lineText(pCmd);
- if (!lineText.empty()) {
- // Check that the handler thread is alive (otherwise we stuck here)
- assert(CMICmnLLDBDebugger::Instance().ThreadIsActive());
-
- {
- // Lock Mutex before processing commands so that we don't disturb an
- // event
- // being processed
- CMIUtilThreadLock lock(
- CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
- bOk = InterpretCommand(lineText);
- }
-
- // Draw prompt if desired
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- // Wait while the handler thread handles incoming events
- CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
- }
- }
- }
-
- // Signal that the application is shutting down
- DoAppQuit();
-
- // Close and wait for the workers to stop
- StopWorkerThreads();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Set things in motion, set state etc that brings *this driver (and
-// the
-// application) to a tidy shutdown.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::DoAppQuit() {
- bool bYesQuit = true;
-
- // Shutdown stuff, ready app for exit
- {
- CMIUtilThreadLock lock(m_threadMutex);
- m_bDriverIsExiting = true;
- }
-
- return bYesQuit;
-}
-
-//++
-// Details: *this driver passes text commands to a fall through driver is it
-// does not
-// understand them (the LLDB driver).
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vTextLine - (R) Text data representing a possible command.
-// vwbCmdYesValid - (W) True = Command valid, false = command not
-// handled.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::InterpretCommandFallThruDriver(const CMIUtilString &vTextLine,
- bool &vwbCmdYesValid) {
- MIunused(vTextLine);
- MIunused(vwbCmdYesValid);
-
- // ToDo: Implement when less urgent work to be done or decide remove as not
- // required
- // bool bOk = MIstatus::success;
- // bool bCmdNotUnderstood = true;
- // if( bCmdNotUnderstood && GetEnableFallThru() )
- //{
- // CMIUtilString errMsg;
- // bOk = DoFallThruToAnotherDriver( vStdInBuffer, errMsg );
- // if( !bOk )
- // {
- // errMsg = errMsg.StripCREndOfLine();
- // errMsg = errMsg.StripCRAll();
- // const CMIDriverBase * pOtherDriver = GetDriverToFallThruTo();
- // const char * pName = pOtherDriver->GetDriverName().c_str();
- // const char * pId = pOtherDriver->GetDriverId().c_str();
- // const CMIUtilString msg( CMIUtilString::Format( MIRSRC(
- // IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR ), pName, pId, errMsg.c_str() )
- //);
- // m_pLog->WriteMsg( msg );
- // }
- //}
- //
- // vwbCmdYesValid = bOk;
- // CMIUtilString strNot;
- // if( vwbCmdYesValid)
- // strNot = CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) );
- // const CMIUtilString msg( CMIUtilString::Format( MIRSRC(
- // IDS_FALLTHRU_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str() ) );
- // m_pLog->WriteLog( msg );
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the name for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Driver name.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetDriverName() const { return GetName(); }
-
-//++
-// Details: Get the unique ID for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetDriverId() const { return GetId(); }
-
-//++
-// Details: This function allows *this driver to call on another driver to
-// perform work
-// should this driver not be able to handle the client data input.
-// SetDriverToFallThruTo() specifies the fall through to driver.
-// Check the error message if the function returns a failure.
-// Type: Overridden.
-// Args: vCmd - (R) Command instruction to interpret.
-// vwErrMsg - (W) Status description on command failing.
-// Return: MIstatus::success - Command succeeded.
-// MIstatus::failure - Command failed.
-// Throws: None.
-//--
-bool CMIDriver::DoFallThruToAnotherDriver(const CMIUtilString &vCmd,
- CMIUtilString &vwErrMsg) {
- bool bOk = MIstatus::success;
-
- CMIDriverBase *pOtherDriver = GetDriverToFallThruTo();
- if (pOtherDriver == nullptr)
- return bOk;
-
- return pOtherDriver->DoFallThruToAnotherDriver(vCmd, vwErrMsg);
-}
-
-//++
-// Details: *this driver provides a file stream to other drivers on which *this
-// driver
-// write's out to and they read as expected input. *this driver is
-// passing
-// through commands to the (child) pass through assigned driver.
-// Type: Overrdidden.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriver::GetStdin() const {
- // Note this fn is called on CMIDriverMgr register driver so stream has to be
- // available before *this driver has been initialized! Flaw?
-
- // This very likely to change later to a stream that the pass thru driver
- // will read and we write to give it 'input'
- return stdin;
-}
-
-//++
-// Details: *this driver provides a file stream to other pass through assigned
-// drivers
-// so they know what to write to.
-// Type: Overidden.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriver::GetStdout() const {
- // Note this fn is called on CMIDriverMgr register driver so stream has to be
- // available before *this driver has been initialized! Flaw?
-
- // Do not want to pass through driver to write to stdout
- return nullptr;
-}
-
-//++
-// Details: *this driver provides a error file stream to other pass through
-// assigned drivers
-// so they know what to write to.
-// Type: Overidden.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriver::GetStderr() const {
- // Note this fn is called on CMIDriverMgr register driver so stream has to be
- // available before *this driver has been initialized! Flaw?
-
- // This very likely to change later to a stream that the pass thru driver
- // will write to and *this driver reads from to pass on the CMICmnLog object
- return stderr;
-}
-
-//++
-// Details: Set a unique ID for *this driver. It cannot be empty.
-// Type: Overridden.
-// Args: vId - (R) Text description.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::SetId(const CMIUtilString &vId) {
- if (vId.empty()) {
- SetErrorDescriptionn(MIRSRC(IDS_DRIVER_ERR_ID_INVALID), GetName().c_str(),
- vId.c_str());
- return MIstatus::failure;
- }
-
- m_strDriverId = vId;
- return MIstatus::success;
-}
-
-//++
-// Details: Get the unique ID for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetId() const { return m_strDriverId; }
-
-//++
-// Details: Interpret the text data and match against current commands to see if
-// there
-// is a match. If a match then the command is issued and actioned on.
-// The
-// text data if not understood by *this driver is past on to the Fall
-// Thru
-// driver.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vTextLine - (R) Text data representing a possible command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::InterpretCommand(const CMIUtilString &vTextLine) {
- const bool bNeedToRebroadcastStopEvent =
- m_rLldbDebugger.CheckIfNeedToRebroadcastStopEvent();
- bool bCmdYesValid = false;
- bool bOk = InterpretCommandThisDriver(vTextLine, bCmdYesValid);
- if (bOk && !bCmdYesValid)
- bOk = InterpretCommandFallThruDriver(vTextLine, bCmdYesValid);
-
- if (bNeedToRebroadcastStopEvent)
- m_rLldbDebugger.RebroadcastStopEvent();
-
- return bOk;
-}
-
-//++
-// Details: Helper function for CMIDriver::InterpretCommandThisDriver.
-// Convert a CLI command to MI command (just wrap any CLI command
-// into "<tokens>-interpreter-exec command \"<CLI command>\"").
-// Type: Method.
-// Args: vTextLine - (R) Text data representing a possible command.
-// Return: CMIUtilString - The original MI command or converted CLI command.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-CMIUtilString
-CMIDriver::WrapCLICommandIntoMICommand(const CMIUtilString &vTextLine) const {
- // Tokens contain following digits
- static const CMIUtilString digits("0123456789");
-
- // Consider an algorithm on the following example:
- // 001-file-exec-and-symbols "/path/to/file"
- //
- // 1. Skip a command token
- // For example:
- // 001-file-exec-and-symbols "/path/to/file"
- // 001target create "/path/to/file"
- // ^ -- command starts here (in both cases)
- // Also possible case when command not found:
- // 001
- // ^ -- i.e. only tokens are present (or empty string at all)
- const size_t nCommandOffset = vTextLine.find_first_not_of(digits);
-
- // 2. Check if command is empty
- // For example:
- // 001-file-exec-and-symbols "/path/to/file"
- // 001target create "/path/to/file"
- // ^ -- command not empty (in both cases)
- // or:
- // 001
- // ^ -- command wasn't found
- const bool bIsEmptyCommand = (nCommandOffset == CMIUtilString::npos);
-
- // 3. Check and exit if it isn't a CLI command
- // For example:
- // 001-file-exec-and-symbols "/path/to/file"
- // 001
- // ^ -- it isn't CLI command (in both cases)
- // or:
- // 001target create "/path/to/file"
- // ^ -- it's CLI command
- const bool bIsCliCommand =
- !bIsEmptyCommand && (vTextLine.at(nCommandOffset) != '-');
- if (!bIsCliCommand)
- return vTextLine;
-
- // 4. Wrap CLI command to make it MI-compatible
- //
- // 001target create "/path/to/file"
- // ^^^ -- token
- const std::string vToken(vTextLine.begin(),
- vTextLine.begin() + nCommandOffset);
- // 001target create "/path/to/file"
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- CLI command
- const CMIUtilString vCliCommand(std::string(vTextLine, nCommandOffset));
-
- // 5. Escape special characters and embed the command in a string
- // Result: it looks like -- target create \"/path/to/file\".
- const std::string vShieldedCliCommand(vCliCommand.AddSlashes());
-
- // 6. Turn the CLI command into an MI command, as in:
- // 001-interpreter-exec command "target create \"/path/to/file\""
- // ^^^ -- token
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ -- wrapper
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- shielded
- // CLI command
- return CMIUtilString::Format("%s-interpreter-exec command \"%s\"",
- vToken.c_str(), vShieldedCliCommand.c_str());
-}
-
-//++
-// Details: Interpret the text data and match against current commands to see if
-// there
-// is a match. If a match then the command is issued and actioned on.
-// If a
-// command cannot be found to match then vwbCmdYesValid is set to false
-// and
-// nothing else is done here.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vTextLine - (R) Text data representing a possible command.
-// vwbCmdYesValid - (W) True = Command valid, false = command not
-// handled.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine,
- bool &vwbCmdYesValid) {
- // Convert any CLI commands into MI commands
- const CMIUtilString vMITextLine(WrapCLICommandIntoMICommand(vTextLine));
-
- vwbCmdYesValid = false;
- bool bCmdNotInCmdFactor = false;
- SMICmdData cmdData;
- CMICmdMgr &rCmdMgr = CMICmdMgr::Instance();
- if (!rCmdMgr.CmdInterpret(vMITextLine, vwbCmdYesValid, bCmdNotInCmdFactor,
- cmdData))
- return MIstatus::failure;
-
- if (vwbCmdYesValid) {
- // For debugging only
- // m_pLog->WriteLog( cmdData.strMiCmdAll.c_str() );
-
- return ExecuteCommand(cmdData);
- }
-
- // Check for escape character, may be cursor control characters
- // This code is not necessary for application operation, just want to keep
- // tabs on what
- // has been given to the driver to try and interpret.
- if (vMITextLine.at(0) == 27) {
- CMIUtilString logInput(MIRSRC(IDS_STDIN_INPUT_CTRL_CHARS));
- for (MIuint i = 0; i < vMITextLine.length(); i++) {
- logInput += CMIUtilString::Format("%d ", vMITextLine.at(i));
- }
- m_pLog->WriteLog(logInput);
- return MIstatus::success;
- }
-
- // Write to the Log that a 'command' was not valid.
- // Report back to the MI client via MI result record.
- CMIUtilString strNotInCmdFactory;
- if (bCmdNotInCmdFactor)
- strNotInCmdFactory = CMIUtilString::Format(
- MIRSRC(IDS_DRIVER_CMD_NOT_IN_FACTORY), cmdData.strMiCmd.c_str());
- const CMIUtilString strNot(
- CMIUtilString::Format("%s ", MIRSRC(IDS_WORD_NOT)));
- const CMIUtilString msg(CMIUtilString::Format(
- MIRSRC(IDS_DRIVER_CMD_RECEIVED), vMITextLine.c_str(), strNot.c_str(),
- strNotInCmdFactory.c_str()));
- const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg);
- const CMICmnMIValueResult valueResult("msg", vconst);
- const CMICmnMIResultRecord miResultRecord(
- cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
- valueResult);
- const bool bOk = m_rStdOut.WriteMIResponse(miResultRecord.GetString());
-
- // Proceed to wait for or execute next command
- return bOk;
-}
-
-//++
-// Details: Having previously had the potential command validated and found
-// valid now
-// get the command executed.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: vCmdData - (RW) Command meta data.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriver::ExecuteCommand(const SMICmdData &vCmdData) {
- CMICmdMgr &rCmdMgr = CMICmdMgr::Instance();
- return rCmdMgr.CmdExecute(vCmdData);
-}
-
-//++
-// Details: Set the MI Driver's exit application flag. The application checks
-// this flag
-// after every stdin line is read so the exit may not be instantaneous.
-// If vbForceExit is false the MI Driver queries its state and
-// determines if is
-// should exit or continue operating depending on that running state.
-// This is related to the running state of the MI driver.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIDriver::SetExitApplicationFlag(const bool vbForceExit) {
- if (vbForceExit) {
- CMIUtilThreadLock lock(m_threadMutex);
- m_bExitApp = true;
- return;
- }
-
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- // Did we receive a SIGINT from the client during a running debug program, if
- // so then SIGINT is not to be taken as meaning kill the MI driver application
- // but halt the inferior program being debugged instead
- if (m_eCurrentDriverState == eDriverState_RunningDebugging) {
- InterpretCommand("-exec-interrupt");
- return;
- }
-
- m_bExitApp = true;
-}
-
-//++
-// Details: Get the MI Driver's exit exit application flag.
-// This is related to the running state of the MI driver.
-// Type: Method.
-// Args: None.
-// Return: bool - True = MI Driver is shutting down, false = MI driver is
-// running.
-// Throws: None.
-//--
-bool CMIDriver::GetExitApplicationFlag() const { return m_bExitApp; }
-
-//++
-// Details: Get the current running state of the MI Driver.
-// Type: Method.
-// Args: None.
-// Return: DriverState_e - The current running state of the application.
-// Throws: None.
-//--
-CMIDriver::DriverState_e CMIDriver::GetCurrentDriverState() const {
- return m_eCurrentDriverState;
-}
-
-//++
-// Details: Set the current running state of the MI Driver to running and
-// currently not in
-// a debug session.
-// Type: Method.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Return: DriverState_e - The current running state of the application.
-// Throws: None.
-//--
-bool CMIDriver::SetDriverStateRunningNotDebugging() {
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
-
- if (m_eCurrentDriverState == eDriverState_RunningNotDebugging)
- return MIstatus::success;
-
- // Driver cannot be in the following states to set
- // eDriverState_RunningNotDebugging
- switch (m_eCurrentDriverState) {
- case eDriverState_NotRunning:
- case eDriverState_Initialising:
- case eDriverState_ShuttingDown: {
- SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
- return MIstatus::failure;
- }
- case eDriverState_RunningDebugging:
- case eDriverState_RunningNotDebugging:
- break;
- case eDriverState_count:
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_CODE_ERR_INVALID_ENUMERATION_VALUE),
- "SetDriverStateRunningNotDebugging()"));
- return MIstatus::failure;
- }
-
- // Driver must be in this state to set eDriverState_RunningNotDebugging
- if (m_eCurrentDriverState != eDriverState_RunningDebugging) {
- SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
- return MIstatus::failure;
- }
-
- m_eCurrentDriverState = eDriverState_RunningNotDebugging;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Set the current running state of the MI Driver to running and
-// currently not in
-// a debug session. The driver's state must in the state running and in
-// a
-// debug session to set this new state.
-// Type: Method.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Return: DriverState_e - The current running state of the application.
-// Throws: None.
-//--
-bool CMIDriver::SetDriverStateRunningDebugging() {
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
-
- if (m_eCurrentDriverState == eDriverState_RunningDebugging)
- return MIstatus::success;
-
- // Driver cannot be in the following states to set
- // eDriverState_RunningDebugging
- switch (m_eCurrentDriverState) {
- case eDriverState_NotRunning:
- case eDriverState_Initialising:
- case eDriverState_ShuttingDown: {
- SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
- return MIstatus::failure;
- }
- case eDriverState_RunningDebugging:
- case eDriverState_RunningNotDebugging:
- break;
- case eDriverState_count:
- SetErrorDescription(
- CMIUtilString::Format(MIRSRC(IDS_CODE_ERR_INVALID_ENUMERATION_VALUE),
- "SetDriverStateRunningDebugging()"));
- return MIstatus::failure;
- }
-
- // Driver must be in this state to set eDriverState_RunningDebugging
- if (m_eCurrentDriverState != eDriverState_RunningNotDebugging) {
- SetErrorDescription(MIRSRC(IDS_DRIVER_ERR_DRIVER_STATE_ERROR));
- return MIstatus::failure;
- }
-
- m_eCurrentDriverState = eDriverState_RunningDebugging;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Prepare the client IDE so it will start working/communicating with
-// *this MI
-// driver.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMIDriver::InitClientIDEToMIDriver() const {
- // Put other IDE init functions here
- return InitClientIDEEclipse();
-}
-
-//++
-// Details: The IDE Eclipse when debugging locally expects "(gdb)\n" character
-// sequence otherwise it refuses to communicate and times out. This
-// should be
-// sent to Eclipse before anything else.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMIDriver::InitClientIDEEclipse() const {
- return CMICmnStreamStdout::WritePrompt();
-}
-
-//++
-// Details: Ask *this driver whether it found an executable in the MI Driver's
-// list of
-// arguments which to open and debug. If so instigate commands to set
-// up a debug
-// session for that executable.
-// Type: Method.
-// Args: None.
-// Return: bool - True = True = Yes executable given as one of the parameters
-// to the MI
-// Driver.
-// False = not found.
-// Throws: None.
-//--
-bool CMIDriver::HaveExecutableFileNamePathOnCmdLine() const {
- return m_bHaveExecutableFileNamePathOnCmdLine;
-}
-
-//++
-// Details: Retrieve from *this driver executable file name path to start a
-// debug session
-// with (if present see HaveExecutableFileNamePathOnCmdLine()).
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Executeable file name path or empty string.
-// Throws: None.
-//--
-const CMIUtilString &CMIDriver::GetExecutableFileNamePathOnCmdLine() const {
- return m_strCmdLineArgExecuteableFileNamePath;
-}
-
-//++
-// Details: Execute commands (by injecting them into the stdin line queue
-// container) and
-// other code to set up the MI Driver such that is can take the
-// executable
-// argument passed on the command and create a debug session for it.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool CMIDriver::LocalDebugSessionStartupExecuteCommands() {
- const CMIUtilString strCmd(CMIUtilString::Format(
- "-file-exec-and-symbols \"%s\"",
- m_strCmdLineArgExecuteableFileNamePath.AddSlashes().c_str()));
- bool bOk = CMICmnStreamStdout::TextToStdout(strCmd);
- bOk = bOk && InterpretCommand(strCmd);
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
- return bOk;
-}
-
-//++
-// Details: Set the MI Driver into "its debugging an executable passed as an
-// argument"
-// mode as against running via a client like Eclipse.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIDriver::SetDriverDebuggingArgExecutable() {
- m_bDriverDebuggingArgExecutable = true;
-}
-
-//++
-// Details: Retrieve the MI Driver state indicating if it is operating in "its
-// debugging
-// an executable passed as an argument" mode as against running via a
-// client
-// like Eclipse.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-bool CMIDriver::IsDriverDebuggingArgExecutable() const {
- return m_bDriverDebuggingArgExecutable;
-}
-
-//++
-// Details: Execute commands from command source file in specified mode, and
-// set exit-flag if needed.
-// Type: Method.
-// Args: vbAsyncMode - (R) True = execute commands in asynchronous
-// mode, false = otherwise.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-bool CMIDriver::ExecuteCommandFile(const bool vbAsyncMode) {
- std::ifstream ifsStartScript(m_strCmdLineArgCommandFileNamePath.c_str());
- if (!ifsStartScript.is_open()) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN),
- m_strCmdLineArgCommandFileNamePath.c_str()));
- SetErrorDescription(errMsg.c_str());
- const bool bForceExit = true;
- SetExitApplicationFlag(bForceExit);
- return MIstatus::failure;
- }
-
- // Switch lldb to synchronous mode
- CMICmnLLDBDebugSessionInfo &rSessionInfo(
- CMICmnLLDBDebugSessionInfo::Instance());
- const bool bAsyncSetting = rSessionInfo.GetDebugger().GetAsync();
- rSessionInfo.GetDebugger().SetAsync(vbAsyncMode);
-
- // Execute commands from file
- bool bOk = MIstatus::success;
- CMIUtilString strCommand;
- while (!m_bExitApp && std::getline(ifsStartScript, strCommand)) {
- // Print command
- bOk = CMICmnStreamStdout::TextToStdout(strCommand);
-
- // Skip if it's a comment or empty line
- if (strCommand.empty() || strCommand[0] == '#')
- continue;
-
- // Execute if no error
- if (bOk) {
- CMIUtilThreadLock lock(rSessionInfo.GetSessionMutex());
- bOk = InterpretCommand(strCommand);
- }
-
- // Draw the prompt after command will be executed (if enabled)
- bOk = bOk && CMICmnStreamStdout::WritePrompt();
-
- // Exit if there is an error
- if (!bOk) {
- const bool bForceExit = true;
- SetExitApplicationFlag(bForceExit);
- break;
- }
-
- // Wait while the handler thread handles incoming events
- CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
- }
-
- // Switch lldb back to initial mode
- rSessionInfo.GetDebugger().SetAsync(bAsyncSetting);
-
- return bOk;
-}
-
-//++
-// Details: Gets called when lldb-mi gets a signal. Stops the process if it was
-// SIGINT.
-//
-// Type: Method.
-// Args: signal that was delivered
-// Return: None.
-// Throws: None.
-//--
-void CMIDriver::DeliverSignal(int signal) {
- if (signal == SIGINT &&
- (m_eCurrentDriverState == eDriverState_RunningDebugging))
- InterpretCommand("-exec-interrupt");
-}
diff --git a/tools/lldb-mi/MIDriver.h b/tools/lldb-mi/MIDriver.h
deleted file mode 100644
index 03bbb3e75151..000000000000
--- a/tools/lldb-mi/MIDriver.h
+++ /dev/null
@@ -1,180 +0,0 @@
-//===-- MIDriver.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <queue>
-
-// In-house headers:
-#include "MICmdData.h"
-#include "MICmnBase.h"
-#include "MICmnConfig.h"
-#include "MICmnStreamStdin.h"
-#include "MIDriverBase.h"
-#include "MIDriverMgr.h"
-#include "MIUtilSingletonBase.h"
-
-// Declarations:
-class CMICmnLLDBDebugger;
-class CMICmnStreamStdout;
-
-//++
-//============================================================================
-// Details: MI driver implementation class. A singleton class derived from
-// LLDB SBBroadcaster class. Register the instance of *this class with
-// the CMIDriverMgr. The CMIDriverMgr sets the driver(s) of to start
-// work depending on the one selected to work. A driver can if not able
-// to handle an instruction or 'command' can pass that command onto
-// another driver object registered with the Driver Manager.
-//--
-class CMIDriver : public CMICmnBase,
- public CMIDriverMgr::IDriver,
- public CMIDriverBase,
- public MI::ISingleton<CMIDriver> {
- friend class MI::ISingleton<CMIDriver>;
-
- // Enumerations:
-public:
- //++ ----------------------------------------------------------------------
- // Details: The MI Driver has a running state which is used to help determine
- // which specific action(s) it should take or not allow.
- // The driver when operational and not shutting down alternates
- // between eDriverState_RunningNotDebugging and
- // eDriverState_RunningDebugging. eDriverState_RunningNotDebugging
- // is normally set when a breakpoint is hit or halted.
- // eDriverState_RunningDebugging is normally set when "exec-continue"
- // or "exec-run" is issued.
- //--
- enum DriverState_e {
- eDriverState_NotRunning = 0, // The MI Driver is not operating
- eDriverState_Initialising, // The MI Driver is setting itself up
- eDriverState_RunningNotDebugging, // The MI Driver is operational acting on
- // any MI commands sent to it
- eDriverState_RunningDebugging, // The MI Driver is currently overseeing an
- // inferior program that is running
- eDriverState_ShuttingDown, // The MI Driver is tearing down resources and
- // about exit
- eDriverState_count // Always last
- };
-
- // Methods:
-public:
- // MI system
- bool Initialize() override;
- bool Shutdown() override;
-
- // MI state
- bool GetExitApplicationFlag() const;
- DriverState_e GetCurrentDriverState() const;
- bool SetDriverStateRunningNotDebugging();
- bool SetDriverStateRunningDebugging();
- void SetDriverDebuggingArgExecutable();
- bool IsDriverDebuggingArgExecutable() const;
-
- // MI information about itself
- const CMIUtilString &GetAppNameShort() const;
- const CMIUtilString &GetAppNameLong() const;
- const CMIUtilString &GetVersionDescription() const;
-
- // MI do work
- bool WriteMessageToLog(const CMIUtilString &vMessage);
- bool SetEnableFallThru(const bool vbYes);
- bool GetEnableFallThru() const;
- bool HaveExecutableFileNamePathOnCmdLine() const;
- const CMIUtilString &GetExecutableFileNamePathOnCmdLine() const;
-
- // Overridden:
-public:
- // From CMIDriverMgr::IDriver
- bool DoInitialize() override;
- bool DoShutdown() override;
- bool DoMainLoop() override;
- lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut,
- bool &vwbExiting) override;
- CMIUtilString GetError() const override;
- const CMIUtilString &GetName() const override;
- lldb::SBDebugger &GetTheDebugger() override;
- bool GetDriverIsGDBMICompatibleDriver() const override;
- bool SetId(const CMIUtilString &vId) override;
- const CMIUtilString &GetId() const override;
- // From CMIDriverBase
- void SetExitApplicationFlag(const bool vbForceExit) override;
- bool DoFallThruToAnotherDriver(const CMIUtilString &vCmd,
- CMIUtilString &vwErrMsg) override;
- bool SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver) override;
- FILE *GetStdin() const override;
- FILE *GetStdout() const override;
- FILE *GetStderr() const override;
- const CMIUtilString &GetDriverName() const override;
- const CMIUtilString &GetDriverId() const override;
- void DeliverSignal(int signal) override;
-
- // Typedefs:
-private:
- typedef std::queue<CMIUtilString> QueueStdinLine_t;
-
- // Methods:
-private:
- /* ctor */ CMIDriver();
- /* ctor */ CMIDriver(const CMIDriver &);
- void operator=(const CMIDriver &);
-
- lldb::SBError ParseArgs(const int argc, const char *argv[], FILE *vpStdOut,
- bool &vwbExiting);
- bool DoAppQuit();
- bool InterpretCommand(const CMIUtilString &vTextLine);
- bool InterpretCommandThisDriver(const CMIUtilString &vTextLine,
- bool &vwbCmdYesValid);
- CMIUtilString
- WrapCLICommandIntoMICommand(const CMIUtilString &vTextLine) const;
- bool InterpretCommandFallThruDriver(const CMIUtilString &vTextLine,
- bool &vwbCmdYesValid);
- bool ExecuteCommand(const SMICmdData &vCmdData);
- bool StartWorkerThreads();
- bool StopWorkerThreads();
- bool InitClientIDEToMIDriver() const;
- bool InitClientIDEEclipse() const;
- bool LocalDebugSessionStartupExecuteCommands();
- bool ExecuteCommandFile(const bool vbAsyncMode);
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMIDriver() override;
-
- // Attributes:
-private:
- static const CMIUtilString ms_constAppNameShort;
- static const CMIUtilString ms_constAppNameLong;
- static const CMIUtilString ms_constMIVersion;
- //
- bool m_bFallThruToOtherDriverEnabled; // True = yes fall through, false = do
- // not pass on command
- CMIUtilThreadMutex m_threadMutex;
- bool m_bDriverIsExiting; // True = yes, driver told to quit, false = continue
- // working
- void *m_handleMainThread; // *this driver is run by the main thread
- CMICmnStreamStdin &m_rStdin;
- CMICmnLLDBDebugger &m_rLldbDebugger;
- CMICmnStreamStdout &m_rStdOut;
- DriverState_e m_eCurrentDriverState;
- bool m_bHaveExecutableFileNamePathOnCmdLine; // True = yes, executable given
- // as one of the parameters to
- // the MI Driver, false = not
- // found
- CMIUtilString m_strCmdLineArgExecuteableFileNamePath;
- bool m_bDriverDebuggingArgExecutable; // True = the MI Driver (MI mode) is
- // debugging executable passed as
- // argument,
- // false = running via a client (e.g. Eclipse)
- bool m_bHaveCommandFileNamePathOnCmdLine; // True = file with initial commands
- // given as one of the parameters to
- // the MI Driver, false = not found
- CMIUtilString m_strCmdLineArgCommandFileNamePath;
-};
diff --git a/tools/lldb-mi/MIDriverBase.cpp b/tools/lldb-mi/MIDriverBase.cpp
deleted file mode 100644
index b8844e288430..000000000000
--- a/tools/lldb-mi/MIDriverBase.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-//===-- MIDriverBase.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#include "lldb/API/SBBroadcaster.h"
-#include "lldb/API/SBEvent.h"
-
-// In-house headers:
-#include "MIDriverBase.h"
-
-//++
-// Details: CMIDriverBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriverBase::CMIDriverBase()
- : m_pDriverFallThru(nullptr), m_pDriverParent(nullptr), m_bExitApp(false) {}
-
-//++
-// Details: CMIDriverBase destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriverBase::~CMIDriverBase() { m_pDriverFallThru = nullptr; }
-
-//++
-// Details: This function allows *this driver to call on another driver to
-// perform work
-// should this driver not be able to handle the client data input.
-// Type: Overrideable.
-// Check the error message if the function returns a failure.
-// Type: Overridden.
-// Args: vCmd - (R) Command instruction to interpret.
-// vwErrMsg - (W) Status description on command failing.
-// Return: MIstatus::success - Command succeeded.
-// MIstatus::failure - Command failed.
-// Throws: None.
-//--
-bool CMIDriverBase::DoFallThruToAnotherDriver(const CMIUtilString &vCmd,
- CMIUtilString &vwErrMsg) {
- // Do nothing - override and implement. Use m_pDriverFallThru.
- return MIstatus::success;
-}
-
-//++
-// Details: This function allows *this driver to call on another driver to
-// perform work
-// should this driver not be able to handle the client data input.
-// Type: Overrideable.
-// Args: vrOtherDriver - (R) Reference to another driver object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverBase::SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver) {
- MIunused(vrOtherDriver);
-
- // Do nothing - override and implement. Set m_pDriverFallThru.
-
- return MIstatus::success;
-}
-
-//++
-// Details: This function allows *this driver to call functionality on the
-// parent driver
-// ask for information for example.
-// Type: Overrideable.
-// Args: vrOtherDriver - (R) Reference to another driver object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverBase::SetDriverParent(const CMIDriverBase &vrOtherDriver) {
- MIunused(vrOtherDriver);
-
- // Do nothing - override and implement. Set m_pDriverParent.
-
- return MIstatus::success;
-}
-
-//++
-// Details: Retrieve the parent driver to *this driver if one assigned. If
-// assigned *this
-// is the pass through driver that the parent driver passes work to.
-// Type: Method.
-// Args: None.
-// Return: CMIDriverBase * - Pointer to a driver object.
-// - NULL = there is not parent to *this driver.
-// Throws: None.
-//--
-CMIDriverBase *CMIDriverBase::GetDriversParent() const {
- return m_pDriverParent;
-}
-
-//++
-// Details: Retrieve the pointer to the other fall through driver *this driver
-// is using
-// (or not using).
-// Type: Method.
-// Args: None.
-// Return: CMIDriverBase * - Pointer to other driver.
-// - NULL if no driver set.
-// Throws: None.
-//--
-CMIDriverBase *CMIDriverBase::GetDriverToFallThruTo() const {
- return m_pDriverFallThru;
-}
-
-//++
-// Details: *this driver provides a file stream to other drivers on which *this
-// driver
-// write's out to and they read as expected input. *this driver is
-// passing
-// through commands to the (child) pass through assigned driver.
-// Type: Overrideable.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriverBase::GetStdin() const {
- // Do nothing - override and implement
- return nullptr;
-}
-
-//++
-// Details: *this driver provides a file stream to other pass through assigned
-// drivers
-// so they know what to write to.
-// Type: Overrideable.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriverBase::GetStdout() const {
- // Do nothing - override and implement
- return nullptr;
-}
-
-//++
-// Details: *this driver provides a error file stream to other pass through
-// assigned drivers
-// so they know what to write to.
-// Type: Overrideable.
-// Args: None.
-// Return: FILE * - Pointer to stream.
-// Throws: None.
-//--
-FILE *CMIDriverBase::GetStderr() const {
- // Do nothing - override and implement
- return nullptr;
-}
-
-//++
-// Details: Set the MI Driver's exit application flag. The application checks
-// this flag
-// after every stdin line is read so the exit may not be instantaneous.
-// If vbForceExit is false the MI Driver queries its state and
-// determines if is
-// should exit or continue operating depending on that running state.
-// Type: Overrideable.
-// Args: vbForceExit - (R) True = Do not query, set state to exit, false =
-// query if can/should exit right now.
-// Return: None.
-// Throws: None.
-//--
-void CMIDriverBase::SetExitApplicationFlag(const bool vbForceExit) {
- MIunused(vbForceExit);
-
- // Do nothing - override and implement
-}
diff --git a/tools/lldb-mi/MIDriverBase.h b/tools/lldb-mi/MIDriverBase.h
deleted file mode 100644
index aec306e4b40a..000000000000
--- a/tools/lldb-mi/MIDriverBase.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- MIDriverBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBBroadcaster.h"
-#include "lldb/API/SBDebugger.h"
-
-// In-house headers:
-#include "MIUtilString.h"
-
-// Declarations:
-namespace lldb {
-class SBBroadcaster;
-}
-
-//++
-//============================================================================
-// Details: MI driver base implementation class. This class has been created so
-// not have to edit the lldb::SBBroadcaster class code. Functionality
-// and attributes need to be common to the LLDB Driver class and the
-// MI Driver class (derived from lldb::SBBroadcaster) so they can call
-// upon each other for functionality fall through and allow the
-// CDriverMgr to manage either (any) driver to be operated on.
-// Each driver instance (the CMIDriver, LLDB::Driver) has its own
-// LLDB::SBDebugger object.
-//--
-class CMIDriverBase {
- // Methods:
-public:
- /* ctor */ CMIDriverBase();
-
- CMIDriverBase *GetDriverToFallThruTo() const;
- CMIDriverBase *GetDriversParent() const;
-
- // Overrideable:
-public:
- /* dtor */ virtual ~CMIDriverBase();
-
- virtual bool DoFallThruToAnotherDriver(const CMIUtilString &vCmd,
- CMIUtilString &vwErrMsg);
- virtual bool SetDriverToFallThruTo(const CMIDriverBase &vrOtherDriver);
- virtual bool SetDriverParent(const CMIDriverBase &vrOtherDriver);
- virtual const CMIUtilString &GetDriverName() const = 0;
- virtual const CMIUtilString &GetDriverId() const = 0;
- virtual void SetExitApplicationFlag(const bool vbForceExit);
-
- // MI provide information for the pass through (child) assigned driver
- virtual FILE *GetStdin() const;
- virtual FILE *GetStdout() const;
- virtual FILE *GetStderr() const;
-
- // Attributes:
-protected:
- CMIDriverBase *m_pDriverFallThru; // Child driver to use should *this driver
- // not be able to handle client input
- CMIDriverBase *m_pDriverParent; // The parent driver who passes work to *this
- // driver to do work
- CMIUtilString m_strDriverId;
- bool m_bExitApp; // True = Yes, exit application, false = continue execution
-};
diff --git a/tools/lldb-mi/MIDriverMain.cpp b/tools/lldb-mi/MIDriverMain.cpp
deleted file mode 100644
index 8bc4571a458d..000000000000
--- a/tools/lldb-mi/MIDriverMain.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//===-- MIDriverMain.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
-//
-//===----------------------------------------------------------------------===//
-
-// Overview: Defines the entry point for the console application.
-// The MI application (project name MI) runs in two modes:
-// An LLDB native driver mode where it acts no different from the
-// LLDB driver.
-// The other mode is the MI when it finds on the command line
-// the --interpreter option. Command line argument --help on its
-// own will give
-// help for the LLDB driver. If entered with --interpreter then MI
-// help will
-// provided.
-// To implement new MI commands derive a new command class from the
-// command base
-// class. To enable the new command for interpretation add the new
-// command class
-// to the command factory. The files of relevance are:
-// MICmdCommands.cpp
-// MICmdBase.h / .cpp
-// MICmdCmd.h / .cpp
-
-// Third party headers:
-#include "lldb/API/SBHostOS.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
-#include <atomic>
-#include <csignal>
-#include <stdio.h>
-
-// In house headers:
-#include "MICmnConfig.h"
-#include "MICmnResources.h"
-#include "MICmnStreamStdin.h"
-#include "MIDriver.h"
-#include "MIDriverMgr.h"
-#include "MIUtilDebug.h"
-#include "Platform.h"
-
-#if defined(_MSC_VER)
-#pragma warning( \
- once : 4530) // Warning C4530: C++ exception handler used, but unwind
- // semantics are not enabled. Specify /EHsc
-#endif // _MSC_VER
-
-// CODETAG_IOR_SIGNALS
-//++
-// Details: The SIGINT signal is sent to a process by its controlling terminal
-// when a
-// user wishes to interrupt the process. This is typically initiated by
-// pressing
-// Control-C, but on some systems, the "delete" character or "break"
-// key can be
-// used.
-// Be aware this function may be called on another thread besides the
-// main thread.
-// Type: Function.
-// Args: vSigno - (R) Signal number.
-// Return: None.
-// Throws: None.
-//--
-void sigint_handler(int vSigno) {
-#ifdef _WIN32 // Restore handler as it is not persistent on Windows
- signal(SIGINT, sigint_handler);
-#endif
- static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
- if (pDebugger != nullptr) {
- if (!g_interrupt_sent.test_and_set()) {
- pDebugger->DispatchInputInterrupt();
- g_interrupt_sent.clear();
- }
- }
-
- // Send signal to driver so that it can take suitable action
- rDriverMgr.DeliverSignal(vSigno);
-}
-
-//++
-// Details: Init the MI driver system. Initialize the whole driver system which
-// includes
-// both the original LLDB driver and the MI driver.
-// Type: Function.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool DriverSystemInit() {
- bool bOk = MIstatus::success;
- CMIDriver &rMIDriver = CMIDriver::Instance();
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- bOk = rDriverMgr.Initialize();
-
- // Register MIDriver first as it needs to initialize and be ready
- // for the Driver to get information from MIDriver when it initializes
- // (LLDB Driver is registered with the Driver Manager in MI's Initialize())
- bOk = bOk &&
- rDriverMgr.RegisterDriver(rMIDriver, "MIDriver"); // Will be main driver
-
- return bOk;
-}
-
-//++
-// Details: Shutdown the debugger system. Release / terminate resources external
-// to
-// specifically the MI driver.
-// Type: Function.
-// Args: vbAppExitOk - (R) True = No problems, false = App exiting with
-// problems (investigate!).
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool DriverSystemShutdown(const bool vbAppExitOk) {
- bool bOk = MIstatus::success;
-
- // *** Order is important here ***
- CMIDriverMgr::Instance().Shutdown();
- return bOk;
-}
-
-//++
-// Details: MI's application start point of execution. The application runs in
-// two modes.
-// An LLDB native driver mode where it acts no different from the LLDB
-// driver.
-// The other mode is the MI when it finds on the command line
-// the --interpreter option. Command line argument --help on its own
-// will give
-// help for the LLDB driver. If entered with --interpreter then
-// application
-// help will provided.
-// Type: Method.
-// Args: argc - (R) An integer that contains the count of arguments that
-// follow in
-// argv. The argc parameter is always greater than or
-// equal to 1.
-// argv - (R) An array of null-terminated strings representing
-// command-line
-// arguments entered by the user of the program. By
-// convention,
-// argv[0] is the command with which the program is
-// invoked.
-// Return: int - 0 = Normal exit, program success.
-// >0 = Program success with status i.e. Control-C signal
-// status
-// <0 = Program failed.
-// -1 = Program failed reason not specified here, see MI log
-// file.
-// -1000 = Program failed did not initialize successfully.
-// Throws: None.
-//--
-int main(int argc, char const *argv[]) {
-#if MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
- CMIUtilDebug::WaitForDbgAttachInfinteLoop();
-#endif // MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
-
- llvm::StringRef ToolName = argv[0];
- llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
- llvm::PrettyStackTraceProgram X(argc, argv);
-
- // *** Order is important here ***
- bool bOk = DriverSystemInit();
- if (!bOk) {
- DriverSystemShutdown(bOk);
- return -1000;
- }
-
- // CODETAG_IOR_SIGNALS
- signal(SIGINT, sigint_handler);
-
- bool bExiting = false;
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- bOk = bOk && rDriverMgr.ParseArgs(argc, argv, bExiting);
- if (bOk && !bExiting)
- bOk = rDriverMgr.DriverParseArgs(argc, argv, stdout, bExiting);
- if (bOk && !bExiting)
- bOk = rDriverMgr.DriverMainLoop();
-
- // Logger and other resources shutdown now
- DriverSystemShutdown(bOk);
-
- const int appResult = bOk ? 0 : -1;
-
- return appResult;
-}
diff --git a/tools/lldb-mi/MIDriverMgr.cpp b/tools/lldb-mi/MIDriverMgr.cpp
deleted file mode 100644
index 26195cdb7414..000000000000
--- a/tools/lldb-mi/MIDriverMgr.cpp
+++ /dev/null
@@ -1,727 +0,0 @@
-//===-- MIDriverMgr.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third Party Headers:
-#include "lldb/API/SBError.h"
-
-// In-house headers:
-#include "MICmnLog.h"
-#include "MICmnLogMediumFile.h"
-#include "MICmnResources.h"
-#include "MICmnStreamStdout.h"
-#include "MIDriver.h"
-#include "MIDriverMgr.h"
-#include "MIUtilSingletonHelper.h"
-
-//++
-// Details: CMIDriverMgr constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriverMgr::CMIDriverMgr() : m_pDriverCurrent(nullptr), m_bInMi2Mode(false) {}
-
-//++
-// Details: CMIDriverMgr destructor.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIDriverMgr::~CMIDriverMgr() { Shutdown(); }
-
-//++
-// Details: Initialize *this manager.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::Initialize() {
- m_clientUsageRefCnt++;
-
- ClrErrorDescription();
-
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on
- // previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
-
- m_bInitialized = bOk;
-
- if (!bOk) {
- CMIUtilString strInitError(CMIUtilString::Format(
- MIRSRC(IDS_MI_INIT_ERR_DRIVERMGR), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
-
- return bOk;
-}
-
-//++
-// Details: Unbind detach or release resources used by this server in general
-// common
-// functionality shared between versions of any server interfaces
-// implemented.
-// Type: Method.
-// Args: vbAppExitOk - (R) True = No problems, false = App exiting with
-// problems (investigate!).
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::Shutdown() {
- // Do not want a ref counter because this function needs to be called how ever
- // this
- // application stops running
- // if( --m_clientUsageRefCnt > 0 )
- // return MIstatus::success;
-
- ClrErrorDescription();
-
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Tidy up
- UnregisterDriverAll();
-
- // Note shutdown order is important here
- MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
-
- if (!bOk) {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_DRIVERMGR), errMsg.c_str());
- }
-
- return bOk;
-}
-//++
-// Details: Unregister all the Driver registered with *this manager. The manager
-// also
-// deletes
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::UnregisterDriverAll() {
- MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
- while (it != m_mapDriverIdToDriver.end()) {
- IDriver *pDriver = (*it).second;
- pDriver->DoShutdown();
-
- // Next
- ++it;
- }
-
- m_mapDriverIdToDriver.clear();
- m_pDriverCurrent = nullptr;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Register a driver with *this Driver Manager. Call
-// SetUseThisDriverToDoWork()
-// inform the manager which driver is the one to the work. The manager
-// calls
-// the driver's init function which must be successful in order to
-// complete the
-// registration.
-// Type: Method.
-// Args: vrDriver - (R) The driver to register.
-// vrDriverID - (R) The driver's ID to lookup by.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::RegisterDriver(const IDriver &vrDriver,
- const CMIUtilString &vrDriverID) {
- if (HaveDriverAlready(vrDriver))
- return MIstatus::success;
-
- IDriver *pDriver = const_cast<IDriver *>(&vrDriver);
- if (!pDriver->SetId(vrDriverID))
- return MIstatus::failure;
- if (!pDriver->DoInitialize()) {
- SetErrorDescriptionn(MIRSRC(IDS_DRIVERMGR_DRIVER_ERR_INIT),
- pDriver->GetName().c_str(), vrDriverID.c_str(),
- pDriver->GetError().c_str());
- return MIstatus::failure;
- }
-
- MapPairDriverIdToDriver_t pr(vrDriverID, pDriver);
- m_mapDriverIdToDriver.insert(pr);
-
- return MIstatus::success;
-}
-
-//++
-// Details: Query the Driver Manager to see if *this manager has the driver
-// already
-// registered.
-// Type: Method.
-// Args: vrDriver - (R) The driver to query.
-// Return: True - registered.
-// False - not registered.
-// Throws: None.
-//--
-bool CMIDriverMgr::HaveDriverAlready(const IDriver &vrDriver) const {
- MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
- while (it != m_mapDriverIdToDriver.end()) {
- const IDriver *pDrvr = (*it).second;
- if (pDrvr == &vrDriver)
- return true;
-
- // Next
- ++it;
- }
-
- return false;
-}
-
-//++
-// Details: Unregister a driver from the Driver Manager. Call the
-// SetUseThisDriverToDoWork()
-// function to define another driver to do work if the one being
-// unregistered did
-// the work previously.
-// Type: Method.
-// Args: vrDriver - (R) The driver to unregister.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::UnregisterDriver(const IDriver &vrDriver) {
- const IDriver *pDrvr = nullptr;
- MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
- while (it != m_mapDriverIdToDriver.end()) {
- pDrvr = (*it).second;
- if (pDrvr == &vrDriver)
- break;
-
- // Next
- ++it;
- }
- m_mapDriverIdToDriver.erase(it);
-
- if (m_pDriverCurrent == pDrvr)
- m_pDriverCurrent = nullptr;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Specify the driver to do work. The Driver Manager drives this
-// driver. Any
-// previous driver doing work is not called anymore (so be sure the
-// previous
-// driver is in a tidy state before stopping it working).
-// Type: Method.
-// Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::SetUseThisDriverToDoWork(const IDriver &vrADriver) {
- m_pDriverCurrent = const_cast<IDriver *>(&vrADriver);
-
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_DRIVER_SAY_DRIVER_USING),
- m_pDriverCurrent->GetName().c_str()));
- m_pLog->Write(msg, CMICmnLog::eLogVerbosity_Log);
-
- m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver();
-
- return MIstatus::success;
-}
-
-//++
-// Details: Ask *this manager which driver is currently doing the work.
-// Type: Method.
-// Args: None.
-// Return: IDriver * - Pointer to a driver, NULL if there is no current working
-// driver.
-// Throws: None.
-//--
-CMIDriverMgr::IDriver *CMIDriverMgr::GetUseThisDriverToDoWork() const {
- return m_pDriverCurrent;
-}
-
-//++
-// Details: Call this function puts *this driver to work.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::DriverMainLoop() {
- if (m_pDriverCurrent != nullptr) {
- if (!m_pDriverCurrent->DoMainLoop()) {
- const CMIUtilString errMsg(
- CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_MAINLOOP),
- m_pDriverCurrent->GetError().c_str()));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- return MIstatus::failure;
- }
- } else {
- const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Get the current driver to validate executable command line
-// arguments.
-// Type: Method.
-// Args: argc - (R) An integer that contains the count of arguments
-// that follow in
-// argv. The argc parameter is always greater than
-// or equal to 1.
-// argv - (R) An array of null-terminated strings representing
-// command-line
-// arguments entered by the user of the program. By
-// convention,
-// argv[0] is the command with which the program is
-// invoked.
-// vpStdOut - (R) Point to a standard output stream.
-// vwbExiting - (W) True = *this want to exit, false = continue to
-// work.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIDriverMgr::DriverParseArgs(const int argc, const char *argv[],
- FILE *vpStdOut, bool &vwbExiting) {
- if (m_pDriverCurrent == nullptr) {
- const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- return MIstatus::failure;
- }
-
- const lldb::SBError error(
- m_pDriverCurrent->DoParseArgs(argc, argv, vpStdOut, vwbExiting));
- bool bOk = !error.Fail();
- if (!bOk) {
- CMIUtilString errMsg;
- const char *pErrorCstr = error.GetCString();
- if (pErrorCstr != nullptr)
- errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS),
- m_pDriverCurrent->GetName().c_str(),
- pErrorCstr);
- else
- errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN),
- m_pDriverCurrent->GetName().c_str());
-
- bOk = CMICmnStreamStdout::Instance().Write(errMsg, true);
- }
-
- return bOk;
-}
-
-//++
-// Details: Retrieve the current driver's last error condition.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString CMIDriverMgr::DriverGetError() const {
- if (m_pDriverCurrent != nullptr)
- return m_pDriverCurrent->GetError();
- else {
- const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- }
-
- return CMIUtilString();
-}
-
-//++
-// Details: Retrieve the current driver's name.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Driver name.
-// Empty string = no current working driver specified.
-// Throws: None.
-//--
-CMIUtilString CMIDriverMgr::DriverGetName() const {
- if (m_pDriverCurrent != nullptr)
- return m_pDriverCurrent->GetName();
- else {
- const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- }
-
- return CMIUtilString();
-}
-
-//++
-// Details: Retrieve the current driver's debugger object.
-// Type: Method.
-// Args: None.
-// Return: lldb::SBDebugger * - Ptr to driver's debugger object.
-// - NULL = no current working driver specified.
-// Throws: None.
-//--
-lldb::SBDebugger *CMIDriverMgr::DriverGetTheDebugger() {
- lldb::SBDebugger *pDebugger = nullptr;
- if (m_pDriverCurrent != nullptr)
- pDebugger = &m_pDriverCurrent->GetTheDebugger();
- else {
- const CMIUtilString errMsg(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- }
-
- return pDebugger;
-}
-
-//++
-// Details: Check the arguments given on the command line. The main purpose of
-// this
-// function is to check for the presence of the --interpreter option.
-// Having
-// this option present tells *this manager to set the CMIDriver to do
-// work. If
-// not use the LLDB driver. The following are options that are only
-// handled by
-// the CMIDriverMgr are:
-// --help or -h
-// --interpreter
-// --version
-// --versionLong
-// --log
-// --executable
-// --log-dir
-// The above arguments are not handled by any driver object except for
-// --executable.
-// The options --interpreter and --executable in code act very similar.
-// The
-// --executable is necessary to differentiate whither the MI Driver is
-// being using
-// by a client i.e. Eclipse or from the command line. Eclipse issues
-// the option
-// --interpreter and also passes additional arguments which can be
-// interpreted as an
-// executable if called from the command line. Using --executable tells
-// the MI
-// Driver is being called the command line and that the executable
-// argument is indeed
-// a specified executable an so actions commands to set up the
-// executable for a
-// debug session. Using --interpreter on the command line does not
-// action additional
-// commands to initialise a debug session and so be able to launch the
-// process. The directory
-// where the log file is created is specified using --log-dir.
-// Type: Method.
-// Args: argc - (R) An integer that contains the count of arguments
-// that follow in
-// argv. The argc parameter is always greater than
-// or equal to 1.
-// argv - (R) An array of null-terminated strings representing
-// command-line
-// arguments entered by the user of the program. By
-// convention,
-// argv[0] is the command with which the program is
-// invoked.
-// vwbExiting - (W) True = *this want to exit, Reasons: help,
-// invalid arg(s),
-// version information only.
-// False = Continue to work, start debugger i.e.
-// Command
-// interpreter.
-// Return: lldb::SBError - LLDB current error status.
-// Throws: None.
-//--
-bool CMIDriverMgr::ParseArgs(const int argc, const char *argv[],
- bool &vwbExiting) {
- bool bOk = MIstatus::success;
-
- vwbExiting = false;
-
- // Print MI application path to the Log file
- const CMIUtilString appPath(
- CMIUtilString::Format(MIRSRC(IDS_MI_APP_FILEPATHNAME), argv[0]));
- bOk = m_pLog->Write(appPath, CMICmnLog::eLogVerbosity_Log);
-
- // Print application arguments to the Log file
- const bool bHaveArgs(argc >= 2);
- CMIUtilString strArgs(MIRSRC(IDS_MI_APP_ARGS));
- if (!bHaveArgs) {
- strArgs += MIRSRC(IDS_WORD_NONE);
- bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
- } else {
- for (MIint i = 1; i < argc; i++) {
- strArgs += CMIUtilString::Format("%d:'%s' ", i,
- CMIUtilString::WithNullAsEmpty(argv[i]));
- }
- bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
- }
-
- // Look for the command line options
- bool bHaveArgInterpret = false;
- bool bHaveArgVersion = false;
- bool bHaveArgVersionLong = false;
- bool bHaveArgLog = false;
- bool bHaveArgLogDir = false;
- bool bHaveArgHelp = false;
- CMIUtilString strLogDir;
-
- bHaveArgInterpret = true;
- if (bHaveArgs) {
- // CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
- for (MIint i = 1; i < argc; i++) {
- // *** Add args to help in GetHelpOnCmdLineArgOptions() ***
- const CMIUtilString strArg(argv[i]);
-
- // Argument "--executable" is also check for in CMIDriver::ParseArgs()
- if (("--interpreter" == strArg) || // Given by the client such as Eclipse
- ("--executable" == strArg)) // Used to specify that there
- // is executable argument also
- // on the command line
- { // See fn description.
- bHaveArgInterpret = true;
- }
- if ("--version" == strArg) {
- bHaveArgVersion = true;
- }
- if ("--versionLong" == strArg) {
- bHaveArgVersionLong = true;
- }
- if ("--log" == strArg) {
- bHaveArgLog = true;
- }
- if (0 == strArg.compare(0, 10, "--log-dir=")) {
- strLogDir = strArg.substr(10, CMIUtilString::npos);
- bHaveArgLogDir = true;
- }
- if (("--help" == strArg) || ("-h" == strArg)) {
- bHaveArgHelp = true;
- }
- }
- }
-
- if (bHaveArgLog) {
- CMICmnLog::Instance().SetEnabled(true);
- }
-
- if (bHaveArgLogDir) {
- bOk = bOk && CMICmnLogMediumFile::Instance().SetDirectory(strLogDir);
- }
-
- // Todo: Remove this output when MI is finished. It is temporary to persuade
- // Eclipse plugin to work.
- // Eclipse reads this literally and will not work unless it gets this
- // exact version text.
- // Handle --version option (ignore the --interpreter option if present)
- if (bHaveArgVersion) {
- vwbExiting = true;
- bOk = bOk &&
- CMICmnStreamStdout::Instance().WriteMIResponse(
- MIRSRC(IDE_MI_VERSION_GDB));
- return bOk;
- }
-
- // Todo: Make this the --version when the above --version version is removed
- // Handle --versionlong option (ignore the --interpreter option if present)
- if (bHaveArgVersionLong) {
- vwbExiting = true;
- bOk =
- bOk && CMICmnStreamStdout::Instance().WriteMIResponse(GetAppVersion());
- return bOk;
- }
-
- // Both '--help' and '--interpreter' means give help for MI only. Without
- // '--interpreter' help the LLDB driver is working and so help is for that.
- if (bHaveArgHelp && bHaveArgInterpret) {
- vwbExiting = true;
- bOk = bOk &&
- CMICmnStreamStdout::Instance().WriteMIResponse(
- GetHelpOnCmdLineArgOptions());
- return bOk;
- }
-
- // This makes the assumption that there is at least one MI compatible
- // driver registered and one LLDB driver registered and the CMIDriver
- // is the first one found.
- // ToDo: Implement a better solution that handle any order, any number
- // of drivers. Or this 'feature' may be removed if deemed not required.
- IDriver *pLldbDriver = GetFirstNonMIDriver();
- IDriver *pMi2Driver = GetFirstMIDriver();
- if (bHaveArgInterpret && (pMi2Driver != nullptr))
- bOk = bOk && SetUseThisDriverToDoWork(*pMi2Driver);
- else if (pLldbDriver != nullptr)
- bOk = bOk && SetUseThisDriverToDoWork(*pLldbDriver);
- else {
- if (bOk) {
- vwbExiting = true;
- const CMIUtilString msg(MIRSRC(IDS_DRIVER_ERR_NON_REGISTERED));
- bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(msg);
- }
- }
-
- return bOk;
-}
-
-//++
-// Details: Return formatted application version and name information.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text data.
-// Throws: None.
-//--
-CMIUtilString CMIDriverMgr::GetAppVersion() const {
- const CMIUtilString strProj(MIRSRC(IDS_PROJNAME));
- const CMIUtilString strVsn(CMIDriver::Instance().GetVersionDescription());
- const CMIUtilString strGdb(MIRSRC(IDE_MI_VERSION_GDB));
- const CMIUtilString strVrsnInfo(CMIUtilString::Format(
- "%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str()));
-
- return strVrsnInfo;
-}
-
-//++
-// Details: Return formatted help information on all the MI command line
-// options.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text data.
-// Throws: None.
-//--
-CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions() const {
- const CMIUtilString pHelp[] = {
- MIRSRC(IDE_MI_APP_DESCRIPTION), MIRSRC(IDE_MI_APP_INFORMATION),
- MIRSRC(IDE_MI_APP_ARG_USAGE), MIRSRC(IDE_MI_APP_ARG_HELP),
- MIRSRC(IDE_MI_APP_ARG_VERSION), MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
- MIRSRC(IDE_MI_APP_ARG_INTERPRETER), MIRSRC(IDE_MI_APP_ARG_SOURCE),
- MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
- MIRSRC(IDE_MI_APP_ARG_SYNCHRONOUS),
- CMIUtilString::Format(
- MIRSRC(IDE_MI_APP_ARG_APP_LOG),
- CMICmnLogMediumFile::Instance().GetFileName().c_str()),
- MIRSRC(IDE_MI_APP_ARG_APP_LOG_DIR), MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
- MIRSRC(IDS_CMD_QUIT_HELP), MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
- const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[0];
- CMIUtilString strHelp;
- for (MIuint i = 0; i < nHelpItems; i++) {
- strHelp += pHelp[i];
- strHelp += "\n\n";
- }
-
- return strHelp;
-}
-
-//++
-// Details: Search the registered drivers and return the first driver which says
-// it is
-// GDB/MI compatible i.e. the CMIDriver class.
-// Type: Method.
-// Args: None.
-// Return: IDriver * - Ptr to driver, NULL = no driver found.
-// Throws: None.
-//--
-CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstMIDriver() const {
- IDriver *pDriver = nullptr;
- MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
- while (it != m_mapDriverIdToDriver.end()) {
- const CMIUtilString &rDrvId = (*it).first;
- MIunused(rDrvId);
- IDriver *pDvr = (*it).second;
- if (pDvr->GetDriverIsGDBMICompatibleDriver()) {
- pDriver = pDvr;
- break;
- }
-
- // Next
- ++it;
- }
-
- return pDriver;
-}
-
-//++
-// Details: Search the registered drivers and return the first driver which says
-// it is
-// not GDB/MI compatible i.e. the LLDB Driver class.
-// Type: Method.
-// Args: None.
-// Return: IDriver * - Ptr to driver, NULL = no driver found.
-// Throws: None.
-//--
-CMIDriverMgr::IDriver *CMIDriverMgr::GetFirstNonMIDriver() const {
- IDriver *pDriver = nullptr;
- MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
- while (it != m_mapDriverIdToDriver.end()) {
- const CMIUtilString &rDrvId = (*it).first;
- MIunused(rDrvId);
- IDriver *pDvr = (*it).second;
- if (!pDvr->GetDriverIsGDBMICompatibleDriver()) {
- pDriver = pDvr;
- break;
- }
-
- // Next
- ++it;
- }
-
- return pDriver;
-}
-
-//++
-// Details: Search the registered drivers and return driver with the specified
-// ID.
-// Type: Method.
-// Args: vrDriverId - (R) ID of a driver.
-// Return: IDriver * - Ptr to driver, NULL = no driver found.
-// Throws: None.
-//--
-CMIDriverMgr::IDriver *
-CMIDriverMgr::GetDriver(const CMIUtilString &vrDriverId) const {
- MapDriverIdToDriver_t::const_iterator it =
- m_mapDriverIdToDriver.find(vrDriverId);
- if (it == m_mapDriverIdToDriver.end())
- return nullptr;
-
- IDriver *pDriver = (*it).second;
-
- return pDriver;
-}
-
-//++
-// Details: Gets called when lldb-mi gets a signal. Passed signal to current
-// driver.
-//
-// Type: Method.
-// Args: signal that was delivered
-// Return: None.
-// Throws: None.
-//--
-void CMIDriverMgr::DeliverSignal(int signal) {
- if (m_pDriverCurrent != nullptr)
- m_pDriverCurrent->DeliverSignal(signal);
-}
diff --git a/tools/lldb-mi/MIDriverMgr.h b/tools/lldb-mi/MIDriverMgr.h
deleted file mode 100644
index a7a1dbbb9bf2..000000000000
--- a/tools/lldb-mi/MIDriverMgr.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- MIDriverMgr.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include "lldb/API/SBDebugger.h"
-#include <map>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnLog.h"
-#include "MIUtilSingletonBase.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI Driver Manager. Register lldb::SBBroadcaster derived Driver type
-// objects with *this manager. The manager does not own driver objects
-// registered with it and so will not delete when this manager is
-// shutdown. The Driver flagged as "use this one" will be set as
-// current
-// driver and will be the one that is used. Other drivers are not
-// operated. A Driver can call another Driver should it not handle a
-// command.
-// It also initializes other resources as part it's setup such as the
-// Logger and Resources objects (explicit indicate *this object
-// requires
-// those objects (modules/components) to support it's own
-// functionality).
-// The Driver manager is the first object instantiated as part of the
-// MI code base. It is also the first thing to interpret the command
-// line arguments passed to the executable. Bases on options it
-// understands the manage will set up the appropriate driver or give
-// help information. Other options are passed on to the driver chosen
-// to do work.
-// Each driver instance (the CMIDriver, LLDB::Driver) has its own
-// LLDB::SBDebugger.
-// Singleton class.
-//--
-class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr> {
- friend MI::ISingleton<CMIDriverMgr>;
-
- // Class:
-public:
- //++
- // Description: Driver deriver objects need this interface to work with
- // *this manager.
- //--
- class IDriver {
- public:
- virtual bool DoInitialize() = 0;
- virtual bool DoShutdown() = 0;
- virtual bool DoMainLoop() = 0;
- virtual lldb::SBError DoParseArgs(const int argc, const char *argv[],
- FILE *vpStdOut, bool &vwbExiting) = 0;
- virtual CMIUtilString GetError() const = 0;
- virtual const CMIUtilString &GetName() const = 0;
- virtual lldb::SBDebugger &GetTheDebugger() = 0;
- virtual bool GetDriverIsGDBMICompatibleDriver() const = 0;
- virtual bool SetId(const CMIUtilString &vId) = 0;
- virtual const CMIUtilString &GetId() const = 0;
- virtual void DeliverSignal(int signal) = 0;
-
- // Not part of the interface, ignore
- /* dtor */ virtual ~IDriver() {}
- };
-
- // Methods:
-public:
- // MI system
- bool Initialize() override;
- bool Shutdown() override;
- //
- CMIUtilString GetAppVersion() const;
- bool RegisterDriver(const IDriver &vrADriver,
- const CMIUtilString &vrDriverID);
- bool UnregisterDriver(const IDriver &vrADriver);
- bool SetUseThisDriverToDoWork(
- const IDriver &vrADriver); // Specify working main driver
- IDriver *GetUseThisDriverToDoWork() const;
- bool ParseArgs(const int argc, const char *argv[], bool &vwbExiting);
- IDriver *GetDriver(const CMIUtilString &vrDriverId) const;
- //
- // MI Proxy fn to current specified working driver
- bool DriverMainLoop();
- bool DriverParseArgs(const int argc, const char *argv[], FILE *vpStdOut,
- bool &vwbExiting);
- CMIUtilString DriverGetError() const;
- CMIUtilString DriverGetName() const;
- lldb::SBDebugger *DriverGetTheDebugger();
- void DeliverSignal(int signal);
-
- // Typedef:
-private:
- typedef std::map<CMIUtilString, IDriver *> MapDriverIdToDriver_t;
- typedef std::pair<CMIUtilString, IDriver *> MapPairDriverIdToDriver_t;
-
- // Methods:
-private:
- /* ctor */ CMIDriverMgr();
- /* ctor */ CMIDriverMgr(const CMIDriverMgr &);
- void operator=(const CMIDriverMgr &);
- //
- bool HaveDriverAlready(const IDriver &vrMedium) const;
- bool UnregisterDriverAll();
- IDriver *GetFirstMIDriver() const;
- IDriver *GetFirstNonMIDriver() const;
- CMIUtilString GetHelpOnCmdLineArgOptions() const;
-
- // Overridden:
-private:
- // From CMICmnBase
- /* dtor */ ~CMIDriverMgr() override;
-
- // Attributes:
-private:
- MapDriverIdToDriver_t m_mapDriverIdToDriver;
- IDriver *m_pDriverCurrent; // This driver is used by this manager to do work.
- // It is the main driver.
- bool m_bInMi2Mode; // True = --interpreter entered on the cmd line, false =
- // operate LLDB driver (non GDB)
-};
diff --git a/tools/lldb-mi/MIExtensions.txt b/tools/lldb-mi/MIExtensions.txt
deleted file mode 100644
index 70508b1d37bd..000000000000
--- a/tools/lldb-mi/MIExtensions.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-# -file-exec-and-symbols now takes two new (optional) options:
-
-Synopsis
-
- -file-exec-and-symbols <file> [-p <platform>] [-r <remote-file>]
-
-Specify the executable file to be debugged. This file is the one from which the symbol table is also read.
-When debugging remote targets specify a remote-file for execution and a file from which symbols are read.
-The optional platform is the name of the platform, e.g., "remote-ios" or "ios-simulator". The remote-file
-is the on-device path to the exe.
-
-# -data-info-line
-
-Synopsis
-
- -data-info-line *<address>
- -data-info-line <file>:<line>
-
-Provides information about a source line. The input can be <address> like 0x12345678 or <file>:<line>
-where file is a name of source file and line is the line number. As a result the command returns the following
-fields:
- start - address of the first instruction which refers to that source line
- end - address of the last instruction which refers to that source line
- file - the file name
- line - the line number
-The last two fields are useful in case you have specified a source line using its address.
-
-Example:
- -data-info-line *0x100000f80
- ^done,start="0x0000000100000f80",end="0x0000000100000f94",file="/Users/IliaK/p/hello.cpp",line="15"
-
- -data-info-line hello.cpp:15
- ^done,start="0x0000000100000f80",end="0x0000000100000f94",file="/Users/IliaK/p/hello.cpp",line="15"
-
-# -data-read-memory-bytes
-
-Synopsis
-
- -data-read-memory-bytes [--thread <thread-id>] [--frame <frame-index>] [-o <byte-offset>] <address> <count>
-
-Where:
-
- `address`
- An expression specifying the start of the memory range to read.
- `count`
- Number of bytes to read.
- `byte-offset`
- Relative offset in bytes from `address` where reading should start.
- `thread-id`
- Integer identifier of the thread within which the expression should be evaluated,
- if this option is omitted the currently selected thread will be used.
- This option is not in the MI specification but is implemented by GDB.
- `frame-index`
- Index of the frame within which the expression should be evaluated,
- if this option is omitted the currently selected frame will be used.
- This option is not in the MI specification but is implemented by GDB.
-
-Reads a block of memory from the specified range.
-
-Note that currently this command works in an all-or-nothing fashion where it either reads the entire
-block of memory successfully and returns it as a single block, or it returns an error. This doesn't
-quite match up with the MI specification that says that subsets of the specified range may be
-returned as individual blocks if only some of the memory within the specified range is accessible.
-
-The result record for this command may contain one or more tuples representing the blocks of memory
-that were read, where each tuple has the following fields:
-
- `begin`
- The start of the address range for this block (in hex notation).
- `end`
- The end of the address range for this block (in hex notation).
- `offset`
- Offset of this block from `address` (that was passed in as an argument).
- `contents`
- The actual data in this block (in hex notation).
-
-Example:
-
- (gdb)
- -data-read-memory-bytes &array 4
- ^done,memory=[{begin="0x00007fffffffeccc",offset="0x0000000000000000",end="0x00007fffffffecd0",contents="01020304"}]
- (gdb)
-
-# =library-loaded notification
-
-The =library-loaded notification has 4 extra fields:
- symbols-loaded - indicates that there are symbols for the loaded library
- symbols-path - if symbols are exist then it contains a path for symbols of the loaded library
- loaded_addr - contains an address of the loaded library or "-" if address isn't resolved yet
- size - contains the size in bytes of the section loaded at 'loaded_addr'
-
-For example:
- =library-loaded,id="/Users/IliaK/p/hello",target-name="/Users/IliaK/p/hello",host-name="/Users/IliaK/p/hello",symbols-loaded="1",symbols-path="/Users/IliaK/p/hello.dSYM/Contents/Resources/DWARF/hello",loaded_addr="-",size="4096"
- =library-loaded,id="/usr/lib/dyld",target-name="/usr/lib/dyld",host-name="/usr/lib/dyld",symbols-loaded="0",loaded_addr="0x00007fff5fc00000",size="4096"
-
-# -target-attach
-
-Synopsis
-
-Additional syntax provided by lldb-mi:
- -target-attach -n <executable-name> [--waitfor]
-
-Attach to an executable. Using -n allows specifying an executable name to attach to.
-Using this with --watifor can do a deffered attach. The flags -n and --waitfor match the syntax of lldb proper's 'process attach' command.
diff --git a/tools/lldb-mi/MIReadMe.txt b/tools/lldb-mi/MIReadMe.txt
deleted file mode 100644
index 51316ed879c5..000000000000
--- a/tools/lldb-mi/MIReadMe.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-========================================================================
- The MI Driver - LLDB Machine Interface V2 (MI) Project Overview
-========================================================================
-
-The MI Driver is a stand alone executable that either be used via a
-client i.e. Eclipse or directly from the command line.
-
-For help information on using the MI driver type at the command line:
-
- lldb-mi --interpreter --help
-
-A blog about the MI Driver is available on CodePlay's website. Although it may not be
-completely accurate after the recent changes in lldb-mi.
-http://www.codeplay.com/portal/lldb-mi-driver---part-1-introduction
-
-In MI mode and invoked with --log option, lldb-mi generates lldb-mi-log.txt
-This file keeps a history of the MI Driver's activity for one session. It is
-used to aid the debugging of the MI Driver. It also gives warnings about
-command's which do not support certain argument or options.
-
-Note any command or text sent to the MI Driver in MI mode that is not a command
-registered in the MI Driver's Command Factory will be rejected and an error message
-will be generated.
-
-All the files prefix with MI are specifically for the MI driver code only.
-File MIDriverMain.cpp contains the executables main() function.
-
-=========================================================================
-Current limitations:
-1. Not all commands and their options have been implemented. Please see
-the source code for details.
-2. LLDB-MI may have additional arguments not used in GDB MI. Please see
-MIExtensions.txt
-
-=========================================================================
-The MI Driver build configuration:
-MICmnConfig.h defines various preprocessor build options.
diff --git a/tools/lldb-mi/MIUtilDateTimeStd.cpp b/tools/lldb-mi/MIUtilDateTimeStd.cpp
deleted file mode 100644
index e92250a4f2d2..000000000000
--- a/tools/lldb-mi/MIUtilDateTimeStd.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- MIUtilDateTimeStd.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MIUtilDateTimeStd.h"
-#include "MICmnResources.h"
-
-//++
-// Details: CMIUtilDateTimeStd constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDateTimeStd::CMIUtilDateTimeStd() {}
-
-//++
-// Details: CMIUtilDateTimeStd destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDateTimeStd::~CMIUtilDateTimeStd() {}
-
-//++
-// Details: Retrieve system local current date. Format is MM/DD/YYYY.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString CMIUtilDateTimeStd::GetDate() {
- CMIUtilString strDate(MIRSRC(IDS_WORD_INVALIDBRKTS));
-
- std::time(&m_rawTime);
- const std::tm *pTi = std::localtime(&m_rawTime);
- if (std::strftime(&m_pScratch[0], sizeof(m_pScratch), "%d/%m/%y", pTi) > 0)
- strDate = m_pScratch;
-
- return strDate;
-}
-
-//++
-// Details: Retrieve system local current time. Format is HH:MM:SS 24 hour
-// clock.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString CMIUtilDateTimeStd::GetTime() {
- std::time(&m_rawTime);
- const std::tm *pTi = std::localtime(&m_rawTime);
- const CMIUtilString seconds(CMIUtilString::Format("%d", pTi->tm_sec));
- const CMIUtilString zero((seconds.length() == 1) ? "0" : "");
- const CMIUtilString strTime(CMIUtilString::Format(
- "%d:%d:%s%s", pTi->tm_hour, pTi->tm_min, zero.c_str(), seconds.c_str()));
-
- return strTime;
-}
-
-//++
-// Details: Retrieve system local current date and time in yyyy-MM-dd--HH-mm-ss
-// format for log file names.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString CMIUtilDateTimeStd::GetDateTimeLogFilename() {
- std::time(&m_rawTime);
- const std::tm *pTi = std::localtime(&m_rawTime);
- const CMIUtilString strTime(CMIUtilString::Format(
- "%d%02d%02d%02d%02d%02d", pTi->tm_year + 1900, pTi->tm_mon, pTi->tm_mday,
- pTi->tm_hour, pTi->tm_min, pTi->tm_sec));
-
- return strTime;
-}
diff --git a/tools/lldb-mi/MIUtilDateTimeStd.h b/tools/lldb-mi/MIUtilDateTimeStd.h
deleted file mode 100644
index 1a8e30c5654f..000000000000
--- a/tools/lldb-mi/MIUtilDateTimeStd.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- MIUtilDateTimeStd.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers
-#include <ctime>
-
-// In-house headers:
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. Used to retrieve system local date
-// time.
-//--
-class CMIUtilDateTimeStd {
- // Methods:
-public:
- /* ctor */ CMIUtilDateTimeStd();
-
- CMIUtilString GetDate();
- CMIUtilString GetTime();
- CMIUtilString GetDateTimeLogFilename();
-
- // Overrideable:
-public:
- // From CMICmnBase
- /* dtor */ virtual ~CMIUtilDateTimeStd();
-
- // Attributes:
-private:
- std::time_t m_rawTime;
- char m_pScratch[16];
-};
diff --git a/tools/lldb-mi/MIUtilDebug.cpp b/tools/lldb-mi/MIUtilDebug.cpp
deleted file mode 100644
index 4b418f390ca7..000000000000
--- a/tools/lldb-mi/MIUtilDebug.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- MIUtilDebug.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers:
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-// In-house headers:
-#include "MICmnLog.h"
-#include "MIDriver.h"
-#include "MIUtilDebug.h"
-
-//++
-// Details: CMIUtilDebug constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDebug::CMIUtilDebug() {}
-
-//++
-// Details: CMIUtilDebug destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDebug::~CMIUtilDebug() {}
-
-//++
-// Details: Temporarily stall the process/application to give the programmer the
-// opportunity to attach a debugger. How to use: Put a break in the
-// programmer
-// where you want to visit, run the application then attach your
-// debugger to the
-// application. Hit the debugger's pause button and the debugger should
-// should
-// show this loop. Change the i variable value to break out of the loop
-// and
-// visit your break point.
-// Type: Static method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilDebug::WaitForDbgAttachInfinteLoop() {
- MIuint i = 0;
- while (i == 0) {
- const std::chrono::milliseconds time(100);
- std::this_thread::sleep_for(time);
- }
-}
-
-
-// Instantiations:
-CMICmnLog &CMIUtilDebugFnTrace::ms_rLog = CMICmnLog::Instance();
-MIuint CMIUtilDebugFnTrace::ms_fnDepthCnt = 0;
-
-//++
-// Details: CMIUtilDebugFnTrace constructor.
-// Type: Method.
-// Args: vFnName - (R) The text to insert into the log.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDebugFnTrace::CMIUtilDebugFnTrace(const CMIUtilString &vFnName)
- : m_strFnName(vFnName) {
- const CMIUtilString txt(
- CMIUtilString::Format("%d>%s", ++ms_fnDepthCnt, m_strFnName.c_str()));
- ms_rLog.Write(txt, CMICmnLog::eLogVerbosity_FnTrace);
-}
-
-//++
-// Details: CMIUtilDebugFnTrace destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilDebugFnTrace::~CMIUtilDebugFnTrace() {
- const CMIUtilString txt(
- CMIUtilString::Format("%d<%s", ms_fnDepthCnt--, m_strFnName.c_str()));
- ms_rLog.Write(txt, CMICmnLog::eLogVerbosity_FnTrace);
-}
diff --git a/tools/lldb-mi/MIUtilDebug.h b/tools/lldb-mi/MIUtilDebug.h
deleted file mode 100644
index 537907ae304f..000000000000
--- a/tools/lldb-mi/MIUtilDebug.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- MIUtilDebug.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-#define MI_USE_DEBUG_TRACE_FN // Undefine to compile out fn trace code
-
-// In-house headers:
-#include "MIUtilString.h"
-
-// Declarations:
-class CMICmnLog;
-
-//++
-//============================================================================
-// Details: MI debugging aid utility class.
-//--
-class CMIUtilDebug {
- // Statics:
-public:
- static void WaitForDbgAttachInfinteLoop();
-
- // Methods:
-public:
- /* ctor */ CMIUtilDebug();
-
- // Overrideable:
-public:
- // From CMICmnBase
- /* dtor */ virtual ~CMIUtilDebug();
-};
-
-//++
-//============================================================================
-// Details: MI debug utility class. Used to indicate the current function
-// depth in the call stack. It uses the CMIlCmnLog logger to output
-// the current fn trace information.
-// Use macro MI_TRACEFN( "Some fn name" ) and implement the scope of
-// the functions you wish to build up a trace off.
-// Use preprocessor definition MI_USE_DEBUG_TRACE_FN to turn off or on
-// tracing code.
-//--
-class CMIUtilDebugFnTrace {
- // Methods:
-public:
- /* ctor */ CMIUtilDebugFnTrace(const CMIUtilString &vFnName);
-
- // Overrideable:
-public:
- // From CMICmnBase
- /* dtor */ virtual ~CMIUtilDebugFnTrace();
-
- // Attributes:
-private:
- const CMIUtilString m_strFnName;
-
- static CMICmnLog &ms_rLog;
- static MIuint ms_fnDepthCnt; // Increment count as fn depth increases,
- // decrement count as fn stack pops off
-};
-
-//++
-//============================================================================
-// Details: Take the given text and send it to the server's Logger to output to
-// the
-// trace file.
-// Type: Compile preprocess.
-// Args: x - (R) Message (may be seen by user).
-//--
-#ifdef MI_USE_DEBUG_TRACE_FN
-#define MI_TRACEFN(x) CMIUtilDebugFnTrace __MITrace(x)
-#else
-#define MI_TRACEFN(x)
-#endif // MI_USE_DEBUG_TRACE_FN
diff --git a/tools/lldb-mi/MIUtilFileStd.cpp b/tools/lldb-mi/MIUtilFileStd.cpp
deleted file mode 100644
index 2d8a05985e59..000000000000
--- a/tools/lldb-mi/MIUtilFileStd.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-//===-- MIUtilFileStd.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers
-#include <assert.h>
-#include <cerrno>
-#include <stdio.h>
-#include <string.h>
-
-// In-house headers:
-#include "MICmnResources.h"
-#include "MIUtilFileStd.h"
-#include "lldb/Host/FileSystem.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Errno.h"
-
-//++
-// Details: CMIUtilFileStd constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilFileStd::CMIUtilFileStd()
- : m_fileNamePath(CMIUtilString()), m_pFileHandle(nullptr)
-#if defined(_MSC_VER)
- ,
- m_constCharNewLine("\r\n")
-#else
- ,
- m_constCharNewLine("\n")
-#endif // #if defined( _MSC_VER )
- ,
- m_bFileError(false) {
-}
-
-//++
-// Details: CMIUtilFileStd destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilFileStd::~CMIUtilFileStd() { Close(); }
-
-//++
-// Details: Open file for writing. On the first call to this function after
-// *this object
-// is created the file is either created or replace, from then on open
-// only opens
-// an existing file.
-// Type: Method.
-// Args: vFileNamePath - (R) File name path.
-// vwrbNewCreated - (W) True - file recreated, false - file appended
-// too.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath,
- bool &vwrbNewCreated) {
- // Reset
- m_bFileError = false;
- vwrbNewCreated = false;
-
- if (vFileNamePath.empty()) {
- m_bFileError = true;
- SetErrorDescription(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
- return MIstatus::failure;
- }
-
- // File is already open so exit
- if (m_pFileHandle != nullptr)
- return MIstatus::success;
-
-#if !defined(_MSC_VER)
- // Open with 'write' and 'binary' mode
- m_pFileHandle = llvm::sys::RetryAfterSignal(nullptr, ::fopen,
- vFileNamePath.c_str(), "wb");
-#else
- // Open a file with exclusive write and shared read permissions
- std::wstring path;
- if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
- m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
- else {
- errno = EINVAL;
- m_pFileHandle = nullptr;
- }
-#endif // !defined( _MSC_VER )
-
- if (m_pFileHandle == nullptr) {
- m_bFileError = true;
- SetErrorDescriptionn(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE),
- strerror(errno), vFileNamePath.c_str());
- return MIstatus::failure;
- }
-
- vwrbNewCreated = true;
- m_fileNamePath = vFileNamePath;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Write data to existing opened file.
-// Type: Method.
-// Args: vData - (R) Text data.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilFileStd::Write(const CMIUtilString &vData) {
- if (vData.size() == 0)
- return MIstatus::success;
-
- if (m_bFileError)
- return MIstatus::failure;
-
- if (m_pFileHandle == nullptr) {
- m_bFileError = true;
- SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
- m_fileNamePath.c_str());
- return MIstatus::failure;
- }
-
- // Get the string size
- MIuint size = vData.size();
- if (::fwrite(vData.c_str(), 1, size, m_pFileHandle) == size) {
- // Flush the data to the file
- ::fflush(m_pFileHandle);
- return MIstatus::success;
- }
-
- // Not all of the data has been transferred
- m_bFileError = true;
- SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
- m_fileNamePath.c_str());
- return MIstatus::failure;
-}
-
-//++
-// Details: Write data to existing opened file.
-// Type: Method.
-// Args: vData - (R) Text data.
-// vCharCnt - (R) Text data length.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilFileStd::Write(const char *vpData, const MIuint vCharCnt) {
- if (vCharCnt == 0)
- return MIstatus::success;
-
- if (m_bFileError)
- return MIstatus::failure;
-
- if (m_pFileHandle == nullptr) {
- m_bFileError = true;
- SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
- m_fileNamePath.c_str());
- return MIstatus::failure;
- }
-
- if (::fwrite(vpData, 1, vCharCnt, m_pFileHandle) == vCharCnt) {
- // Flush the data to the file
- ::fflush(m_pFileHandle);
- return MIstatus::success;
- }
-
- // Not all of the data has been transferred
- m_bFileError = true;
- SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
- m_fileNamePath.c_str());
- return MIstatus::failure;
-}
-
-//++
-// Details: Close existing opened file. Note Close() must must an open!
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilFileStd::Close() {
- if (m_pFileHandle == nullptr)
- return;
-
- ::fclose(m_pFileHandle);
- m_pFileHandle = nullptr;
- // m_bFileError = false; Do not reset as want to remain until next attempt at
- // open or create
-}
-
-//++
-// Details: Retrieve state of whether the file is ok.
-// Type: Method.
-// Args: None.
-// Return: True - file ok.
-// False - file has a problem.
-// Throws: None.
-//--
-bool CMIUtilFileStd::IsOk() const { return !m_bFileError; }
-
-//++
-// Details: Status on a file existing already.
-// Type: Method.
-// Args: vFileNamePath.
-// Return: True - Exists.
-// False - Not found.
-// Throws: None.
-//--
-bool CMIUtilFileStd::IsFileExist(const CMIUtilString &vFileNamePath) const {
- if (vFileNamePath.empty())
- return false;
-
- FILE *pTmp = nullptr;
- pTmp = llvm::sys::RetryAfterSignal(nullptr, ::fopen,
- vFileNamePath.c_str(), "wb");
- if (pTmp != nullptr) {
- ::fclose(pTmp);
- return true;
- }
-
- return false;
-}
-
-//++
-// Details: Retrieve the file current carriage line return characters used.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString & - Text.
-// Throws: None.
-//--
-const CMIUtilString &CMIUtilFileStd::GetLineReturn() const {
- return m_constCharNewLine;
-}
-
-//++
-// Details: Given a file name directory path, strip off the filename and return
-// the path.
-// It look for either backslash or forward slash.
-// Type: Method.
-// Args: vDirectoryPath - (R) Text directory path.
-// Return: CMIUtilString - Directory path.
-// Throws: None.
-//--
-CMIUtilString
-CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) {
- const size_t nPos = vDirectoryPath.rfind('\\');
- size_t nPos2 = vDirectoryPath.rfind('/');
- if ((nPos == std::string::npos) && (nPos2 == std::string::npos))
- return vDirectoryPath;
-
- if (nPos > nPos2)
- nPos2 = nPos;
-
- const CMIUtilString strPath(vDirectoryPath.substr(0, nPos2).c_str());
- return strPath;
-}
-
-//++
-// Details: Return either backslash or forward slash appropriate to the OS this
-// application
-// is running on.
-// Type: Static method.
-// Args: None.
-// Return: char - '/' or '\' character.
-// Throws: None.
-//--
-char CMIUtilFileStd::GetSlash() {
-#if !defined(_MSC_VER)
- return '/';
-#else
- return '\\';
-#endif // !defined( _MSC_VER )
-}
diff --git a/tools/lldb-mi/MIUtilFileStd.h b/tools/lldb-mi/MIUtilFileStd.h
deleted file mode 100644
index e2e590b6aaf4..000000000000
--- a/tools/lldb-mi/MIUtilFileStd.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- MIUtilFileStd.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. File handling.
-//--
-class CMIUtilFileStd : public CMICmnBase {
- // Static:
-public:
- static char GetSlash();
-
- // Methods:
-public:
- /* ctor */ CMIUtilFileStd();
- //
- bool CreateWrite(const CMIUtilString &vFileNamePath, bool &vwrbNewCreated);
- bool Write(const CMIUtilString &vData);
- bool Write(const char *vpData, const MIuint vCharCnt);
- void Close();
- bool IsOk() const;
- bool IsFileExist(const CMIUtilString &vFileNamePath) const;
- const CMIUtilString &GetLineReturn() const;
- static CMIUtilString StripOffFileName(const CMIUtilString &vDirectoryPath);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMIUtilFileStd() override;
-
- // Attributes:
-private:
- CMIUtilString m_fileNamePath;
- FILE *m_pFileHandle;
- CMIUtilString m_constCharNewLine;
- bool m_bFileError; // True = have a file error ATM, false = all ok
-};
diff --git a/tools/lldb-mi/MIUtilMapIdToVariant.cpp b/tools/lldb-mi/MIUtilMapIdToVariant.cpp
deleted file mode 100644
index 9361cedab3e7..000000000000
--- a/tools/lldb-mi/MIUtilMapIdToVariant.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- MIUtilMapIdToVariant.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MIUtilMapIdToVariant.h"
-
-//++
-// Details: CMIUtilMapIdToVariant constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilMapIdToVariant::CMIUtilMapIdToVariant() {}
-
-//++
-// Details: CMIUtilMapIdToVariant destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilMapIdToVariant::~CMIUtilMapIdToVariant() {}
-
-//++
-// Details: Remove at the data from *this container.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilMapIdToVariant::Clear() { m_mapKeyToVariantValue.clear(); }
-
-//++
-// Details: Check an ID is present already in *this container.
-// Type: Method.
-// Args: vId - (R) Unique ID i.e. GUID.
-// Return: True - registered.
-// False - not found.
-// Throws: None.
-//--
-bool CMIUtilMapIdToVariant::HaveAlready(const CMIUtilString &vId) const {
- const MapKeyToVariantValue_t::const_iterator it =
- m_mapKeyToVariantValue.find(vId);
- return it != m_mapKeyToVariantValue.end();
-}
-
-//++
-// Details: Determine if *this container is currently holding any data.
-// Type: Method.
-// Args: None.
-// Return: bool - True - Yes empty, false - one or more data object present.
-// Throws: None.
-//--
-bool CMIUtilMapIdToVariant::IsEmpty() const {
- return m_mapKeyToVariantValue.empty();
-}
-
-//++
-// Details: Check the ID is valid to be registered.
-// Type: Method.
-// Args: vId - (R) Unique ID i.e. GUID.
-// Return: True - valid.
-// False - not valid.
-// Throws: None.
-//--
-bool CMIUtilMapIdToVariant::IsValid(const CMIUtilString &vId) const {
- bool bValid = true;
-
- if (vId.empty())
- bValid = false;
-
- return bValid;
-}
-
-//++
-// Details: Remove from *this contain a data object specified by ID. The data
-// object
-// when removed also calls its destructor should it have one.
-// Type: Method.
-// Args: vId - (R) Unique ID i.e. GUID.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilMapIdToVariant::Remove(const CMIUtilString &vId) {
- const MapKeyToVariantValue_t::const_iterator it =
- m_mapKeyToVariantValue.find(vId);
- if (it != m_mapKeyToVariantValue.end()) {
- m_mapKeyToVariantValue.erase(it);
- }
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MIUtilMapIdToVariant.h b/tools/lldb-mi/MIUtilMapIdToVariant.h
deleted file mode 100644
index ba3e176e0c41..000000000000
--- a/tools/lldb-mi/MIUtilMapIdToVariant.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- MIUtilMapIdToVariant.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <map>
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnResources.h"
-#include "MIUtilString.h"
-#include "MIUtilVariant.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. Map type container that hold general
-// object types (by being a variant wrapper)
-// objects by ID.
-//--
-class CMIUtilMapIdToVariant : public CMICmnBase {
- // Methods:
-public:
- /* ctor */ CMIUtilMapIdToVariant();
-
- template <typename T> bool Add(const CMIUtilString &vId, const T &vData);
- void Clear();
- template <typename T>
- bool Get(const CMIUtilString &vId, T &vrwData, bool &vrwbFound) const;
- bool HaveAlready(const CMIUtilString &vId) const;
- bool IsEmpty() const;
- bool Remove(const CMIUtilString &vId);
-
- // Overridden:
-public:
- // From CMICmnBase
- /* dtor */ ~CMIUtilMapIdToVariant() override;
-
- // Typedefs:
-private:
- typedef std::map<CMIUtilString, CMIUtilVariant> MapKeyToVariantValue_t;
- typedef std::pair<CMIUtilString, CMIUtilVariant> MapPairKeyToVariantValue_t;
-
- // Methods:
-private:
- bool IsValid(const CMIUtilString &vId) const;
-
- // Attributes:
- MapKeyToVariantValue_t m_mapKeyToVariantValue;
-};
-
-//++
-// Details: Add to *this container a data object of general type identified by
-// an ID.
-// If the data with that ID already exists in the container it is
-// replace with
-// the new data specified.
-// Type: Method.
-// Args: T - The data object's variable type.
-// vId - (R) Unique ID i.e. GUID.
-// vData - (R) The general data object to be stored of some type.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-template <typename T>
-bool CMIUtilMapIdToVariant::Add(const CMIUtilString &vId, const T &vData) {
- if (!IsValid(vId)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_VARIANT_ERR_MAP_KEY_INVALID), vId.c_str()));
- return MIstatus::failure;
- }
-
- const bool bOk = HaveAlready(vId) ? Remove(vId) : MIstatus::success;
- if (bOk) {
- CMIUtilVariant data;
- data.Set<T>(vData);
- MapPairKeyToVariantValue_t pr(vId, data);
- m_mapKeyToVariantValue.insert(pr);
- }
-
- return bOk;
-}
-
-//++
-// Details: Retrieve a data object from *this container identified by the
-// specified ID.
-// Type: Method.
-// Args: T - The data object's variable type.
-// vId - (R) Unique ID i.e. GUID.
-// vrwData - (W) Copy of the data object held.
-// vrwbFound - (W) True = data found, false = data not found.
-// Return: MIstatus::success - Function succeeded.
-// MIstatus::failure - Function failed.
-// Throws: None.
-//--
-template <typename T>
-bool CMIUtilMapIdToVariant::Get(const CMIUtilString &vId, T &vrwData,
- bool &vrwbFound) const {
- vrwbFound = false;
-
- if (!IsValid(vId)) {
- SetErrorDescription(CMIUtilString::Format(
- MIRSRC(IDS_VARIANT_ERR_MAP_KEY_INVALID), vId.c_str()));
- return MIstatus::failure;
- }
-
- const MapKeyToVariantValue_t::const_iterator it =
- m_mapKeyToVariantValue.find(vId);
- if (it != m_mapKeyToVariantValue.end()) {
- const CMIUtilVariant &rData = (*it).second;
- const T *pDataObj = rData.Get<T>();
- if (pDataObj != nullptr) {
- vrwbFound = true;
- vrwData = *pDataObj;
- return MIstatus::success;
- } else {
- SetErrorDescription(MIRSRC(IDS_VARIANT_ERR_USED_BASECLASS));
- return MIstatus::failure;
- }
- }
-
- return MIstatus::success;
-}
diff --git a/tools/lldb-mi/MIUtilSingletonBase.h b/tools/lldb-mi/MIUtilSingletonBase.h
deleted file mode 100644
index e76fff72b27c..000000000000
--- a/tools/lldb-mi/MIUtilSingletonBase.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- MIUtilSingletonBase.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-namespace MI {
-
-// MI::ISingleton base class usage:
-//
-// class CMIDerivedClass
-// : public MI::ISingleton< CMIDerivedClass >
-// {
-// friend MI::ISingleton< CMIDerivedClass >;
-//
-// // Overridden:
-// public:
-// // From MI::ISingleton
-// bool Initialize() override;
-// bool Shutdown() override;
-// };
-
-//++
-//============================================================================
-// Details: Base class for the singleton pattern.
-// Gotchas: Derived class must specify MI::ISingleton<> as a friend class.
-//--
-template <typename T> class ISingleton {
- // Statics:
-public:
- // Return an instance of the derived class
- static T &Instance() {
- // This will fail if the derived class has not
- // declared itself to be a friend of MI::ISingleton
- static T instance;
-
- return instance;
- }
-
- // Overrideable:
-public:
- virtual bool Initialize() = 0;
- virtual bool Shutdown() = 0;
- //
- /* dtor */ virtual ~ISingleton() {}
-};
-
-} // namespace MI
diff --git a/tools/lldb-mi/MIUtilSingletonHelper.h b/tools/lldb-mi/MIUtilSingletonHelper.h
deleted file mode 100644
index b9ac61a58e7f..000000000000
--- a/tools/lldb-mi/MIUtilSingletonHelper.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- MIUtilSingletonHelper.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In house headers:
-#include "MICmnResources.h"
-#include "MIUtilString.h"
-
-namespace MI {
-
-//++
-//============================================================================
-// Details: Short cut helper function to simplify repeated initialisation of
-// MI components (singletons) required by a client module.
-// Type: Template method.
-// Args: vErrorResrcId - (R) The string resource ID error message
-// identifier to place in errMsg.
-// vwrbOk - (RW) On input True = Try to initialize MI driver
-// module.
-// On output True = MI driver module initialise
-// successfully.
-// vwrErrMsg - (W) MI driver module initialise error description
-// on failure.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-//--
-template <typename T>
-bool ModuleInit(const MIint vErrorResrcId, bool &vwrbOk,
- CMIUtilString &vwrErrMsg) {
- if (vwrbOk && !T::Instance().Initialize()) {
- vwrbOk = MIstatus::failure;
- vwrErrMsg = CMIUtilString::Format(
- MIRSRC(vErrorResrcId), T::Instance().GetErrorDescription().c_str());
- }
-
- return vwrbOk;
-}
-
-//++
-//============================================================================
-// Details: Short cut helper function to simplify repeated shutdown of
-// MI components (singletons) required by a client module.
-// Type: Template method.
-// Args: vErrorResrcId - (R) The string resource ID error message
-// identifier
-// to place in errMsg.
-// vwrbOk - (W) If not already false make false on module
-// shutdown failure.
-// vwrErrMsg - (RW) Append to existing error description string
-// MI
-// driver module initialise error description on
-// failure.
-// Return: True - Module shutdown succeeded.
-// False - Module shutdown failed.
-//--
-template <typename T>
-bool ModuleShutdown(const MIint vErrorResrcId, bool &vwrbOk,
- CMIUtilString &vwrErrMsg) {
- bool bOk = MIstatus::success;
-
- if (!T::Instance().Shutdown()) {
- const bool bMoreThanOneError(!vwrErrMsg.empty());
- bOk = MIstatus::failure;
- if (bMoreThanOneError)
- vwrErrMsg += ", ";
- vwrErrMsg += CMIUtilString::Format(
- MIRSRC(vErrorResrcId), T::Instance().GetErrorDescription().c_str());
- }
-
- vwrbOk = bOk ? vwrbOk : MIstatus::failure;
-
- return bOk;
-}
-
-} // namespace MI
diff --git a/tools/lldb-mi/MIUtilString.cpp b/tools/lldb-mi/MIUtilString.cpp
deleted file mode 100644
index 986de963450e..000000000000
--- a/tools/lldb-mi/MIUtilString.cpp
+++ /dev/null
@@ -1,915 +0,0 @@
-//===-- MIUtilString.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third party headers
-#include "llvm/Support/Compiler.h"
-#include <cstdlib>
-#include <inttypes.h>
-#include <limits.h>
-#include <memory>
-#include <sstream>
-#include <stdarg.h>
-#include <string.h>
-
-// In-house headers:
-#include "MIUtilString.h"
-
-//++
-// Details: CMIUtilString constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilString::CMIUtilString() : std::string() {}
-
-//++
-// Details: CMIUtilString constructor.
-// Type: Method.
-// Args: vpData - Pointer to UTF8 text data.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilString::CMIUtilString(const char *vpData)
- : std::string(WithNullAsEmpty(vpData)) {}
-
-//++
-// Details: CMIUtilString constructor.
-// Type: Method.
-// Args: vpStr - Text data.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilString::CMIUtilString(const std::string &vrStr) : std::string(vrStr) {}
-
-//++
-// Details: CMIUtilString assignment operator.
-// Type: Method.
-// Args: vpRhs - Pointer to UTF8 text data.
-// Return: CMIUtilString & - *this string.
-// Throws: None.
-//--
-CMIUtilString &CMIUtilString::operator=(const char *vpRhs) {
- assign(WithNullAsEmpty(vpRhs));
- return *this;
-}
-
-//++
-// Details: CMIUtilString assignment operator.
-// Type: Method.
-// Args: vrRhs - The other string to copy from.
-// Return: CMIUtilString & - *this string.
-// Throws: None.
-//--
-CMIUtilString &CMIUtilString::operator=(const std::string &vrRhs) {
- assign(vrRhs);
- return *this;
-}
-
-//++
-// Details: CMIUtilString destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilString::~CMIUtilString() {}
-
-//++
-// Details: Perform a snprintf format style on a string data. A new string
-// object is
-// created and returned.
-// Type: Static method.
-// Args: vrFormat - (R) Format string data instruction.
-// vArgs - (R) Var list args of any type.
-// Return: CMIUtilString - Number of splits found in the string data.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::FormatPriv(const CMIUtilString &vrFormat,
- va_list vArgs) {
- CMIUtilString strResult;
- MIint nFinal = 0;
- MIint n = vrFormat.size();
-
- // IOR: mysterious crash in this function on some windows builds not able to
- // duplicate but found article which may be related. Crash occurs in
- // vsnprintf() or va_copy().
- // Duplicate vArgs va_list argument pointer to ensure that it can be safely
- // used in a new frame.
- // http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
- va_list argsDup;
- va_copy(argsDup, vArgs);
-
- // Create a copy va_list to reset when we spin
- va_list argsCpy;
- va_copy(argsCpy, argsDup);
-
- if (n == 0)
- return strResult;
-
- n = n << 4; // Reserve 16 times as much the length of the vrFormat
-
- std::unique_ptr<char[]> pFormatted;
- while (1) {
- pFormatted.reset(new char[n + 1]); // +1 for safety margin
- ::strncpy(&pFormatted[0], vrFormat.c_str(), n);
-
- // We need to restore the variable argument list pointer to the start again
- // before running vsnprintf() more then once
- va_copy(argsDup, argsCpy);
-
- nFinal = ::vsnprintf(&pFormatted[0], n, vrFormat.c_str(), argsDup);
- if ((nFinal < 0) || (nFinal >= n))
- n += abs(nFinal - n + 1);
- else
- break;
- }
-
- va_end(argsCpy);
- va_end(argsDup);
-
- strResult = pFormatted.get();
-
- return strResult;
-}
-
-//++
-// Details: Perform a snprintf format style on a string data. A new string
-// object is
-// created and returned.
-// Type: Static method.
-// Args: vFormat - (R) Format string data instruction.
-// ... - (R) Var list args of any type.
-// Return: CMIUtilString - Number of splits found in the string data.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::Format(const char *vFormating, ...) {
- va_list args;
- va_start(args, vFormating);
- CMIUtilString strResult =
- CMIUtilString::FormatPriv(WithNullAsEmpty(vFormating), args);
- va_end(args);
-
- return strResult;
-}
-
-//++
-// Details: Perform a snprintf format style on a string data. A new string
-// object is
-// created and returned.
-// Type: Static method.
-// Args: vrFormat - (R) Format string data instruction.
-// vArgs - (R) Var list args of any type.
-// Return: CMIUtilString - Number of splits found in the string data.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::FormatValist(const CMIUtilString &vrFormating,
- va_list vArgs) {
- return CMIUtilString::FormatPriv(vrFormating, vArgs);
-}
-
-//++
-// Details: Splits string into array of strings using delimiter. If multiple
-// delimiter
-// are found in sequence then they are not added to the list of splits.
-// Type: Method.
-// Args: vData - (R) String data to be split up.
-// vDelimiter - (R) Delimiter char or text.
-// vwVecSplits - (W) Container of splits found in string data.
-// Return: size_t - Number of splits found in the string data.
-// Throws: None.
-//--
-size_t CMIUtilString::Split(const CMIUtilString &vDelimiter,
- VecString_t &vwVecSplits) const {
- vwVecSplits.clear();
-
- if (this->empty() || vDelimiter.empty())
- return 0;
-
- const size_t nLen(length());
- size_t nOffset(0);
- do {
- // Find first occurrence which doesn't match to the delimiter
- const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
- if (nSectionPos == std::string::npos)
- break;
-
- // Find next occurrence of the delimiter after section
- size_t nNextDelimiterPos(FindFirst(vDelimiter, nSectionPos));
- if (nNextDelimiterPos == std::string::npos)
- nNextDelimiterPos = nLen;
-
- // Extract string between delimiters
- const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
- const std::string strSection(substr(nSectionPos, nSectionLen));
- vwVecSplits.push_back(strSection);
-
- // Next
- nOffset = nNextDelimiterPos + 1;
- } while (nOffset < nLen);
-
- return vwVecSplits.size();
-}
-
-//++
-// Details: Splits string into array of strings using delimiter. However the
-// string is
-// also considered for text surrounded by quotes. Text with quotes
-// including the
-// delimiter is treated as a whole. If multiple delimiter are found in
-// sequence
-// then they are not added to the list of splits. Quotes that are
-// embedded in
-// the string as string formatted quotes are ignored (proceeded by a
-// '\\') i.e.
-// "\"MI GDB local C++.cpp\":88".
-// Type: Method.
-// Args: vData - (R) String data to be split up.
-// vDelimiter - (R) Delimiter char or text.
-// vwVecSplits - (W) Container of splits found in string data.
-// Return: size_t - Number of splits found in the string data.
-// Throws: None.
-//--
-size_t CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter,
- VecString_t &vwVecSplits) const {
- vwVecSplits.clear();
-
- if (this->empty() || vDelimiter.empty())
- return 0;
-
- const size_t nLen(length());
- size_t nOffset(0);
- do {
- // Find first occurrence which doesn't match to the delimiter
- const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
- if (nSectionPos == std::string::npos)
- break;
-
- // Find next occurrence of the delimiter after (quoted) section
- const bool bSkipQuotedText(true);
- bool bUnmatchedQuote(false);
- size_t nNextDelimiterPos(
- FindFirst(vDelimiter, bSkipQuotedText, bUnmatchedQuote, nSectionPos));
- if (bUnmatchedQuote) {
- vwVecSplits.clear();
- return 0;
- }
- if (nNextDelimiterPos == std::string::npos)
- nNextDelimiterPos = nLen;
-
- // Extract string between delimiters
- const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
- const std::string strSection(substr(nSectionPos, nSectionLen));
- vwVecSplits.push_back(strSection);
-
- // Next
- nOffset = nNextDelimiterPos + 1;
- } while (nOffset < nLen);
-
- return vwVecSplits.size();
-}
-
-//++
-// Details: Split string into lines using \n and return an array of strings.
-// Type: Method.
-// Args: vwVecSplits - (W) Container of splits found in string data.
-// Return: size_t - Number of splits found in the string data.
-// Throws: None.
-//--
-size_t CMIUtilString::SplitLines(VecString_t &vwVecSplits) const {
- return Split("\n", vwVecSplits);
-}
-
-//++
-// Details: Remove '\n' from the end of string if found. It does not alter
-// *this string.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - New version of the string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::StripCREndOfLine() const {
- const size_t nPos = rfind('\n');
- if (nPos == std::string::npos)
- return *this;
-
- const CMIUtilString strNew(substr(0, nPos));
-
- return strNew;
-}
-
-//++
-// Details: Remove all '\n' from the string and replace with a space. It does
-// not alter
-// *this string.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - New version of the string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::StripCRAll() const {
- return FindAndReplace("\n", " ");
-}
-
-//++
-// Details: Find and replace all matches of a sub string with another string. It
-// does not
-// alter *this string.
-// Type: Method.
-// Args: vFind - (R) The string to look for.
-// vReplaceWith - (R) The string to replace the vFind match.
-// Return: CMIUtilString - New version of the string.
-// Throws: None.
-//--
-CMIUtilString
-CMIUtilString::FindAndReplace(const CMIUtilString &vFind,
- const CMIUtilString &vReplaceWith) const {
- if (vFind.empty() || this->empty())
- return *this;
-
- size_t nPos = find(vFind);
- if (nPos == std::string::npos)
- return *this;
-
- CMIUtilString strNew(*this);
- while (nPos != std::string::npos) {
- strNew.replace(nPos, vFind.length(), vReplaceWith);
- nPos += vReplaceWith.length();
- nPos = strNew.find(vFind, nPos);
- }
-
- return strNew;
-}
-
-//++
-// Details: Check if *this string is a decimal number.
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes number, false not a number.
-// Throws: None.
-//--
-bool CMIUtilString::IsNumber() const {
- if (empty())
- return false;
-
- if ((at(0) == '-') && (length() == 1))
- return false;
-
- const size_t nPos = find_first_not_of("-.0123456789");
- return nPos == std::string::npos;
-}
-
-//++
-// Details: Check if *this string is a hexadecimal number.
-// Type: Method.
-// Args: None.
-// Return: bool - True = yes number, false not a number.
-// Throws: None.
-//--
-bool CMIUtilString::IsHexadecimalNumber() const {
- // Compare '0x..' prefix
- if ((strncmp(c_str(), "0x", 2) != 0) && (strncmp(c_str(), "0X", 2) != 0))
- return false;
-
- // Skip '0x..' prefix
- const size_t nPos = find_first_not_of("01234567890ABCDEFabcedf", 2);
- return nPos == std::string::npos;
-}
-
-//++
-// Details: Extract the number from the string. The number can be either a
-// hexadecimal or
-// natural number. It cannot contain other non-numeric characters.
-// Type: Method.
-// Args: vwrNumber - (W) Number extracted from the string.
-// Return: bool - True = yes number, false not a number.
-// Throws: None.
-//--
-bool CMIUtilString::ExtractNumber(MIint64 &vwrNumber) const {
- vwrNumber = 0;
-
- if (!IsNumber()) {
- return ExtractNumberFromHexadecimal(vwrNumber);
- }
-
- std::stringstream ss(const_cast<CMIUtilString &>(*this));
- ss >> vwrNumber;
-
- return true;
-}
-
-//++
-// Details: Extract the number from the hexadecimal string..
-// Type: Method.
-// Args: vwrNumber - (W) Number extracted from the string.
-// Return: bool - True = yes number, false not a number.
-// Throws: None.
-//--
-bool CMIUtilString::ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const {
- vwrNumber = 0;
-
- const size_t nPos = find_first_not_of("xX01234567890ABCDEFabcedf");
- if (nPos != std::string::npos)
- return false;
-
- errno = 0;
- const MIuint64 nNum = ::strtoull(this->c_str(), nullptr, 16);
- if (errno == ERANGE)
- return false;
-
- vwrNumber = static_cast<MIint64>(nNum);
-
- return true;
-}
-
-//++
-// Details: Determine if the text is all valid alpha numeric characters. Letters
-// can be
-// either upper or lower case.
-// Type: Static method.
-// Args: vpText - (R) The text data to examine.
-// Return: bool - True = yes all alpha, false = one or more chars is non alpha.
-// Throws: None.
-//--
-bool CMIUtilString::IsAllValidAlphaAndNumeric(const char *vpText) {
- const size_t len = ::strlen(WithNullAsEmpty(vpText));
- if (len == 0)
- return false;
-
- for (size_t i = 0; i < len; i++, vpText++) {
- const char c = *vpText;
- if (::isalnum((int)c) == 0)
- return false;
- }
-
- return true;
-}
-
-//++
-// Details: Check if two strings share equal contents.
-// Type: Method.
-// Args: vrLhs - (R) String A.
-// vrRhs - (R) String B.
-// Return: bool - True = yes equal, false - different.
-// Throws: None.
-//--
-bool CMIUtilString::Compare(const CMIUtilString &vrLhs,
- const CMIUtilString &vrRhs) {
- // Check the sizes match
- if (vrLhs.size() != vrRhs.size())
- return false;
-
- return (::strncmp(vrLhs.c_str(), vrRhs.c_str(), vrLhs.size()) == 0);
-}
-
-//++
-// Details: Remove from either end of *this string the following: " \t\n\v\f\r".
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Trimmed string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::Trim() const {
- CMIUtilString strNew(*this);
- const char *pWhiteSpace = " \t\n\v\f\r";
- const size_t nPos = find_last_not_of(pWhiteSpace);
- if (nPos != std::string::npos) {
- strNew = substr(0, nPos + 1);
- }
- const size_t nPos2 = strNew.find_first_not_of(pWhiteSpace);
- if (nPos2 != std::string::npos) {
- strNew = strNew.substr(nPos2);
- }
-
- return strNew;
-}
-
-//++
-// Details: Remove from either end of *this string the specified character.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - Trimmed string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::Trim(const char vChar) const {
- CMIUtilString strNew(*this);
- const size_t nLen = strNew.length();
- if (nLen > 1) {
- if ((strNew[0] == vChar) && (strNew[nLen - 1] == vChar))
- strNew = strNew.substr(1, nLen - 2);
- }
-
- return strNew;
-}
-
-//++
-// Details: Do a printf equivalent for printing a number in binary i.e. "b%llB".
-// Type: Static method.
-// Args: vnDecimal - (R) The number to represent in binary.
-// Return: CMIUtilString - Binary number in text.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::FormatBinary(const MIuint64 vnDecimal) {
- CMIUtilString strBinaryNumber;
-
- const MIuint nConstBits = 64;
- MIuint nRem[nConstBits + 1];
- MIint i = 0;
- MIuint nLen = 0;
- MIuint64 nNum = vnDecimal;
- while ((nNum > 0) && (nLen < nConstBits)) {
- nRem[i++] = nNum % 2;
- nNum = nNum >> 1;
- nLen++;
- }
- char pN[nConstBits + 1];
- MIuint j = 0;
- for (i = nLen; i > 0; --i, j++) {
- pN[j] = '0' + nRem[i - 1];
- }
- pN[j] = 0; // String NUL termination
-
- strBinaryNumber = CMIUtilString::Format("0b%s", &pN[0]);
-
- return strBinaryNumber;
-}
-
-//++
-// Details: Remove from a string doubled up characters so only one set left.
-// Characters
-// are only removed if the previous character is already a same
-// character.
-// Type: Method.
-// Args: vChar - (R) The character to search for and remove adjacent
-// duplicates.
-// Return: CMIUtilString - New version of the string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::RemoveRepeatedCharacters(const char vChar) {
- return RemoveRepeatedCharacters(0, vChar);
-}
-
-//++
-// Details: Recursively remove from a string doubled up characters so only one
-// set left.
-// Characters are only removed if the previous character is already a
-// same
-// character.
-// Type: Method.
-// Args: vChar - (R) The character to search for and remove adjacent
-// duplicates.
-// vnPos - Character position in the string.
-// Return: CMIUtilString - New version of the string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::RemoveRepeatedCharacters(size_t vnPos,
- const char vChar) {
- const char cQuote = '"';
-
- // Look for first quote of two
- const size_t nPos = find(cQuote, vnPos);
- if (nPos == std::string::npos)
- return *this;
-
- const size_t nPosNext = nPos + 1;
- if (nPosNext > length())
- return *this;
-
- if (at(nPosNext) == cQuote) {
- *this = substr(0, nPos) + substr(nPosNext, length());
- RemoveRepeatedCharacters(nPosNext, vChar);
- }
-
- return *this;
-}
-
-//++
-// Details: Is the text in *this string surrounded by quotes.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes string is quoted, false = no quoted.
-// Throws: None.
-//--
-bool CMIUtilString::IsQuoted() const {
- const char cQuote = '"';
-
- if (at(0) != cQuote)
- return false;
-
- const size_t nLen = length();
- return !((nLen > 0) && (at(nLen - 1) != cQuote));
-}
-
-//++
-// Details: Find first occurrence in *this string which matches the pattern.
-// Type: Method.
-// Args: vrPattern - (R) The pattern to search for.
-// vnPos - The starting position at which to start searching.
-// (Dflt = 0)
-// Return: size_t - The position of the first substring that match.
-// Throws: None.
-//--
-size_t CMIUtilString::FindFirst(const CMIUtilString &vrPattern,
- size_t vnPos /* = 0 */) const {
- return find(vrPattern, vnPos);
-}
-
-//++
-// Details: Find first occurrence in *this string which matches the pattern and
-// isn't surrounded by quotes.
-// Type: Method.
-// Args: vrPattern - (R) The pattern to search for.
-// vbSkipQuotedText - (R) True = don't look at quoted text,
-// false = otherwise.
-// vrwbNotFoundClosedQuote - (W) True = parsing error: unmatched
-// quote, false = otherwise.
-// vnPos - Position of the first character in the
-// string to be considered in the search. (Dflt = 0)
-// Return: size_t - The position of the first substring that matches and isn't
-// quoted.
-// Throws: None.
-//--
-size_t CMIUtilString::FindFirst(const CMIUtilString &vrPattern,
- const bool vbSkipQuotedText,
- bool &vrwbNotFoundClosedQuote,
- size_t vnPos /* = 0 */) const {
- vrwbNotFoundClosedQuote = false;
-
- if (!vbSkipQuotedText)
- return FindFirst(vrPattern, vnPos);
-
- const size_t nLen(length());
-
- size_t nPos = vnPos;
- do {
- const size_t nQuotePos(FindFirstQuote(nPos));
- const size_t nPatternPos(FindFirst(vrPattern, nPos));
- if (nQuotePos == std::string::npos)
- return nPatternPos;
-
- const size_t nQuoteClosedPos = FindFirstQuote(nQuotePos + 1);
- if (nQuoteClosedPos == std::string::npos) {
- vrwbNotFoundClosedQuote = true;
- return std::string::npos;
- }
-
- if ((nPatternPos == std::string::npos) || (nPatternPos < nQuotePos))
- return nPatternPos;
-
- nPos = nQuoteClosedPos + 1;
- } while (nPos < nLen);
-
- return std::string::npos;
-}
-
-//++
-// Details: Find first occurrence in *this string which doesn't match the
-// pattern.
-// Type: Method.
-// Args: vrPattern - (R) The pattern to search for.
-// vnPos - Position of the first character in the string to be
-// considered in the search. (Dflt = 0)
-// Return: size_t - The position of the first character that doesn't match.
-// Throws: None.
-//--
-size_t CMIUtilString::FindFirstNot(const CMIUtilString &vrPattern,
- size_t vnPos /* = 0 */) const {
- const size_t nLen(length());
- const size_t nPatternLen(vrPattern.length());
-
- size_t nPatternPos(vnPos);
- do {
- const bool bMatchPattern(compare(nPatternPos, nPatternLen, vrPattern) == 0);
- if (!bMatchPattern)
- return nPatternPos;
- nPatternPos += nPatternLen;
- } while (nPatternPos < nLen);
-
- return std::string::npos;
-}
-
-//++
-// Details: Find first occurrence of not escaped quotation mark in *this string.
-// Type: Method.
-// Args: vnPos - Position of the first character in the string to be
-// considered in the search.
-// Return: size_t - The position of the quotation mark.
-// Throws: None.
-//--
-size_t CMIUtilString::FindFirstQuote(size_t vnPos) const {
- const char cBckSlash('\\');
- const char cQuote('"');
- const size_t nLen(length());
-
- size_t nPos = vnPos;
- do {
- const size_t nBckSlashPos(find(cBckSlash, nPos));
- const size_t nQuotePos(find(cQuote, nPos));
- if ((nBckSlashPos == std::string::npos) || (nQuotePos == std::string::npos))
- return nQuotePos;
-
- if (nQuotePos < nBckSlashPos)
- return nQuotePos;
-
- // Skip 2 characters: First is '\', second is that which is escaped by '\'
- nPos = nBckSlashPos + 2;
- } while (nPos < nLen);
-
- return std::string::npos;
-}
-
-//++
-// Details: Get escaped string from *this string.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - The escaped version of the initial string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::Escape(bool vbEscapeQuotes /* = false */) const {
- const size_t nLen(length());
- CMIUtilString strNew;
- strNew.reserve(nLen);
- for (size_t nIndex(0); nIndex < nLen; ++nIndex) {
- const char cUnescapedChar((*this)[nIndex]);
- if (cUnescapedChar == '"' && vbEscapeQuotes)
- strNew.append("\\\"");
- else
- strNew.append(ConvertToPrintableASCII((char)cUnescapedChar));
- }
- return strNew;
-}
-
-//++
-// Details: Get string with backslashes in front of double quote '"' and
-// backslash '\\'
-// characters.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - The wrapped version of the initial string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::AddSlashes() const {
- const char cBckSlash('\\');
- const size_t nLen(length());
- CMIUtilString strNew;
- strNew.reserve(nLen);
-
- size_t nOffset(0);
- while (nOffset < nLen) {
- const size_t nUnescapedCharPos(find_first_of("\"\\", nOffset));
- const bool bUnescapedCharNotFound(nUnescapedCharPos == std::string::npos);
- if (bUnescapedCharNotFound) {
- const size_t nAppendAll(std::string::npos);
- strNew.append(*this, nOffset, nAppendAll);
- break;
- }
- const size_t nAppendLen(nUnescapedCharPos - nOffset);
- strNew.append(*this, nOffset, nAppendLen);
- strNew.push_back(cBckSlash);
- const char cUnescapedChar((*this)[nUnescapedCharPos]);
- strNew.push_back(cUnescapedChar);
- nOffset = nUnescapedCharPos + 1;
- }
-
- return strNew;
-}
-
-//++
-// Details: Remove backslashes added by CMIUtilString::AddSlashes.
-// Type: Method.
-// Args: None.
-// Return: CMIUtilString - The initial version of wrapped string.
-// Throws: None.
-//--
-CMIUtilString CMIUtilString::StripSlashes() const {
- const char cBckSlash('\\');
- const size_t nLen(length());
- CMIUtilString strNew;
- strNew.reserve(nLen);
-
- size_t nOffset(0);
- while (nOffset < nLen) {
- const size_t nBckSlashPos(find(cBckSlash, nOffset));
- const bool bBckSlashNotFound(nBckSlashPos == std::string::npos);
- if (bBckSlashNotFound) {
- const size_t nAppendAll(std::string::npos);
- strNew.append(*this, nOffset, nAppendAll);
- break;
- }
- const size_t nAppendLen(nBckSlashPos - nOffset);
- strNew.append(*this, nOffset, nAppendLen);
- const bool bBckSlashIsLast(nBckSlashPos == nLen);
- if (bBckSlashIsLast) {
- strNew.push_back(cBckSlash);
- break;
- }
- const char cEscapedChar((*this)[nBckSlashPos + 1]);
- const size_t nEscapedCharPos(std::string("\"\\").find(cEscapedChar));
- const bool bEscapedCharNotFound(nEscapedCharPos == std::string::npos);
- if (bEscapedCharNotFound)
- strNew.push_back(cBckSlash);
- strNew.push_back(cEscapedChar);
- nOffset = nBckSlashPos + 2;
- }
-
- return strNew;
-}
-
-CMIUtilString CMIUtilString::ConvertToPrintableASCII(const char vChar,
- bool bEscapeQuotes) {
- switch (vChar) {
- case '\a':
- return "\\a";
- case '\b':
- return "\\b";
- case '\t':
- return "\\t";
- case '\n':
- return "\\n";
- case '\v':
- return "\\v";
- case '\f':
- return "\\f";
- case '\r':
- return "\\r";
- case '\033':
- return "\\e";
- case '\\':
- return "\\\\";
- case '"':
- if (bEscapeQuotes)
- return "\\\"";
- LLVM_FALLTHROUGH;
- default:
- if (::isprint(vChar))
- return Format("%c", vChar);
- else
- return Format("\\x%02" PRIx8, vChar);
- }
-}
-
-CMIUtilString
-CMIUtilString::ConvertCharValueToPrintableASCII(char vChar,
- bool bEscapeQuotes) {
- switch (vChar) {
- case '\a':
- return "\\a";
- case '\b':
- return "\\b";
- case '\t':
- return "\\t";
- case '\n':
- return "\\n";
- case '\v':
- return "\\v";
- case '\f':
- return "\\f";
- case '\r':
- return "\\r";
- case '\033':
- return "\\e";
- case '\\':
- return "\\\\";
- case '"':
- if (bEscapeQuotes)
- return "\\\"";
- LLVM_FALLTHROUGH;
- default:
- if (::isprint(vChar))
- return Format("%c", vChar);
- else
- return CMIUtilString();
- }
-}
-
-CMIUtilString CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16,
- bool bEscapeQuotes) {
- if (vChar16 == (char16_t)(char)vChar16) {
- // Convert char16_t to char (if possible)
- CMIUtilString str =
- ConvertCharValueToPrintableASCII((char)vChar16, bEscapeQuotes);
- if (str.length() > 0)
- return str;
- }
- return Format("\\u%02" PRIx8 "%02" PRIx8, (vChar16 >> 8) & 0xff,
- vChar16 & 0xff);
-}
-
-CMIUtilString CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32,
- bool bEscapeQuotes) {
- if (vChar32 == (char32_t)(char)vChar32) {
- // Convert char32_t to char (if possible)
- CMIUtilString str =
- ConvertCharValueToPrintableASCII((char)vChar32, bEscapeQuotes);
- if (str.length() > 0)
- return str;
- }
- return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
- (vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
- (vChar32 >> 8) & 0xff, vChar32 & 0xff);
-}
diff --git a/tools/lldb-mi/MIUtilString.h b/tools/lldb-mi/MIUtilString.h
deleted file mode 100644
index e9d3af7a6225..000000000000
--- a/tools/lldb-mi/MIUtilString.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- MIUtilString.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <cinttypes>
-#include <cstdarg>
-#include <string>
-#include <vector>
-
-// In-house headers:
-#include "MIDataTypes.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. Used to help handle text.
-// Derived from std::string
-//--
-class CMIUtilString : public std::string {
- // Typedefs:
-public:
- typedef std::vector<CMIUtilString> VecString_t;
-
- // Static method:
-public:
- static CMIUtilString Format(const char *vFormating, ...);
- static CMIUtilString FormatBinary(const MIuint64 vnDecimal);
- static CMIUtilString FormatValist(const CMIUtilString &vrFormating,
- va_list vArgs);
- static bool IsAllValidAlphaAndNumeric(const char *vpText);
- static const char *WithNullAsEmpty(const char *vpText) {
- return vpText ? vpText : "";
- }
- static bool Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs);
- static CMIUtilString ConvertToPrintableASCII(const char vChar,
- bool bEscapeQuotes = false);
- static CMIUtilString ConvertToPrintableASCII(const char16_t vChar16,
- bool bEscapeQuotes = false);
- static CMIUtilString ConvertToPrintableASCII(const char32_t vChar32,
- bool bEscapeQuotes = false);
-
- // Methods:
-public:
- /* ctor */ CMIUtilString();
- /* ctor */ CMIUtilString(const char *vpData);
- /* ctor */ CMIUtilString(const std::string &vrStr);
- //
- bool ExtractNumber(MIint64 &vwrNumber) const;
- CMIUtilString FindAndReplace(const CMIUtilString &vFind,
- const CMIUtilString &vReplaceWith) const;
- bool IsNumber() const;
- bool IsHexadecimalNumber() const;
- bool IsQuoted() const;
- CMIUtilString RemoveRepeatedCharacters(const char vChar);
- size_t Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
- size_t SplitConsiderQuotes(const CMIUtilString &vDelimiter,
- VecString_t &vwVecSplits) const;
- size_t SplitLines(VecString_t &vwVecSplits) const;
- CMIUtilString StripCREndOfLine() const;
- CMIUtilString StripCRAll() const;
- CMIUtilString Trim() const;
- CMIUtilString Trim(const char vChar) const;
- size_t FindFirst(const CMIUtilString &vrPattern, size_t vnPos = 0) const;
- size_t FindFirst(const CMIUtilString &vrPattern, bool vbSkipQuotedText,
- bool &vrwbNotFoundClosedQuote, size_t vnPos = 0) const;
- size_t FindFirstNot(const CMIUtilString &vrPattern, size_t vnPos = 0) const;
- CMIUtilString Escape(bool vbEscapeQuotes = false) const;
- CMIUtilString AddSlashes() const;
- CMIUtilString StripSlashes() const;
- //
- CMIUtilString &operator=(const char *vpRhs);
- CMIUtilString &operator=(const std::string &vrRhs);
-
- // Overrideable:
-public:
- /* dtor */ virtual ~CMIUtilString();
-
- // Static method:
-private:
- static CMIUtilString FormatPriv(const CMIUtilString &vrFormat, va_list vArgs);
- static CMIUtilString ConvertCharValueToPrintableASCII(char vChar,
- bool bEscapeQuotes);
-
- // Methods:
-private:
- bool ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const;
- CMIUtilString RemoveRepeatedCharacters(size_t vnPos, const char vChar);
- size_t FindFirstQuote(size_t vnPos) const;
-};
diff --git a/tools/lldb-mi/MIUtilThreadBaseStd.cpp b/tools/lldb-mi/MIUtilThreadBaseStd.cpp
deleted file mode 100644
index 72cf1474a78b..000000000000
--- a/tools/lldb-mi/MIUtilThreadBaseStd.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-//===-- MIUtilThreadBaseStd.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
-//
-//===----------------------------------------------------------------------===//
-
-// Third Party Headers:
-#include <assert.h>
-
-// In-house headers:
-#include "MICmnThreadMgrStd.h"
-#include "MIUtilThreadBaseStd.h"
-
-//++
-// Details: Constructor.
-// Type: None.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilThreadActiveObjBase::CMIUtilThreadActiveObjBase()
- : m_references(0), m_bHasBeenKilled(false) {}
-
-//++
-// Details: Destructor.
-// Type: None.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilThreadActiveObjBase::~CMIUtilThreadActiveObjBase() {
- // Make sure our thread is not alive before we die
- m_thread.Join();
-}
-
-//++
-// Details: Check if an object is already running.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::ThreadIsActive() {
- // Create a new thread to occupy this threads Run() function
- return m_thread.IsActive();
-}
-
-//++
-// Details: Set up *this thread.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::ThreadExecute() {
- // Create a new thread to occupy this threads Run() function
- return m_thread.Start(ThreadEntry, this);
-}
-
-//++
-// Details: Acquire a reference to CMIUtilThreadActiveObjBase.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::Acquire() {
- // Access to this function is serial
- CMIUtilThreadLock serial(m_mutex);
-
- // >0 == *this thread is alive
- m_references++;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Release a reference to CMIUtilThreadActiveObjBase.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::Release() {
- // Access to this function is serial
- CMIUtilThreadLock serial(m_mutex);
-
- // 0 == kill off *this thread
- m_references--;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Force this thread to stop, regardless of references
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::ThreadKill() {
- // Access to this function is serial
- CMIUtilThreadLock serial(m_mutex);
-
- // Set this thread to killed status
- m_bHasBeenKilled = true;
-
- return MIstatus::success;
-}
-
-//++
-// Details: Proxy to thread join.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThreadActiveObjBase::ThreadJoin() { return m_thread.Join(); }
-
-//++
-// Details: This function is the entry point of this object thread.
-// It is a trampoline to an instances operation manager.
-// Type: Static method.
-// Args: vpThisClass - (R) From the system (our CMIUtilThreadActiveObjBase
-// from the ctor).
-// Return: MIuint - 0 = success.
-// Throws: None.
-//--
-MIuint CMIUtilThreadActiveObjBase::ThreadEntry(void *vpThisClass) {
- // The argument is a pointer to a CMIUtilThreadActiveObjBase class
- // as passed from the initialize function, so we can safely cast it.
- assert(vpThisClass != nullptr);
- CMIUtilThreadActiveObjBase *pActive =
- reinterpret_cast<CMIUtilThreadActiveObjBase *>(vpThisClass);
-
- // Start the management routine of this object
- pActive->ThreadManage();
-
- // Thread death
- return 0;
-}
-
-//++
-// Details: This function forms a small management routine, to handle the
-// thread's running.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilThreadActiveObjBase::ThreadManage() {
- bool bAlive = true;
-
- // Infinite loop
- while (bAlive) {
- // Scope the lock while we access m_isDying
- {
- // Lock down access to the interface
- CMIUtilThreadLock serial(m_mutex);
-
- // Quit the run loop if we are dying
- if (m_references == 0)
- break;
- }
- // Execute the run routine
- if (!ThreadRun(bAlive))
- // Thread's run function failed (MIstatus::failure)
- break;
-
- // We will die if we have been signaled to die
- bAlive &= !m_bHasBeenKilled;
- }
-
- // Execute the finish routine just before we die
- // to give the object a chance to clean up
- ThreadFinish();
-
- m_thread.Finish();
-}
-
-
-//
-CMIUtilThread::CMIUtilThread() : m_pThread(nullptr), m_bIsActive(false) {}
-
-//++
-// Details: CMIUtilThread destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilThread::~CMIUtilThread() { Join(); }
-
-//++
-// Details: Wait for thread to stop.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThread::Join() {
- if (m_pThread != nullptr) {
- // Wait for this thread to die
- m_pThread->join();
-
- // Scope the thread lock while we modify the pointer
- {
- CMIUtilThreadLock _lock(m_mutex);
- delete m_pThread;
- m_pThread = nullptr;
- }
- }
-
- return MIstatus::success;
-}
-
-//++
-// Details: Is the thread doing work.
-// Type: Method.
-// Args: None.
-// Return: bool - True = Yes active, false = not active.
-// Throws: None.
-//--
-bool CMIUtilThread::IsActive() {
- // Lock while we access the thread status
- CMIUtilThreadLock _lock(m_mutex);
- return m_bIsActive;
-}
-
-//++
-// Details: Finish this thread
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilThread::Finish() {
- // Lock while we access the thread status
- CMIUtilThreadLock _lock(m_mutex);
- m_bIsActive = false;
-}
-
-//++
-// Details: Set up *this thread.
-// Type: Method.
-// Args: vpFn (R) - Function pointer to thread's main function.
-// vpArg (R) - Pointer arguments to pass to the thread.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool CMIUtilThread::Start(FnThreadProc vpFn, void *vpArg) {
- // Lock while we access the thread pointer and status
- CMIUtilThreadLock _lock(m_mutex);
-
- // Create the std thread, which starts immediately and update its status
- m_pThread = new std::thread(vpFn, vpArg);
- m_bIsActive = true;
-
- // We expect to always be able to create one
- assert(m_pThread != nullptr);
-
- return MIstatus::success;
-}
-
-
-//++
-// Details: Take resource.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilThreadMutex::Lock() { m_mutex.lock(); }
-
-//++
-// Details: Release resource.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilThreadMutex::Unlock() { m_mutex.unlock(); }
-
-//++
-// Details: Take resource if available. Immediately return in either case.
-// Type: Method.
-// Args: None.
-// Return: True - mutex has been locked.
-// False - mutex could not be locked.
-// Throws: None.
-//--
-bool CMIUtilThreadMutex::TryLock() { return m_mutex.try_lock(); }
diff --git a/tools/lldb-mi/MIUtilThreadBaseStd.h b/tools/lldb-mi/MIUtilThreadBaseStd.h
deleted file mode 100644
index 3fa03b6f072e..000000000000
--- a/tools/lldb-mi/MIUtilThreadBaseStd.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- MIUtilThreadBaseStd.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// Third party headers:
-#include <mutex>
-#include <thread>
-
-// In-house headers:
-#include "MIDataTypes.h"
-#include "MIUtilString.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. Handle thread mutual exclusion.
-// Embed Mutexes in your Active Object and then use them through Locks.
-//--
-class CMIUtilThreadMutex {
- // Methods:
-public:
- /* ctor */ CMIUtilThreadMutex() {}
- //
- void Lock(); // Wait until mutex can be obtained
- void Unlock(); // Release the mutex
- bool TryLock(); // Gain the lock if available
-
- // Overrideable:
-public:
- // From CMICmnBase
- /* dtor */ virtual ~CMIUtilThreadMutex() {}
-
- // Attributes:
-private:
- std::recursive_mutex m_mutex;
-};
-
-//++
-//============================================================================
-// Details: MI common code utility class. Thread object.
-//--
-class CMIUtilThread {
- // Typedef:
-public:
- typedef MIuint (*FnThreadProc)(void *vpThisClass);
-
- // Methods:
-public:
- /* ctor */ CMIUtilThread();
- //
- bool Start(FnThreadProc vpFn, void *vpArg); // Start execution of this thread
- bool Join(); // Wait for this thread to stop
- bool IsActive(); // Returns true if this thread is running
- void Finish(); // Finish this thread
-
- // Overrideable:
-public:
- /* dtor */ virtual ~CMIUtilThread();
-
- // Methods:
-private:
- CMIUtilThreadMutex m_mutex;
- std::thread *m_pThread;
- bool m_bIsActive;
-};
-
-//++
-//============================================================================
-// Details: MI common code utility class. Base class for a worker thread active
-// object. Runs an 'captive thread'.
-//--
-class CMIUtilThreadActiveObjBase {
- // Methods:
-public:
- /* ctor */ CMIUtilThreadActiveObjBase();
- //
- bool Acquire(); // Obtain a reference to this object
- bool Release(); // Release a reference to this object
- bool ThreadIsActive(); // Return true if this object is running
- bool ThreadJoin(); // Wait for this thread to stop running
- bool ThreadKill(); // Force this thread to stop, regardless of references
- bool ThreadExecute(); // Start this objects execution in another thread
- void ThreadManage();
-
- // Overrideable:
-public:
- /* dtor */ virtual ~CMIUtilThreadActiveObjBase();
- //
- // Each thread object must supple a unique name that can be used to locate it
- virtual const CMIUtilString &ThreadGetName() const = 0;
-
- // Statics:
-protected:
- static MIuint ThreadEntry(void *vpThisClass); // Thread entry point
-
- // Overrideable:
-protected:
- virtual bool ThreadRun(bool &vrIsAlive) = 0; // Call the main worker method
- virtual bool ThreadFinish() = 0; // Finish of what you were doing
-
- // Attributes:
-protected:
- volatile MIuint m_references; // Stores the current lifetime state of this
- // thread, 0 = running, > 0 = shutting down
- volatile bool
- m_bHasBeenKilled; // Set to true when this thread has been killed
- CMIUtilThread m_thread; // The execution thread
- CMIUtilThreadMutex m_mutex; // This mutex allows us to safely communicate with
- // this thread object across the interface from
- // multiple threads
-};
-
-//++
-//============================================================================
-// Details: MI common code utility class. Handle thread resource locking.
-// Put Locks inside all the methods of your Active Object that access
-// data shared with the captive thread.
-//--
-class CMIUtilThreadLock {
- // Methods:
-public:
- /* ctor */
- CMIUtilThreadLock(CMIUtilThreadMutex &vMutex) : m_rMutex(vMutex) {
- m_rMutex.Lock();
- }
-
- // Overrideable:
-public:
- /* dtor */
- virtual ~CMIUtilThreadLock() { m_rMutex.Unlock(); }
-
- // Attributes:
-private:
- CMIUtilThreadMutex &m_rMutex;
-};
diff --git a/tools/lldb-mi/MIUtilVariant.cpp b/tools/lldb-mi/MIUtilVariant.cpp
deleted file mode 100644
index 062dce80c4b9..000000000000
--- a/tools/lldb-mi/MIUtilVariant.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-//===-- MIUtilVariant.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
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MIUtilVariant.h"
-
-//++
-// Details: CDataObjectBase constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase::CDataObjectBase() {}
-
-//++
-// Details: CDataObjectBase copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase::CDataObjectBase(
- const CDataObjectBase &vrOther) {
- MIunused(vrOther);
-}
-
-//++
-// Details: CDataObjectBase copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase::CDataObjectBase(CDataObjectBase &vrOther) {
- MIunused(vrOther);
-}
-
-//++
-// Details: CDataObjectBase move constructor.
-// Type: Method.
-// Args: vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase::CDataObjectBase(CDataObjectBase &&vrwOther) {
- MIunused(vrwOther);
-}
-
-//++
-// Details: CDataObjectBase destructor.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase::~CDataObjectBase() { Destroy(); }
-
-//++
-// Details: CDataObjectBase copy assignment.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase &CMIUtilVariant::CDataObjectBase::
-operator=(const CDataObjectBase &vrOther) {
- Copy(vrOther);
- return *this;
-}
-
-//++
-// Details: CDataObjectBase move assignment.
-// Type: Method.
-// Args: vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase &CMIUtilVariant::CDataObjectBase::
-operator=(CDataObjectBase &&vrwOther) {
- Copy(vrwOther);
- vrwOther.Destroy();
- return *this;
-}
-
-//++
-// Details: Create a new copy of *this class.
-// Type: Overrideable.
-// Args: None.
-// Return: CDataObjectBase * - Pointer to a new object.
-// Throws: None.
-//--
-CMIUtilVariant::CDataObjectBase *
-CMIUtilVariant::CDataObjectBase::CreateCopyOfSelf() {
- // Override to implement copying of variant's data object
- return new CDataObjectBase();
-}
-
-//++
-// Details: Determine if *this object is a derived from CDataObjectBase.
-// Type: Overrideable.
-// Args: None.
-// Return: bool - True = *this is derived from CDataObjectBase, false =
-// *this is instance of the this base class.
-// Throws: None.
-//--
-bool CMIUtilVariant::CDataObjectBase::GetIsDerivedClass() const {
- // Override to in the derived class and return true
- return false;
-}
-
-//++
-// Details: Perform a bitwise copy of *this object.
-// Type: Overrideable.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilVariant::CDataObjectBase::Copy(const CDataObjectBase &vrOther) {
- // Override to implement
- MIunused(vrOther);
-}
-
-//++
-// Details: Release any resources used by *this object.
-// Type: Overrideable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilVariant::CDataObjectBase::Destroy() {
- // Do nothing - override to implement
-}
-
-
-//++
-// Details: CDataObject copy constructor.
-// Type: Method.
-// Args: T - The object's type.
-// vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T>::CDataObject(const CDataObject &vrOther) {
- if (this == &vrOther)
- return;
- Copy(vrOther);
-}
-
-//++
-// Details: CDataObject copy constructor.
-// Type: Method.
-// Args: T - The object's type.
-// vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T>::CDataObject(CDataObject &vrOther) {
- if (this == &vrOther)
- return;
- Copy(vrOther);
-}
-
-//++
-// Details: CDataObject move constructor.
-// Type: Method.
-// Args: T - The object's type.
-// vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T>::CDataObject(CDataObject &&vrwOther) {
- if (this == &vrwOther)
- return;
- Copy(vrwOther);
- vrwOther.Destroy();
-}
-
-//++
-// Details: CDataObject copy assignment.
-// Type: Method.
-// Args: T - The object's type.
-// vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T> &CMIUtilVariant::CDataObject<T>::
-operator=(const CDataObject &vrOther) {
- if (this == &vrOther)
- return *this;
- Copy(vrOther);
- return *this;
-}
-
-//++
-// Details: CDataObject move assignment.
-// Type: Method.
-// Args: T - The object's type.
-// vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T> &CMIUtilVariant::CDataObject<T>::
-operator=(CDataObject &&vrwOther) {
- if (this == &vrwOther)
- return *this;
- Copy(vrwOther);
- vrwOther.Destroy();
- return *this;
-}
-
-
-//++
-// Details: CMIUtilVariant constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CMIUtilVariant() : m_pDataObject(nullptr) {}
-
-//++
-// Details: CMIUtilVariant copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CMIUtilVariant(const CMIUtilVariant &vrOther)
- : m_pDataObject(nullptr) {
- if (this == &vrOther)
- return;
-
- Copy(vrOther);
-}
-
-//++
-// Details: CMIUtilVariant copy constructor.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CMIUtilVariant(CMIUtilVariant &vrOther)
- : m_pDataObject(nullptr) {
- if (this == &vrOther)
- return;
-
- Copy(vrOther);
-}
-
-//++
-// Details: CMIUtilVariant move constructor.
-// Type: Method.
-// Args: vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::CMIUtilVariant(CMIUtilVariant &&vrwOther)
- : m_pDataObject(nullptr) {
- if (this == &vrwOther)
- return;
-
- Copy(vrwOther);
- vrwOther.Destroy();
-}
-
-//++
-// Details: CMIUtilVariant destructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant::~CMIUtilVariant() { Destroy(); }
-
-//++
-// Details: CMIUtilVariant copy assignment.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant &CMIUtilVariant::operator=(const CMIUtilVariant &vrOther) {
- if (this == &vrOther)
- return *this;
-
- Copy(vrOther);
- return *this;
-}
-
-//++
-// Details: CMIUtilVariant move assignment.
-// Type: Method.
-// Args: vrwOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-CMIUtilVariant &CMIUtilVariant::operator=(CMIUtilVariant &&vrwOther) {
- if (this == &vrwOther)
- return *this;
-
- Copy(vrwOther);
- vrwOther.Destroy();
- return *this;
-}
-
-//++
-// Details: Release the resources used by *this object.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilVariant::Destroy() {
- if (m_pDataObject != nullptr)
- delete m_pDataObject;
- m_pDataObject = nullptr;
-}
-
-//++
-// Details: Bitwise copy another data object to *this variant object.
-// Type: Method.
-// Args: vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-void CMIUtilVariant::Copy(const CMIUtilVariant &vrOther) {
- Destroy();
-
- if (vrOther.m_pDataObject != nullptr) {
- m_pDataObject = vrOther.m_pDataObject->CreateCopyOfSelf();
- }
-}
diff --git a/tools/lldb-mi/MIUtilVariant.h b/tools/lldb-mi/MIUtilVariant.h
deleted file mode 100644
index 4c9db33021b5..000000000000
--- a/tools/lldb-mi/MIUtilVariant.h
+++ /dev/null
@@ -1,247 +0,0 @@
-//===-- MIUtilVariant.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
-//
-//===----------------------------------------------------------------------===//
-
-#pragma once
-
-// In-house headers:
-#include "MIDataTypes.h"
-
-//++
-//============================================================================
-// Details: MI common code utility class. The class implements behaviour of a
-// variant object which holds any data object of type T. A copy of the
-// data object specified is made and stored in *this wrapper. When the
-// *this object is destroyed the data object hold within calls its
-// destructor should it have one.
-//--
-class CMIUtilVariant {
- // Methods:
-public:
- /* ctor */ CMIUtilVariant();
- /* ctor */ CMIUtilVariant(const CMIUtilVariant &vrOther);
- /* ctor */ CMIUtilVariant(CMIUtilVariant &vrOther);
- /* ctor */ CMIUtilVariant(CMIUtilVariant &&vrwOther);
- /* dtor */ ~CMIUtilVariant();
-
- template <typename T> void Set(const T &vArg);
- template <typename T> T *Get() const;
-
- CMIUtilVariant &operator=(const CMIUtilVariant &vrOther);
- CMIUtilVariant &operator=(CMIUtilVariant &&vrwOther);
-
- // Classes:
-private:
- //++ ----------------------------------------------------------------------
- // Details: Base class wrapper to hold the variant's data object when
- // assigned to it by the Set() function. Do not use the
- // CDataObjectBase
- // to create objects, use only CDataObjectBase derived objects,
- // see CDataObject() class.
- //--
- class CDataObjectBase {
- // Methods:
- public:
- /* ctor */ CDataObjectBase();
- /* ctor */ CDataObjectBase(const CDataObjectBase &vrOther);
- /* ctor */ CDataObjectBase(CDataObjectBase &vrOther);
- /* ctor */ CDataObjectBase(CDataObjectBase &&vrwOther);
- //
- CDataObjectBase &operator=(const CDataObjectBase &vrOther);
- CDataObjectBase &operator=(CDataObjectBase &&vrwOther);
-
- // Overrideable:
- public:
- virtual ~CDataObjectBase();
- virtual CDataObjectBase *CreateCopyOfSelf();
- virtual bool GetIsDerivedClass() const;
-
- // Overrideable:
- protected:
- virtual void Copy(const CDataObjectBase &vrOther);
- virtual void Destroy();
- };
-
- //++ ----------------------------------------------------------------------
- // Details: Derived from CDataObjectBase, this class is the wrapper for the
- // data object as it has an aggregate of type T which is a copy
- // of the data object assigned to the variant object.
- //--
- template <typename T> class CDataObject : public CDataObjectBase {
- // Methods:
- public:
- /* ctor */ CDataObject();
- /* ctor */ CDataObject(const T &vArg);
- /* ctor */ CDataObject(const CDataObject &vrOther);
- /* ctor */ CDataObject(CDataObject &vrOther);
- /* ctor */ CDataObject(CDataObject &&vrwOther);
- //
- CDataObject &operator=(const CDataObject &vrOther);
- CDataObject &operator=(CDataObject &&vrwOther);
- //
- T &GetDataObject();
-
- // Overridden:
- public:
- // From CDataObjectBase
- ~CDataObject() override;
- CDataObjectBase *CreateCopyOfSelf() override;
- bool GetIsDerivedClass() const override;
-
- // Overrideable:
- private:
- virtual void Duplicate(const CDataObject &vrOther);
-
- // Overridden:
- private:
- // From CDataObjectBase
- void Destroy() override;
-
- // Attributes:
- private:
- T m_dataObj;
- };
-
- // Methods
-private:
- void Destroy();
- void Copy(const CMIUtilVariant &vrOther);
-
- // Attributes:
-private:
- CDataObjectBase *m_pDataObject;
-};
-
-
-//++
-// Details: CDataObject constructor.
-// Type: Method.
-// Args: T - The object's type.
-// Return: None.
-// Throws: None.
-//--
-template <typename T> CMIUtilVariant::CDataObject<T>::CDataObject() {}
-
-//++
-// Details: CDataObject constructor.
-// Type: Method.
-// Args: T - The object's type.
-// vArg - (R) The data object to be stored in the variant object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObject<T>::CDataObject(const T &vArg) {
- m_dataObj = vArg;
-}
-
-//++
-// Details: CDataObject destructor.
-// Type: Overridden.
-// Args: T - The object's type.
-// Return: None.
-// Throws: None.
-//--
-template <typename T> CMIUtilVariant::CDataObject<T>::~CDataObject() {
- Destroy();
-}
-
-//++
-// Details: Retrieve the data object hold by *this object wrapper.
-// Type: Method.
-// Args: T - The object's type.
-// Return: T & - Reference to the data object.
-// Throws: None.
-//--
-template <typename T> T &CMIUtilVariant::CDataObject<T>::GetDataObject() {
- return m_dataObj;
-}
-
-//++
-// Details: Create a new copy of *this class.
-// Type: Overridden.
-// Args: T - The object's type.
-// Return: CDataObjectBase * - Pointer to a new object.
-// Throws: None.
-//--
-template <typename T>
-CMIUtilVariant::CDataObjectBase *
-CMIUtilVariant::CDataObject<T>::CreateCopyOfSelf() {
- CDataObject *pCopy = new CDataObject<T>(m_dataObj);
-
- return pCopy;
-}
-
-//++
-// Details: Determine if *this object is a derived from CDataObjectBase.
-// Type: Overridden.
-// Args: T - The object's type.
-// Return: bool - True = *this is derived from CDataObjectBase
-// - False = *this is an instance of the base class.
-// Throws: None.
-//--
-template <typename T>
-bool CMIUtilVariant::CDataObject<T>::GetIsDerivedClass() const {
- return true;
-}
-
-//++
-// Details: Perform a bitwise copy of *this object.
-// Type: Overrideable.
-// Args: T - The object's type.
-// vrOther - (R) The other object.
-// Return: None.
-// Throws: None.
-//--
-template <typename T>
-void CMIUtilVariant::CDataObject<T>::Duplicate(const CDataObject &vrOther) {
- CDataObjectBase::Copy(vrOther);
- m_dataObj = vrOther.m_dataObj;
-}
-
-//++
-// Details: Release any resources used by *this object.
-// Type: Overridden.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-template <typename T> void CMIUtilVariant::CDataObject<T>::Destroy() {
- CDataObjectBase::Destroy();
-}
-
-
-//++
-// Details: Assign to the variant an object of a specified type.
-// Type: Template method.
-// Args: T - The object's type.
-// vArg - (R) The object to store.
-// Return: None.
-// Throws: None.
-//--
-template <typename T> void CMIUtilVariant::Set(const T &vArg) {
- m_pDataObject = new CDataObject<T>(vArg);
-}
-
-//++
-// Details: Retrieve the data object from *this variant.
-// Type: Template method.
-// Args: T - The object's type.
-// Return: T * - Pointer the data object, NULL = data object not assigned to
-// *this variant.
-// Throws: None.
-//--
-template <typename T> T *CMIUtilVariant::Get() const {
- if ((m_pDataObject != nullptr) && m_pDataObject->GetIsDerivedClass()) {
- CDataObject<T> *pDataObj = static_cast<CDataObject<T> *>(m_pDataObject);
- return &pDataObj->GetDataObject();
- }
-
- // Do not use a CDataObjectBase object, use only CDataObjectBase derived
- // objects
- return nullptr;
-}
diff --git a/tools/lldb-mi/Platform.h b/tools/lldb-mi/Platform.h
deleted file mode 100644
index aa999f51b956..000000000000
--- a/tools/lldb-mi/Platform.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- Platform.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
-//
-//===----------------------------------------------------------------------===//
-#pragma once
-
-#if defined(_MSC_VER)
-
-#include <inttypes.h>
-#include <io.h>
-#include <signal.h>
-
-#include "lldb/Host/HostGetOpt.h"
-#include "lldb/Host/windows/windows.h"
-
-struct winsize {
- long ws_col;
-};
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-// fcntl.h // This is not used by MI
-#define O_NOCTTY 0400
-
-// ioctls.h
-#define TIOCGWINSZ 0x5413
-
-// tcsetattr arguments
-#define TCSANOW 0
-
-#define NCCS 32
-struct termios {
- tcflag_t c_iflag; // input mode flags
- tcflag_t c_oflag; // output mode flags
- tcflag_t c_cflag; // control mode flags
- tcflag_t c_lflag; // local mode flags
- cc_t c_line; // line discipline
- cc_t c_cc[NCCS]; // control characters
- speed_t c_ispeed; // input speed
- speed_t c_ospeed; // output speed
-};
-
-typedef long pid_t;
-
-#define STDIN_FILENO 0
-#define PATH_MAX 32768
-#define snprintf _snprintf
-
-extern int ioctl(int d, int request, ...);
-extern int kill(pid_t pid, int sig);
-extern int tcsetattr(int fd, int optional_actions,
- const struct termios *termios_p);
-extern int tcgetattr(int fildes, struct termios *termios_p);
-
-// signal handler function pointer type
-typedef void (*sighandler_t)(int);
-
-// CODETAG_IOR_SIGNALS
-// signal.h
-#define SIGQUIT 3 // Terminal quit signal
-#define SIGKILL 9 // Kill (cannot be caught or ignored)
-#define SIGPIPE 13 // Write on a pipe with no one to read it
-#define SIGCONT 18 // Continue executing, if stopped.
-#define SIGTSTP 20 // Terminal stop signal
-#define SIGSTOP 23 // Stop executing (cannot be caught or ignored)
-#define SIGWINCH 28 // (== SIGVTALRM)
-
-#else
-
-#include <inttypes.h>
-#include <limits.h>
-
-#include <getopt.h>
-#include <libgen.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <pthread.h>
-#include <sys/time.h>
-
-#endif
diff --git a/tools/lldb-mi/module.modulemap b/tools/lldb-mi/module.modulemap
deleted file mode 100644
index 01f6a2b79508..000000000000
--- a/tools/lldb-mi/module.modulemap
+++ /dev/null
@@ -1,79 +0,0 @@
-module lldb_mi {
- module MICmdArgContext { header "MICmdArgContext.h" export * }
- module MICmdArgSet { header "MICmdArgSet.h" export * }
- module MICmdArgValBase { header "MICmdArgValBase.h" export * }
- module MICmdArgValConsume { header "MICmdArgValConsume.h" export * }
- module MICmdArgValFile { header "MICmdArgValFile.h" export * }
- module MICmdArgValListBase { header "MICmdArgValListBase.h" export * }
- module MICmdArgValListOfN { header "MICmdArgValListOfN.h" export * }
- module MICmdArgValNumber { header "MICmdArgValNumber.h" export * }
- module MICmdArgValOptionLong { header "MICmdArgValOptionLong.h" export * }
- module MICmdArgValOptionShort { header "MICmdArgValOptionShort.h" export * }
- module MICmdArgValPrintValues { header "MICmdArgValPrintValues.h" export * }
- module MICmdArgValString { header "MICmdArgValString.h" export * }
- module MICmdArgValThreadGrp { header "MICmdArgValThreadGrp.h" export * }
- module MICmdBase { header "MICmdBase.h" export * }
- module MICmdCmdBreak { header "MICmdCmdBreak.h" export * }
- module MICmdCmdData { header "MICmdCmdData.h" export * }
- module MICmdCmdEnviro { header "MICmdCmdEnviro.h" export * }
- module MICmdCmdExec { header "MICmdCmdExec.h" export * }
- module MICmdCmdFile { header "MICmdCmdFile.h" export * }
- module MICmdCmdGdbInfo { header "MICmdCmdGdbInfo.h" export * }
- module MICmdCmdGdbSet { header "MICmdCmdGdbSet.h" export * }
- module MICmdCmdGdbShow { header "MICmdCmdGdbShow.h" export * }
- module MICmdCmdGdbThread { header "MICmdCmdGdbThread.h" export * }
- module MICmdCmd { header "MICmdCmd.h" export * }
- module MICmdCmdMiscellanous { header "MICmdCmdMiscellanous.h" export * }
- module MICmdCmdStack { header "MICmdCmdStack.h" export * }
- module MICmdCmdSupportInfo { header "MICmdCmdSupportInfo.h" export * }
- module MICmdCmdSupportList { header "MICmdCmdSupportList.h" export * }
- module MICmdCmdSymbol { header "MICmdCmdSymbol.h" export * }
- module MICmdCmdTarget { header "MICmdCmdTarget.h" export * }
- module MICmdCmdThread { header "MICmdCmdThread.h" export * }
- module MICmdCmdTrace { header "MICmdCmdTrace.h" export * }
- module MICmdCmdVar { header "MICmdCmdVar.h" export * }
- module MICmdCommands { header "MICmdCommands.h" export * }
- module MICmdData { header "MICmdData.h" export * }
- module MICmdFactory { header "MICmdFactory.h" export * }
- module MICmdInterpreter { header "MICmdInterpreter.h" export * }
- module MICmdInvoker { header "MICmdInvoker.h" export * }
- module MICmdMgr { header "MICmdMgr.h" export * }
- module MICmdMgrSetCmdDeleteCallback { header "MICmdMgrSetCmdDeleteCallback.h" export * }
- module MICmnBase { header "MICmnBase.h" export * }
- module MICmnConfig { header "MICmnConfig.h" export * }
- module MICmnLLDBBroadcaster { header "MICmnLLDBBroadcaster.h" export * }
- module MICmnLLDBDebugger { header "MICmnLLDBDebugger.h" export * }
- module MICmnLLDBDebuggerHandleEvents { header "MICmnLLDBDebuggerHandleEvents.h" export * }
- module MICmnLLDBDebugSessionInfo { header "MICmnLLDBDebugSessionInfo.h" export * }
- module MICmnLLDBDebugSessionInfoVarObj { header "MICmnLLDBDebugSessionInfoVarObj.h" export * }
- module MICmnLLDBProxySBValue { header "MICmnLLDBProxySBValue.h" export * }
- module MICmnLLDBUtilSBValue { header "MICmnLLDBUtilSBValue.h" export * }
- module MICmnLog { header "MICmnLog.h" export * }
- module MICmnLogMediumFile { header "MICmnLogMediumFile.h" export * }
- module MICmnMIOutOfBandRecord { header "MICmnMIOutOfBandRecord.h" export * }
- module MICmnMIResultRecord { header "MICmnMIResultRecord.h" export * }
- module MICmnMIValueConst { header "MICmnMIValueConst.h" export * }
- module MICmnMIValue { header "MICmnMIValue.h" export * }
- module MICmnMIValueList { header "MICmnMIValueList.h" export * }
- module MICmnMIValueResult { header "MICmnMIValueResult.h" export * }
- module MICmnMIValueTuple { header "MICmnMIValueTuple.h" export * }
- module MICmnResources { header "MICmnResources.h" export * }
- module MICmnStreamStderr { header "MICmnStreamStderr.h" export * }
- module MICmnStreamStdin { header "MICmnStreamStdin.h" export * }
- module MICmnStreamStdout { header "MICmnStreamStdout.h" export * }
- module MICmnThreadMgrStd { header "MICmnThreadMgrStd.h" export * }
- module MIDataTypes { header "MIDataTypes.h" export * }
- module MIDriverBase { header "MIDriverBase.h" export * }
- module MIDriver { header "MIDriver.h" export * }
- module MIDriverMgr { header "MIDriverMgr.h" export * }
- module MIUtilDateTimeStd { header "MIUtilDateTimeStd.h" export * }
- module MIUtilDebug { header "MIUtilDebug.h" export * }
- module MIUtilFileStd { header "MIUtilFileStd.h" export * }
- module MIUtilMapIdToVariant { header "MIUtilMapIdToVariant.h" export * }
- module MIUtilSingletonBase { header "MIUtilSingletonBase.h" export * }
- module MIUtilSingletonHelper { header "MIUtilSingletonHelper.h" export * }
- module MIUtilString { header "MIUtilString.h" export * }
- module MIUtilThreadBaseStd { header "MIUtilThreadBaseStd.h" export * }
- module MIUtilVariant { header "MIUtilVariant.h" export * }
- module Platform { header "Platform.h" export * }
-}
diff --git a/tools/lldb-server/LLDBServerUtilities.cpp b/tools/lldb-server/LLDBServerUtilities.cpp
index 095d281e9208..7f9271e36b68 100644
--- a/tools/lldb-server/LLDBServerUtilities.cpp
+++ b/tools/lldb-server/LLDBServerUtilities.cpp
@@ -24,7 +24,7 @@ static std::shared_ptr<raw_ostream> GetLogStream(StringRef log_file) {
if (!log_file.empty()) {
std::error_code EC;
std::shared_ptr<raw_ostream> stream_sp = std::make_shared<raw_fd_ostream>(
- log_file, EC, sys::fs::F_Text | sys::fs::F_Append);
+ log_file, EC, sys::fs::OF_Text | sys::fs::OF_Append);
if (!EC)
return stream_sp;
errs() << llvm::formatv(
diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp
index b479c2197bff..204c67bc470f 100644
--- a/tools/lldb-server/lldb-gdbserver.cpp
+++ b/tools/lldb-server/lldb-gdbserver.cpp
@@ -39,6 +39,8 @@
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#elif defined(__NetBSD__)
#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
+#elif defined(_WIN32)
+#include "Plugins/Process/Windows/Common/NativeProcessWindows.h"
#endif
#ifndef LLGS_PROGRAM_NAME
@@ -60,6 +62,8 @@ namespace {
typedef process_linux::NativeProcessLinux::Factory NativeProcessFactory;
#elif defined(__NetBSD__)
typedef process_netbsd::NativeProcessNetBSD::Factory NativeProcessFactory;
+#elif defined(_WIN32)
+typedef NativeProcessWindows::Factory NativeProcessFactory;
#else
// Dummy implementation to make sure the code compiles
class NativeProcessFactory : public NativeProcessProtocol::Factory {
@@ -104,17 +108,16 @@ static struct option g_long_options[] = {
{"fd", required_argument, nullptr, 'F'},
{nullptr, 0, nullptr, 0}};
+#ifndef _WIN32
// Watch for signals
static int g_sighup_received_count = 0;
-#ifndef _WIN32
static void sighup_handler(MainLoopBase &mainloop) {
++g_sighup_received_count;
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("lldb-server:%s swallowing SIGHUP (receive count=%d)",
- __FUNCTION__, g_sighup_received_count);
+ LLDB_LOGF(log, "lldb-server:%s swallowing SIGHUP (receive count=%d)",
+ __FUNCTION__, g_sighup_received_count);
if (g_sighup_received_count >= 2)
mainloop.RequestTermination();
@@ -479,9 +482,9 @@ int main_gdbserver(int argc, char *argv[]) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(GDBR_LOG_PROCESS));
if (log) {
- log->Printf("lldb-server launch");
+ LLDB_LOGF(log, "lldb-server launch");
for (int i = 0; i < argc; i++) {
- log->Printf("argv[%i] = '%s'", i, argv[i]);
+ LLDB_LOGF(log, "argv[%i] = '%s'", i, argv[i]);
}
}
@@ -515,7 +518,7 @@ int main_gdbserver(int argc, char *argv[]) {
handle_launch(gdb_server, argc, argv);
// Print version info.
- printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
+ printf("%s-%s\n", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port,
progname, subcommand, named_pipe_path.c_str(),
diff --git a/tools/lldb-server/lldb-platform.cpp b/tools/lldb-server/lldb-platform.cpp
index af78f624073e..a6fb5639d642 100644
--- a/tools/lldb-server/lldb-platform.cpp
+++ b/tools/lldb-server/lldb-platform.cpp
@@ -15,12 +15,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#if !defined(_WIN32)
#include <sys/wait.h>
-
+#endif
#include <fstream>
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/raw_ostream.h"
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
@@ -67,6 +69,7 @@ static struct option g_long_options[] = {
#define HIGH_PORT (49151u)
#endif
+#if !defined(_WIN32)
// Watch for signals
static void signal_handler(int signo) {
switch (signo) {
@@ -81,6 +84,7 @@ static void signal_handler(int signo) {
break;
}
}
+#endif
static void display_usage(const char *progname, const char *subcommand) {
fprintf(stderr, "Usage:\n %s %s [--log-file log-file-name] [--log-channels "
@@ -100,29 +104,36 @@ static Status save_socket_id_to_file(const std::string &socket_id,
llvm::SmallString<64> temp_file_path;
temp_file_spec.AppendPathComponent("port-file.%%%%%%");
- int FD;
- auto err_code = llvm::sys::fs::createUniqueFile(temp_file_spec.GetPath(), FD,
- temp_file_path);
- if (err_code)
- return Status("Failed to create temp file: %s", err_code.message().c_str());
-
- llvm::FileRemover tmp_file_remover(temp_file_path);
-
- {
- llvm::raw_fd_ostream temp_file(FD, true);
- temp_file << socket_id;
- temp_file.close();
- if (temp_file.has_error())
- return Status("Failed to write to port file.");
- }
- err_code = llvm::sys::fs::rename(temp_file_path, file_spec.GetPath());
- if (err_code)
- return Status("Failed to rename file %s to %s: %s", temp_file_path.c_str(),
- file_spec.GetPath().c_str(), err_code.message().c_str());
-
- tmp_file_remover.releaseFile();
- return Status();
+ Status status;
+ if (auto Err =
+ handleErrors(llvm::writeFileAtomically(
+ temp_file_path, temp_file_spec.GetPath(), socket_id),
+ [&status, &file_spec](const AtomicFileWriteError &E) {
+ std::string ErrorMsgBuffer;
+ llvm::raw_string_ostream S(ErrorMsgBuffer);
+ E.log(S);
+
+ switch (E.Error) {
+ case atomic_write_error::failed_to_create_uniq_file:
+ status = Status("Failed to create temp file: %s",
+ ErrorMsgBuffer.c_str());
+ break;
+ case atomic_write_error::output_stream_error:
+ status = Status("Failed to write to port file.");
+ break;
+ case atomic_write_error::failed_to_rename_temp_file:
+ status = Status("Failed to rename file %s to %s: %s",
+ ErrorMsgBuffer.c_str(),
+ file_spec.GetPath().c_str(),
+ ErrorMsgBuffer.c_str());
+ break;
+ }
+ })) {
+ return Status("Failed to atomically write file %s",
+ file_spec.GetPath().c_str());
+ }
+ return status;
}
// main
@@ -131,8 +142,10 @@ int main_platform(int argc, char *argv[]) {
const char *subcommand = argv[1];
argc--;
argv++;
+#if !defined(_WIN32)
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, signal_handler);
+#endif
int long_option_index = 0;
Status error;
std::string listen_host_port;
@@ -309,8 +322,10 @@ int main_platform(int argc, char *argv[]) {
printf("Connection established.\n");
if (g_server) {
// Collect child zombie processes.
+#if !defined(_WIN32)
while (waitpid(-1, nullptr, WNOHANG) > 0)
;
+#endif
if (fork()) {
// Parent doesn't need a connection to the lldb client
delete conn;
diff --git a/tools/lldb-server/lldb-server.cpp b/tools/lldb-server/lldb-server.cpp
index 690aa6277bce..ab32eefb518e 100644
--- a/tools/lldb-server/lldb-server.cpp
+++ b/tools/lldb-server/lldb-server.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
@@ -39,7 +40,7 @@ int main_platform(int argc, char *argv[]);
namespace llgs {
static void initialize() {
if (auto e = g_debugger_lifetime->Initialize(
- llvm::make_unique<SystemInitializerLLGS>(), nullptr))
+ std::make_unique<SystemInitializerLLGS>(), nullptr))
llvm::consumeError(std::move(e));
}
@@ -48,6 +49,7 @@ static void terminate_debugger() { g_debugger_lifetime->Terminate(); }
// main
int main(int argc, char *argv[]) {
+ llvm::InitLLVM IL(argc, argv);
llvm::StringRef ToolName = argv[0];
llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
llvm::PrettyStackTraceProgram X(argc, argv);
diff --git a/utils/TableGen/LLDBOptionDefEmitter.cpp b/utils/TableGen/LLDBOptionDefEmitter.cpp
index 4e62197d3989..6e73d0c53de3 100644
--- a/utils/TableGen/LLDBOptionDefEmitter.cpp
+++ b/utils/TableGen/LLDBOptionDefEmitter.cpp
@@ -1,4 +1,4 @@
-//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===//
+//===- LLDBOptionDefEmitter.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,140 +12,174 @@
//===----------------------------------------------------------------------===//
#include "LLDBTableGenBackends.h"
+#include "LLDBTableGenUtils.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
-#include <map>
#include <vector>
using namespace llvm;
+using namespace lldb_private;
-/// Map of command names to their associated records. Also makes sure our
-/// commands are sorted in a deterministic way.
-typedef std::map<std::string, std::vector<Record *>> RecordsByCommand;
-
-/// Groups all records by their command.
-static RecordsByCommand getCommandList(std::vector<Record *> Options) {
- RecordsByCommand result;
- for (Record *Option : Options)
- result[Option->getValueAsString("Command").str()].push_back(Option);
- return result;
-}
-
-static void emitOption(Record *Option, raw_ostream &OS) {
- OS << " {";
-
- // List of option groups this option is in.
+namespace {
+struct CommandOption {
std::vector<std::string> GroupsArg;
-
- if (Option->getValue("Groups")) {
- // The user specified a list of groups.
- auto Groups = Option->getValueAsListOfInts("Groups");
- for (int Group : Groups)
- GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(Group));
- } else if (Option->getValue("GroupStart")) {
- // The user specified a range of groups (with potentially only one element).
- int GroupStart = Option->getValueAsInt("GroupStart");
- int GroupEnd = Option->getValueAsInt("GroupEnd");
- for (int i = GroupStart; i <= GroupEnd; ++i)
- GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(i));
+ bool Required = false;
+ std::string FullName;
+ std::string ShortName;
+ std::string ArgType;
+ bool OptionalArg = false;
+ std::string Validator;
+ std::string ArgEnum;
+ std::vector<StringRef> Completions;
+ std::string Description;
+
+ CommandOption() = default;
+ CommandOption(Record *Option) {
+ if (Option->getValue("Groups")) {
+ // The user specified a list of groups.
+ auto Groups = Option->getValueAsListOfInts("Groups");
+ for (int Group : Groups)
+ GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(Group));
+ } else if (Option->getValue("GroupStart")) {
+ // The user specified a range of groups (with potentially only one
+ // element).
+ int GroupStart = Option->getValueAsInt("GroupStart");
+ int GroupEnd = Option->getValueAsInt("GroupEnd");
+ for (int i = GroupStart; i <= GroupEnd; ++i)
+ GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(i));
+ }
+
+ // Check if this option is required.
+ Required = Option->getValue("Required");
+
+ // Add the full and short name for this option.
+ FullName = Option->getValueAsString("FullName");
+ ShortName = Option->getValueAsString("ShortName");
+
+ if (auto A = Option->getValue("ArgType"))
+ ArgType = A->getValue()->getAsUnquotedString();
+ OptionalArg = Option->getValue("OptionalArg") != nullptr;
+
+ if (Option->getValue("Validator"))
+ Validator = Option->getValueAsString("Validator");
+
+ if (Option->getValue("ArgEnum"))
+ ArgEnum = Option->getValueAsString("ArgEnum");
+
+ if (Option->getValue("Completions"))
+ Completions = Option->getValueAsListOfStrings("Completions");
+
+ if (auto D = Option->getValue("Description"))
+ Description = D->getValue()->getAsUnquotedString();
}
+};
+} // namespace
+
+static void emitOption(const CommandOption &O, raw_ostream &OS) {
+ OS << " {";
// If we have any groups, we merge them. Otherwise we move this option into
// the all group.
- if (GroupsArg.empty())
+ if (O.GroupsArg.empty())
OS << "LLDB_OPT_SET_ALL";
else
- OS << llvm::join(GroupsArg.begin(), GroupsArg.end(), " | ");
+ OS << llvm::join(O.GroupsArg.begin(), O.GroupsArg.end(), " | ");
OS << ", ";
// Check if this option is required.
- OS << (Option->getValue("Required") ? "true" : "false");
+ OS << (O.Required ? "true" : "false");
// Add the full and short name for this option.
- OS << ", \"" << Option->getValueAsString("FullName") << "\", ";
- OS << '\'' << Option->getValueAsString("ShortName") << "'";
-
- auto ArgType = Option->getValue("ArgType");
- bool IsOptionalArg = Option->getValue("OptionalArg") != nullptr;
+ OS << ", \"" << O.FullName << "\", ";
+ OS << '\'' << O.ShortName << "'";
// Decide if we have either an option, required or no argument for this
// option.
OS << ", OptionParser::";
- if (ArgType) {
- if (IsOptionalArg)
+ if (!O.ArgType.empty()) {
+ if (O.OptionalArg)
OS << "eOptionalArgument";
else
OS << "eRequiredArgument";
} else
OS << "eNoArgument";
- OS << ", nullptr, ";
+ OS << ", ";
- if (Option->getValue("ArgEnum"))
- OS << Option->getValueAsString("ArgEnum");
+ if (!O.Validator.empty())
+ OS << O.Validator;
+ else
+ OS << "nullptr";
+ OS << ", ";
+
+ if (!O.ArgEnum.empty())
+ OS << O.ArgEnum;
else
OS << "{}";
OS << ", ";
// Read the tab completions we offer for this option (if there are any)
- if (Option->getValue("Completions")) {
- auto Completions = Option->getValueAsListOfStrings("Completions");
+ if (!O.Completions.empty()) {
std::vector<std::string> CompletionArgs;
- for (llvm::StringRef Completion : Completions)
+ for (llvm::StringRef Completion : O.Completions)
CompletionArgs.push_back("CommandCompletions::e" + Completion.str() +
"Completion");
OS << llvm::join(CompletionArgs.begin(), CompletionArgs.end(), " | ");
- } else {
+ } else
OS << "CommandCompletions::eNoCompletion";
- }
// Add the argument type.
OS << ", eArgType";
- if (ArgType) {
- OS << ArgType->getValue()->getAsUnquotedString();
+ if (!O.ArgType.empty()) {
+ OS << O.ArgType;
} else
OS << "None";
OS << ", ";
// Add the description if there is any.
- if (auto D = Option->getValue("Description"))
- OS << D->getValue()->getAsString();
- else
+ if (!O.Description.empty()) {
+ OS << "\"";
+ llvm::printEscapedString(O.Description, OS);
+ OS << "\"";
+ } else
OS << "\"\"";
OS << "},\n";
}
/// Emits all option initializers to the raw_ostream.
-static void emitOptions(std::string Command, std::vector<Record *> Option,
+static void emitOptions(std::string Command, std::vector<Record *> Records,
raw_ostream &OS) {
+ std::vector<CommandOption> Options;
+ for (Record *R : Records)
+ Options.emplace_back(R);
+
+ std::string ID = Command;
+ std::replace(ID.begin(), ID.end(), ' ', '_');
// Generate the macro that the user needs to define before including the
// *.inc file.
- std::string NeededMacro = "LLDB_OPTIONS_" + Command;
- std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
+ std::string NeededMacro = "LLDB_OPTIONS_" + ID;
// All options are in one file, so we need put them behind macros and ask the
// user to define the macro for the options that are needed.
OS << "// Options for " << Command << "\n";
OS << "#ifdef " << NeededMacro << "\n";
- for (Record *R : Option)
- emitOption(R, OS);
+ OS << "constexpr static OptionDefinition g_" + ID + "_options[] = {\n";
+ for (CommandOption &CO : Options)
+ emitOption(CO, OS);
// We undefine the macro for the user like Clang's include files are doing it.
+ OS << "};\n";
OS << "#undef " << NeededMacro << "\n";
OS << "#endif // " << Command << " command\n\n";
}
void lldb_private::EmitOptionDefs(RecordKeeper &Records, raw_ostream &OS) {
-
- std::vector<Record *> Options = Records.getAllDerivedDefinitions("Option");
-
emitSourceFileHeader("Options for LLDB command line commands.", OS);
- RecordsByCommand ByCommand = getCommandList(Options);
-
- for (auto &CommandRecordPair : ByCommand) {
+ std::vector<Record *> Options = Records.getAllDerivedDefinitions("Option");
+ for (auto &CommandRecordPair : getRecordsByName(Options, "Command")) {
emitOptions(CommandRecordPair.first, CommandRecordPair.second, OS);
}
}
diff --git a/utils/TableGen/LLDBPropertyDefEmitter.cpp b/utils/TableGen/LLDBPropertyDefEmitter.cpp
new file mode 100644
index 000000000000..f49c05c9a585
--- /dev/null
+++ b/utils/TableGen/LLDBPropertyDefEmitter.cpp
@@ -0,0 +1,165 @@
+//===- LLDBPropertyDefEmitter.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
+//
+//===----------------------------------------------------------------------===//
+//
+// These tablegen backends emits LLDB's PropertyDefinition values.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLDBTableGenBackends.h"
+#include "LLDBTableGenUtils.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/StringMatcher.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <vector>
+
+using namespace llvm;
+using namespace lldb_private;
+
+static void emitPropertyEnum(Record *Property, raw_ostream &OS) {
+ OS << "eProperty";
+ OS << Property->getName();
+ OS << ",\n";
+}
+
+static void emitProperty(Record *Property, raw_ostream &OS) {
+ OS << " {";
+
+ // Emit the property name.
+ OS << "\"" << Property->getValueAsString("Name") << "\"";
+ OS << ", ";
+
+ // Emit the property type.
+ OS << "OptionValue::eType";
+ OS << Property->getValueAsString("Type");
+ OS << ", ";
+
+ // Emit the property's global value.
+ OS << (Property->getValue("Global") ? "true" : "false");
+ OS << ", ";
+
+ bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");
+ bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");
+ bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");
+
+ // Guarantee that every property has a default value.
+ assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||
+ hasDefaultStringValue) &&
+ "Property must have a default value");
+
+ // Guarantee that no property has both a default unsigned value and a default
+ // enum value, since they're bothed stored in the same field.
+ assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&
+ "Property cannot have both a unsigned and enum default value.");
+
+ // Emit the default uint value.
+ if (hasDefaultUnsignedValue) {
+ OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));
+ } else if (hasDefaultEnumValue) {
+ OS << Property->getValueAsString("DefaultEnumValue");
+ } else {
+ OS << "0";
+ }
+ OS << ", ";
+
+ // Emit the default string value.
+ if (hasDefaultStringValue) {
+ if (auto D = Property->getValue("DefaultStringValue")) {
+ OS << "\"";
+ OS << D->getValue()->getAsUnquotedString();
+ OS << "\"";
+ } else {
+ OS << "\"\"";
+ }
+ } else {
+ OS << "nullptr";
+ }
+ OS << ", ";
+
+ // Emit the enum values value.
+ if (Property->getValue("EnumValues"))
+ OS << Property->getValueAsString("EnumValues");
+ else
+ OS << "{}";
+ OS << ", ";
+
+ // Emit the property description.
+ if (auto D = Property->getValue("Description")) {
+ OS << "\"";
+ OS << D->getValue()->getAsUnquotedString();
+ OS << "\"";
+ } else {
+ OS << "\"\"";
+ }
+
+ OS << "},\n";
+}
+
+/// Emits all property initializers to the raw_ostream.
+static void emityProperties(std::string PropertyName,
+ std::vector<Record *> PropertyRecords,
+ raw_ostream &OS) {
+ // Generate the macro that the user needs to define before including the
+ // *.inc file.
+ std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
+ std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
+
+ // All options are in one file, so we need put them behind macros and ask the
+ // user to define the macro for the options that are needed.
+ OS << "// Property definitions for " << PropertyName << "\n";
+ OS << "#ifdef " << NeededMacro << "\n";
+ OS << "static constexpr PropertyDefinition g_" << PropertyName
+ << "_properties[] = {\n";
+ for (Record *R : PropertyRecords)
+ emitProperty(R, OS);
+ OS << "};\n";
+ // We undefine the macro for the user like Clang's include files are doing it.
+ OS << "#undef " << NeededMacro << "\n";
+ OS << "#endif // " << PropertyName << " Property\n\n";
+}
+
+/// Emits all property initializers to the raw_ostream.
+static void emitPropertyEnum(std::string PropertyName,
+ std::vector<Record *> PropertyRecords,
+ raw_ostream &OS) {
+ // Generate the macro that the user needs to define before including the
+ // *.inc file.
+ std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
+ std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
+
+ // All options are in one file, so we need put them behind macros and ask the
+ // user to define the macro for the options that are needed.
+ OS << "// Property enum cases for " << PropertyName << "\n";
+ OS << "#ifdef " << NeededMacro << "\n";
+ for (Record *R : PropertyRecords)
+ emitPropertyEnum(R, OS);
+ // We undefine the macro for the user like Clang's include files are doing it.
+ OS << "#undef " << NeededMacro << "\n";
+ OS << "#endif // " << PropertyName << " Property\n\n";
+}
+
+void lldb_private::EmitPropertyDefs(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("Property definitions for LLDB.", OS);
+
+ std::vector<Record *> Properties =
+ Records.getAllDerivedDefinitions("Property");
+ for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
+ emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
+ }
+}
+
+void lldb_private::EmitPropertyEnumDefs(RecordKeeper &Records,
+ raw_ostream &OS) {
+ emitSourceFileHeader("Property definition enum for LLDB.", OS);
+
+ std::vector<Record *> Properties =
+ Records.getAllDerivedDefinitions("Property");
+ for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
+ emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
+ }
+}
diff --git a/utils/TableGen/LLDBTableGen.cpp b/utils/TableGen/LLDBTableGen.cpp
index 9325fe038561..abb6589f0ca6 100644
--- a/utils/TableGen/LLDBTableGen.cpp
+++ b/utils/TableGen/LLDBTableGen.cpp
@@ -1,4 +1,4 @@
-//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===//
+//===- LLDBTableGen.cpp - Top-Level TableGen implementation for LLDB ------===//
//
// 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 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the main function for Clang's TableGen.
+// This file contains the main function for LLDB's TableGen.
//
//===----------------------------------------------------------------------===//
@@ -25,16 +25,22 @@ enum ActionType {
PrintRecords,
DumpJSON,
GenOptionDefs,
+ GenPropertyDefs,
+ GenPropertyEnumDefs,
};
-static cl::opt<ActionType>
- Action(cl::desc("Action to perform:"),
- cl::values(clEnumValN(PrintRecords, "print-records",
- "Print all records to stdout (default)"),
- clEnumValN(DumpJSON, "dump-json",
- "Dump all records as machine-readable JSON"),
- clEnumValN(GenOptionDefs, "gen-lldb-option-defs",
- "Generate clang attribute clases")));
+static cl::opt<ActionType> Action(
+ cl::desc("Action to perform:"),
+ cl::values(clEnumValN(PrintRecords, "print-records",
+ "Print all records to stdout (default)"),
+ clEnumValN(DumpJSON, "dump-json",
+ "Dump all records as machine-readable JSON"),
+ clEnumValN(GenOptionDefs, "gen-lldb-option-defs",
+ "Generate lldb option definitions"),
+ clEnumValN(GenPropertyDefs, "gen-lldb-property-defs",
+ "Generate lldb property definitions"),
+ clEnumValN(GenPropertyEnumDefs, "gen-lldb-property-enum-defs",
+ "Generate lldb property enum definitions")));
static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
switch (Action) {
@@ -47,6 +53,12 @@ static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenOptionDefs:
EmitOptionDefs(Records, OS);
break;
+ case GenPropertyDefs:
+ EmitPropertyDefs(Records, OS);
+ break;
+ case GenPropertyEnumDefs:
+ EmitPropertyEnumDefs(Records, OS);
+ break;
}
return false;
}
diff --git a/utils/TableGen/LLDBTableGenBackends.h b/utils/TableGen/LLDBTableGenBackends.h
index eb14d80c5627..b424abfce9a7 100644
--- a/utils/TableGen/LLDBTableGenBackends.h
+++ b/utils/TableGen/LLDBTableGenBackends.h
@@ -1,4 +1,4 @@
-//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===//
+//===- LLDBTableGenBackends.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,19 +7,21 @@
//===----------------------------------------------------------------------===//
//
// This file contains the declarations for all of the LLDB TableGen
-// backends. A "TableGen backend" is just a function. See
-// "$LLVM_ROOT/utils/TableGen/TableGenBackends.h" for more info.
+// backends. A "TableGen backend" is just a function.
+//
+// See "$LLVM_ROOT/utils/TableGen/TableGenBackends.h" for more info.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H
#define LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H
-#include <string>
+#include "llvm/ADT/StringRef.h"
namespace llvm {
class raw_ostream;
class RecordKeeper;
+class Record;
} // namespace llvm
using llvm::raw_ostream;
@@ -28,6 +30,8 @@ using llvm::RecordKeeper;
namespace lldb_private {
void EmitOptionDefs(RecordKeeper &RK, raw_ostream &OS);
+void EmitPropertyDefs(RecordKeeper &RK, raw_ostream &OS);
+void EmitPropertyEnumDefs(RecordKeeper &RK, raw_ostream &OS);
} // namespace lldb_private
diff --git a/utils/TableGen/LLDBTableGenUtils.cpp b/utils/TableGen/LLDBTableGenUtils.cpp
new file mode 100644
index 000000000000..8b4c7581c98b
--- /dev/null
+++ b/utils/TableGen/LLDBTableGenUtils.cpp
@@ -0,0 +1,21 @@
+//===- LLDBTableGenUtils.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 "LLDBTableGenUtils.h"
+#include "llvm/TableGen/Record.h"
+
+using namespace llvm;
+using namespace lldb_private;
+
+RecordsByName lldb_private::getRecordsByName(std::vector<Record *> Records,
+ StringRef Name) {
+ RecordsByName Result;
+ for (Record *R : Records)
+ Result[R->getValueAsString(Name).str()].push_back(R);
+ return Result;
+}
diff --git a/utils/TableGen/LLDBTableGenUtils.h b/utils/TableGen/LLDBTableGenUtils.h
new file mode 100644
index 000000000000..5553cecafb12
--- /dev/null
+++ b/utils/TableGen/LLDBTableGenUtils.h
@@ -0,0 +1,34 @@
+//===- LLDBTableGenUtils.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 LLVM_LLDB_UTILS_TABLEGEN_TABLEGENUTILS_H
+#define LLVM_LLDB_UTILS_TABLEGEN_TABLEGENUTILS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class RecordKeeper;
+class Record;
+} // namespace llvm
+
+namespace lldb_private {
+
+/// Map of names to their associated records. This map also ensures that our
+/// records are sorted in a deterministic way.
+typedef std::map<std::string, std::vector<llvm::Record *>> RecordsByName;
+
+/// Return records grouped by name.
+RecordsByName getRecordsByName(std::vector<llvm::Record *> Records,
+ llvm::StringRef);
+
+} // namespace lldb_private
+
+#endif