aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit205afe679855a4ce8149cdaa94d3f0868ce796dc (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source
parent0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff)
downloadsrc-205afe679855a4ce8149cdaa94d3f0868ce796dc.tar.gz
src-205afe679855a4ce8149cdaa94d3f0868ce796dc.zip
Import LLDB as of upstream SVN r225923 (git 2b588ecd)vendor/lldb/lldb-r225923
This corresponds with the branchpoint for the 3.6 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/vendor/lldb/dist/; revision=278332 svn path=/vendor/lldb/lldb-r225923/; revision=278333; tag=vendor/lldb/lldb-r225923
Diffstat (limited to 'source')
-rw-r--r--source/API/SBAddress.cpp42
-rw-r--r--source/API/SBBreakpoint.cpp78
-rw-r--r--source/API/SBCommandInterpreter.cpp192
-rw-r--r--source/API/SBCommunication.cpp4
-rw-r--r--source/API/SBCompileUnit.cpp8
-rw-r--r--source/API/SBDebugger.cpp71
-rw-r--r--source/API/SBEvent.cpp6
-rw-r--r--source/API/SBExecutionContext.cpp129
-rw-r--r--source/API/SBFunction.cpp10
-rw-r--r--source/API/SBHostOS.cpp36
-rw-r--r--source/API/SBInstruction.cpp17
-rw-r--r--source/API/SBInstructionList.cpp16
-rw-r--r--source/API/SBListener.cpp6
-rw-r--r--source/API/SBPlatform.cpp3
-rw-r--r--source/API/SBProcess.cpp44
-rw-r--r--source/API/SBSection.cpp8
-rw-r--r--source/API/SBTarget.cpp306
-rw-r--r--source/API/SBThread.cpp105
-rw-r--r--source/API/SBThreadCollection.cpp97
-rw-r--r--source/API/SBThreadPlan.cpp285
-rw-r--r--source/API/SBType.cpp173
-rw-r--r--source/API/SBTypeSummary.cpp97
-rw-r--r--source/API/SBValue.cpp123
-rw-r--r--source/API/SBValueList.cpp24
-rw-r--r--source/Breakpoint/Breakpoint.cpp398
-rw-r--r--source/Breakpoint/BreakpointID.cpp17
-rw-r--r--source/Breakpoint/BreakpointIDList.cpp44
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp23
-rw-r--r--source/Breakpoint/BreakpointLocationCollection.cpp1
-rw-r--r--source/Breakpoint/BreakpointLocationList.cpp27
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp3
-rw-r--r--source/Breakpoint/BreakpointResolverAddress.cpp8
-rw-r--r--source/Breakpoint/BreakpointResolverFileLine.cpp11
-rw-r--r--source/Breakpoint/BreakpointResolverFileRegex.cpp7
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp18
-rw-r--r--source/Breakpoint/BreakpointSite.cpp9
-rw-r--r--source/Commands/CommandCompletions.cpp6
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp588
-rw-r--r--source/Commands/CommandObjectBreakpoint.h14
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp112
-rw-r--r--source/Commands/CommandObjectCommands.cpp238
-rw-r--r--source/Commands/CommandObjectExpression.cpp6
-rw-r--r--source/Commands/CommandObjectMemory.cpp113
-rw-r--r--source/Commands/CommandObjectPlatform.cpp5
-rw-r--r--source/Commands/CommandObjectProcess.cpp27
-rw-r--r--source/Commands/CommandObjectSource.cpp12
-rw-r--r--source/Commands/CommandObjectSyntax.cpp6
-rw-r--r--source/Commands/CommandObjectTarget.cpp120
-rw-r--r--source/Commands/CommandObjectThread.cpp666
-rw-r--r--source/Commands/CommandObjectType.cpp125
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp15
-rw-r--r--source/Core/Address.cpp13
-rw-r--r--source/Core/AddressRange.cpp2
-rw-r--r--source/Core/AddressResolverFileLine.cpp2
-rw-r--r--source/Core/ArchSpec.cpp141
-rw-r--r--source/Core/Communication.cpp25
-rw-r--r--source/Core/Connection.cpp16
-rw-r--r--source/Core/ConnectionSharedMemory.cpp2
-rw-r--r--source/Core/ConstString.cpp25
-rw-r--r--source/Core/DataExtractor.cpp52
-rw-r--r--source/Core/Debugger.cpp509
-rw-r--r--source/Core/Disassembler.cpp55
-rw-r--r--source/Core/FastDemangle.cpp1496
-rw-r--r--source/Core/FileSpecList.cpp4
-rw-r--r--source/Core/IOHandler.cpp236
-rw-r--r--source/Core/Log.cpp8
-rw-r--r--source/Core/Mangled.cpp61
-rw-r--r--source/Core/Module.cpp37
-rw-r--r--source/Core/ModuleList.cpp20
-rw-r--r--source/Core/PluginManager.cpp223
-rw-r--r--source/Core/RegularExpression.cpp20
-rw-r--r--source/Core/SearchFilter.cpp92
-rw-r--r--source/Core/Section.cpp14
-rw-r--r--source/Core/StreamString.cpp16
-rw-r--r--source/Core/ValueObject.cpp520
-rw-r--r--source/Core/ValueObjectCast.cpp2
-rw-r--r--source/Core/ValueObjectChild.cpp2
-rw-r--r--source/Core/ValueObjectConstResult.cpp18
-rw-r--r--source/Core/ValueObjectConstResultImpl.cpp56
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp13
-rw-r--r--source/Core/ValueObjectMemory.cpp2
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp60
-rw-r--r--source/Core/ValueObjectVariable.cpp43
-rw-r--r--source/DataFormatters/CF.cpp8
-rw-r--r--source/DataFormatters/CXXFormatterFunctions.cpp580
-rw-r--r--source/DataFormatters/Cocoa.cpp28
-rw-r--r--source/DataFormatters/DataVisualization.cpp24
-rw-r--r--source/DataFormatters/FormatCache.cpp76
-rw-r--r--source/DataFormatters/FormatManager.cpp205
-rw-r--r--source/DataFormatters/LibCxx.cpp113
-rw-r--r--source/DataFormatters/LibCxxInitializerList.cpp145
-rw-r--r--source/DataFormatters/LibCxxList.cpp61
-rw-r--r--source/DataFormatters/LibCxxMap.cpp215
-rw-r--r--source/DataFormatters/LibCxxUnorderedMap.cpp35
-rw-r--r--source/DataFormatters/LibCxxVector.cpp157
-rw-r--r--source/DataFormatters/LibStdcpp.cpp2
-rw-r--r--source/DataFormatters/NSArray.cpp17
-rw-r--r--source/DataFormatters/NSDictionary.cpp197
-rw-r--r--source/DataFormatters/NSIndexPath.cpp309
-rw-r--r--source/DataFormatters/NSSet.cpp178
-rw-r--r--source/DataFormatters/StringPrinter.cpp650
-rw-r--r--source/DataFormatters/TypeCategory.cpp97
-rw-r--r--source/DataFormatters/TypeCategoryMap.cpp68
-rw-r--r--source/DataFormatters/TypeFormat.cpp12
-rw-r--r--source/DataFormatters/TypeSummary.cpp56
-rw-r--r--source/DataFormatters/TypeSynthetic.cpp138
-rw-r--r--source/DataFormatters/TypeValidator.cpp75
-rw-r--r--source/DataFormatters/ValueObjectPrinter.cpp108
-rw-r--r--source/Expression/ClangASTSource.cpp239
-rw-r--r--source/Expression/ClangExpressionDeclMap.cpp51
-rw-r--r--source/Expression/ClangExpressionParser.cpp83
-rw-r--r--source/Expression/ClangExpressionVariable.cpp11
-rw-r--r--source/Expression/ClangFunction.cpp22
-rw-r--r--source/Expression/ClangModulesDeclVendor.cpp372
-rw-r--r--source/Expression/ClangUserExpression.cpp25
-rw-r--r--source/Expression/DWARFExpression.cpp7
-rw-r--r--source/Expression/IRExecutionUnit.cpp128
-rw-r--r--source/Expression/IRForTarget.cpp54
-rw-r--r--source/Host/common/Editline.cpp1735
-rw-r--r--source/Host/common/File.cpp2
-rw-r--r--source/Host/common/FileSpec.cpp189
-rw-r--r--source/Host/common/Host.cpp471
-rw-r--r--source/Host/common/HostInfoBase.cpp36
-rw-r--r--source/Host/common/HostNativeThreadBase.cpp82
-rw-r--r--source/Host/common/HostProcess.cpp65
-rw-r--r--source/Host/common/HostThread.cpp78
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp102
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp23
-rw-r--r--source/Host/common/NativeProcessProtocol.h23
-rw-r--r--source/Host/common/NativeThreadProtocol.h2
-rw-r--r--source/Host/common/Pipe.cpp171
-rw-r--r--source/Host/common/PipeBase.cpp27
-rw-r--r--source/Host/common/Socket.cpp78
-rw-r--r--source/Host/common/SocketAddress.cpp10
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp19
-rw-r--r--source/Host/common/ThisThread.cpp52
-rw-r--r--source/Host/common/ThreadLauncher.cpp74
-rw-r--r--source/Host/freebsd/Host.cpp114
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp6
-rw-r--r--source/Host/freebsd/HostThreadFreeBSD.cpp77
-rw-r--r--source/Host/freebsd/ThisThread.cpp30
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp (renamed from source/Core/ConnectionFileDescriptor.cpp)478
-rw-r--r--source/Host/posix/HostInfoPosix.cpp14
-rw-r--r--source/Host/posix/HostProcessPosix.cpp47
-rw-r--r--source/Host/posix/HostThreadPosix.cpp74
-rw-r--r--source/Host/posix/PipePosix.cpp378
-rw-r--r--source/Host/posix/ProcessLauncherPosix.cpp33
-rw-r--r--source/Interpreter/Args.cpp33
-rw-r--r--source/Interpreter/CommandInterpreter.cpp337
-rw-r--r--source/Interpreter/CommandObject.cpp53
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp6
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp2
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp13
-rw-r--r--source/Interpreter/OptionValue.cpp39
-rw-r--r--source/Interpreter/OptionValueArch.cpp4
-rw-r--r--source/Interpreter/OptionValueArray.cpp2
-rw-r--r--source/Interpreter/OptionValueBoolean.cpp2
-rw-r--r--source/Interpreter/OptionValueChar.cpp80
-rw-r--r--source/Interpreter/OptionValueDictionary.cpp6
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp2
-rw-r--r--source/Interpreter/OptionValueFileSpec.cpp2
-rw-r--r--source/Interpreter/OptionValueFileSpecLIst.cpp8
-rw-r--r--source/Interpreter/OptionValueFormat.cpp2
-rw-r--r--source/Interpreter/OptionValuePathMappings.cpp8
-rw-r--r--source/Interpreter/OptionValueProperties.cpp10
-rw-r--r--source/Interpreter/OptionValueRegex.cpp2
-rw-r--r--source/Interpreter/OptionValueSInt64.cpp2
-rw-r--r--source/Interpreter/OptionValueString.cpp37
-rw-r--r--source/Interpreter/OptionValueUInt64.cpp2
-rw-r--r--source/Interpreter/OptionValueUUID.cpp4
-rw-r--r--source/Interpreter/Property.cpp15
-rw-r--r--source/Interpreter/ScriptInterpreter.cpp12
-rw-r--r--source/Interpreter/ScriptInterpreterPython.cpp221
-rw-r--r--source/Interpreter/embedded_interpreter.py2
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp30
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h14
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp34
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h16
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h14
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h14
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp1120
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h143
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp1124
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h143
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp14
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h14
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp37
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp28
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp189
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h4
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp2
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp314
-rw-r--r--source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.h86
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp30
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.h4
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp183
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h62
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp2
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp9
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp135
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h3
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp77
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h6
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp130
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h56
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp26
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h7
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp3
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp66
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h7
-rw-r--r--source/Plugins/Process/POSIX/POSIXThread.cpp45
-rw-r--r--source/Plugins/Process/POSIX/POSIXThread.h2
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.cpp39
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.h59
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp4
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp4
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp321
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h95
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp9
-rw-r--r--source/Plugins/Process/Utility/ARMDefines.h34
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp12
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp2
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h12
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp2
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h3
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp24
-rw-r--r--source/Plugins/Process/Utility/InstructionUtils.h2
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp230
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h66
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp703
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h26
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp273
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h173
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp578
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h277
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_powerpc.h163
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h18
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_powerpc.h144
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h34
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp8
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp46
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h3
-rw-r--r--source/Plugins/Process/Utility/lldb-x86-register-enums.h461
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp25
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h24
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp109
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h62
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp2
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp20
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp118
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp61
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp236
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h19
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp134
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h97
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp16
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp29
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h15
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp91
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp153
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h23
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h6
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp280
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h5
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp3
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp473
-rw-r--r--source/Symbol/ClangASTContext.cpp67
-rw-r--r--source/Symbol/ClangASTImporter.cpp2
-rw-r--r--source/Symbol/ClangASTType.cpp225
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp38
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp1215
-rw-r--r--source/Symbol/CompileUnit.cpp7
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp41
-rw-r--r--source/Symbol/Declaration.cpp2
-rw-r--r--source/Symbol/FuncUnwinders.cpp379
-rw-r--r--source/Symbol/LineTable.cpp1
-rw-r--r--source/Symbol/ObjectFile.cpp6
-rw-r--r--source/Symbol/Symbol.cpp2
-rw-r--r--source/Symbol/SymbolContext.cpp12
-rw-r--r--source/Symbol/Type.cpp112
-rw-r--r--source/Symbol/UnwindPlan.cpp77
-rw-r--r--source/Symbol/UnwindTable.cpp16
-rw-r--r--source/Symbol/Variable.cpp4
-rw-r--r--source/Target/CPPLanguageRuntime.cpp78
-rw-r--r--source/Target/FileAction.cpp32
-rw-r--r--source/Target/InstrumentationRuntime.cpp48
-rw-r--r--source/Target/InstrumentationRuntimeStopInfo.cpp36
-rw-r--r--source/Target/LanguageRuntime.cpp56
-rw-r--r--source/Target/Memory.cpp19
-rw-r--r--source/Target/MemoryHistory.cpp30
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp8
-rw-r--r--source/Target/Platform.cpp281
-rw-r--r--source/Target/Process.cpp518
-rw-r--r--source/Target/ProcessLaunchInfo.cpp180
-rw-r--r--source/Target/StackFrame.cpp55
-rw-r--r--source/Target/StackFrameList.cpp15
-rw-r--r--source/Target/StopInfo.cpp24
-rw-r--r--source/Target/Target.cpp218
-rw-r--r--source/Target/TargetList.cpp134
-rw-r--r--source/Target/Thread.cpp259
-rw-r--r--source/Target/ThreadCollection.cpp62
-rw-r--r--source/Target/ThreadList.cpp23
-rw-r--r--source/Target/ThreadPlanPython.cpp192
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp30
-rw-r--r--source/Target/ThreadPlanStepInstruction.cpp29
-rw-r--r--source/Target/ThreadPlanStepOut.cpp51
-rw-r--r--source/Target/ThreadPlanStepOverBreakpoint.cpp35
-rw-r--r--source/Target/ThreadPlanStepOverRange.cpp26
-rw-r--r--source/Target/ThreadPlanStepRange.cpp8
-rw-r--r--source/Target/ThreadPlanStepThrough.cpp5
-rw-r--r--source/Target/ThreadPlanTracer.cpp6
-rw-r--r--source/Utility/PseudoTerminal.cpp6
-rw-r--r--source/Utility/RegisterNumber.cpp157
-rw-r--r--source/Utility/StringExtractor.cpp105
-rw-r--r--source/Utility/StringExtractor.h7
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp13
-rw-r--r--source/Utility/StringLexer.cpp78
-rw-r--r--source/Utility/UriParser.cpp58
-rw-r--r--source/Utility/UriParser.h31
-rw-r--r--source/lldb-log.cpp3
-rw-r--r--source/lldb.cpp39
332 files changed, 25749 insertions, 7724 deletions
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp
index 6aec0722169f..d6e32b60059b 100644
--- a/source/API/SBAddress.cpp
+++ b/source/API/SBAddress.cpp
@@ -23,19 +23,19 @@ using namespace lldb_private;
SBAddress::SBAddress () :
- m_opaque_ap ()
+ m_opaque_ap (new Address())
{
}
SBAddress::SBAddress (const Address *lldb_object_ptr) :
- m_opaque_ap ()
+ m_opaque_ap (new Address())
{
if (lldb_object_ptr)
ref() = *lldb_object_ptr;
}
SBAddress::SBAddress (const SBAddress &rhs) :
- m_opaque_ap ()
+ m_opaque_ap (new Address())
{
if (rhs.IsValid())
ref() = rhs.ref();
@@ -49,7 +49,7 @@ SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) :
// Create an address by resolving a load address using the supplied target
SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) :
- m_opaque_ap()
+ m_opaque_ap(new Address())
{
SetLoadAddress (load_addr, target);
}
@@ -68,7 +68,7 @@ SBAddress::operator = (const SBAddress &rhs)
if (rhs.IsValid())
ref() = rhs.ref();
else
- m_opaque_ap.reset();
+ m_opaque_ap.reset (new Address());
}
return *this;
}
@@ -82,7 +82,7 @@ SBAddress::IsValid () const
void
SBAddress::Clear ()
{
- m_opaque_ap.reset();
+ m_opaque_ap.reset (new Address());
}
void
@@ -100,13 +100,13 @@ SBAddress::SetAddress (const Address *lldb_object_ptr)
if (lldb_object_ptr)
ref() = *lldb_object_ptr;
else
- m_opaque_ap.reset();
+ m_opaque_ap.reset (new Address());
}
lldb::addr_t
SBAddress::GetFileAddress () const
{
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
return m_opaque_ap->GetFileAddress();
else
return LLDB_INVALID_ADDRESS;
@@ -121,7 +121,7 @@ SBAddress::GetLoadAddress (const SBTarget &target) const
TargetSP target_sp (target.GetSP());
if (target_sp)
{
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
addr = m_opaque_ap->GetLoadAddress (target_sp.get());
@@ -162,7 +162,7 @@ SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target)
bool
SBAddress::OffsetAddress (addr_t offset)
{
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
{
addr_t addr_offset = m_opaque_ap->GetOffset();
if (addr_offset != LLDB_INVALID_ADDRESS)
@@ -178,7 +178,7 @@ lldb::SBSection
SBAddress::GetSection ()
{
lldb::SBSection sb_section;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_section.SetSP (m_opaque_ap->GetSection());
return sb_section;
}
@@ -186,7 +186,7 @@ SBAddress::GetSection ()
lldb::addr_t
SBAddress::GetOffset ()
{
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
return m_opaque_ap->GetOffset();
return 0;
}
@@ -233,7 +233,7 @@ SBAddress::GetDescription (SBStream &description)
// Call "ref()" on the stream to make sure it creates a backing stream in
// case there isn't one already...
Stream &strm = description.ref();
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
{
m_opaque_ap->Dump (&strm,
NULL,
@@ -255,7 +255,7 @@ SBModule
SBAddress::GetModule ()
{
SBModule sb_module;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_module.SetSP (m_opaque_ap->GetModule());
return sb_module;
}
@@ -264,7 +264,7 @@ SBSymbolContext
SBAddress::GetSymbolContext (uint32_t resolve_scope)
{
SBSymbolContext sb_sc;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
return sb_sc;
}
@@ -273,7 +273,7 @@ SBCompileUnit
SBAddress::GetCompileUnit ()
{
SBCompileUnit sb_comp_unit;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
return sb_comp_unit;
}
@@ -282,7 +282,7 @@ SBFunction
SBAddress::GetFunction ()
{
SBFunction sb_function;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
return sb_function;
}
@@ -291,7 +291,7 @@ SBBlock
SBAddress::GetBlock ()
{
SBBlock sb_block;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock());
return sb_block;
}
@@ -300,7 +300,7 @@ SBSymbol
SBAddress::GetSymbol ()
{
SBSymbol sb_symbol;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
return sb_symbol;
}
@@ -309,7 +309,7 @@ SBLineEntry
SBAddress::GetLineEntry ()
{
SBLineEntry sb_line_entry;
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
{
LineEntry line_entry;
if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
@@ -321,7 +321,7 @@ SBAddress::GetLineEntry ()
AddressClass
SBAddress::GetAddressClass ()
{
- if (m_opaque_ap.get())
+ if (m_opaque_ap->IsValid())
return m_opaque_ap->GetAddressClass();
return eAddressClassInvalid;
}
diff --git a/source/API/SBBreakpoint.cpp b/source/API/SBBreakpoint.cpp
index a950ca934c68..dd4c80caf45d 100644
--- a/source/API/SBBreakpoint.cpp
+++ b/source/API/SBBreakpoint.cpp
@@ -13,6 +13,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
#include "lldb/API/SBThread.h"
#include "lldb/Breakpoint/Breakpoint.h"
@@ -653,6 +654,83 @@ SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
return sb_error;
}
+bool
+SBBreakpoint::AddName (const char *new_name)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (log)
+ log->Printf ("SBBreakpoint(%p)::AddName (name=%s)",
+ static_cast<void*>(m_opaque_sp.get()),
+ new_name);
+
+ if (m_opaque_sp)
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ Error error; // Think I'm just going to swallow the error here, it's probably more annoying to have to provide it.
+ return m_opaque_sp->AddName(new_name, error);
+ }
+
+ return false;
+}
+
+void
+SBBreakpoint::RemoveName (const char *name_to_remove)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (log)
+ log->Printf ("SBBreakpoint(%p)::RemoveName (name=%s)",
+ static_cast<void*>(m_opaque_sp.get()),
+ name_to_remove);
+
+ if (m_opaque_sp)
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ m_opaque_sp->RemoveName(name_to_remove);
+ }
+}
+
+bool
+SBBreakpoint::MatchesName (const char *name)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (log)
+ log->Printf ("SBBreakpoint(%p)::MatchesName (name=%s)",
+ static_cast<void*>(m_opaque_sp.get()),
+ name);
+
+ if (m_opaque_sp)
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ return m_opaque_sp->MatchesName(name);
+ }
+
+ return false;
+}
+
+void
+SBBreakpoint::GetNames (SBStringList &names)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (log)
+ log->Printf ("SBBreakpoint(%p)::GetNames ()",
+ static_cast<void*>(m_opaque_sp.get()));
+
+ if (m_opaque_sp)
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+ std::vector<std::string> names_vec;
+ m_opaque_sp->GetNames(names_vec);
+ for (std::string name : names_vec)
+ {
+ names.AppendString (name.c_str());
+ }
+ }
+}
+
lldb_private::Breakpoint *
SBBreakpoint::operator->() const
{
diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp
index e1adea795b08..193d06e4d920 100644
--- a/source/API/SBCommandInterpreter.cpp
+++ b/source/API/SBCommandInterpreter.cpp
@@ -20,6 +20,7 @@
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBExecutionContext.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBListener.h"
@@ -29,6 +30,100 @@
using namespace lldb;
using namespace lldb_private;
+SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions()
+{
+ m_opaque_up.reset(new CommandInterpreterRunOptions());
+}
+
+SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions()
+{
+
+}
+
+bool
+SBCommandInterpreterRunOptions::GetStopOnContinue () const
+{
+ return m_opaque_up->GetStopOnContinue();
+}
+
+void
+SBCommandInterpreterRunOptions::SetStopOnContinue (bool stop_on_continue)
+{
+ m_opaque_up->SetStopOnContinue(stop_on_continue);
+}
+
+bool
+SBCommandInterpreterRunOptions::GetStopOnError () const
+{
+ return m_opaque_up->GetStopOnError();
+}
+
+void
+SBCommandInterpreterRunOptions::SetStopOnError (bool stop_on_error)
+{
+ m_opaque_up->SetStopOnError(stop_on_error);
+}
+
+bool
+SBCommandInterpreterRunOptions::GetStopOnCrash () const
+{
+ return m_opaque_up->GetStopOnCrash();
+}
+
+void
+SBCommandInterpreterRunOptions::SetStopOnCrash (bool stop_on_crash)
+{
+ m_opaque_up->SetStopOnCrash(stop_on_crash);
+}
+
+bool
+SBCommandInterpreterRunOptions::GetEchoCommands () const
+{
+ return m_opaque_up->GetEchoCommands();
+}
+
+void
+SBCommandInterpreterRunOptions::SetEchoCommands (bool echo_commands)
+{
+ m_opaque_up->SetEchoCommands(echo_commands);
+}
+
+bool
+SBCommandInterpreterRunOptions::GetPrintResults () const
+{
+ return m_opaque_up->GetPrintResults();
+}
+
+void
+SBCommandInterpreterRunOptions::SetPrintResults (bool print_results)
+{
+ m_opaque_up->SetPrintResults(print_results);
+}
+
+bool
+SBCommandInterpreterRunOptions::GetAddToHistory () const
+{
+ return m_opaque_up->GetAddToHistory();
+}
+
+void
+SBCommandInterpreterRunOptions::SetAddToHistory (bool add_to_history)
+{
+ m_opaque_up->SetAddToHistory(add_to_history);
+}
+
+lldb_private::CommandInterpreterRunOptions *
+SBCommandInterpreterRunOptions::get () const
+{
+ return m_opaque_up.get();
+}
+
+lldb_private::CommandInterpreterRunOptions &
+SBCommandInterpreterRunOptions::ref () const
+{
+ return *m_opaque_up.get();
+}
+
class CommandPluginInterfaceImplementation : public CommandObjectParsed
{
public:
@@ -128,6 +223,13 @@ SBCommandInterpreter::GetIOHandlerControlSequence(char ch)
lldb::ReturnStatus
SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
{
+ SBExecutionContext sb_exe_ctx;
+ return HandleCommand (command_line, sb_exe_ctx, result, add_to_history);
+}
+
+lldb::ReturnStatus
+SBCommandInterpreter::HandleCommand (const char *command_line, SBExecutionContext &override_context, SBCommandReturnObject &result, bool add_to_history)
+{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
@@ -135,11 +237,21 @@ SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnOb
static_cast<void*>(m_opaque_ptr), command_line,
static_cast<void*>(result.get()), add_to_history);
+ ExecutionContext ctx, *ctx_ptr;
+ if (override_context.get())
+ {
+ ctx = override_context.get()->Lock(true);
+ ctx_ptr = &ctx;
+ }
+ else
+ ctx_ptr = nullptr;
+
+
result.Clear();
if (command_line && m_opaque_ptr)
{
result.ref().SetInteractive(false);
- m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref());
+ m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref(), ctx_ptr);
}
else
{
@@ -162,6 +274,54 @@ SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnOb
return result.GetStatus();
}
+void
+SBCommandInterpreter::HandleCommandsFromFile (lldb::SBFileSpec &file,
+ lldb::SBExecutionContext &override_context,
+ lldb::SBCommandInterpreterRunOptions &options,
+ lldb::SBCommandReturnObject result)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (log)
+ {
+ SBStream s;
+ file.GetDescription (s);
+ log->Printf ("SBCommandInterpreter(%p)::HandleCommandsFromFile (file=\"%s\", SBCommandReturnObject(%p))",
+ static_cast<void*>(m_opaque_ptr), s.GetData(),
+ static_cast<void*>(result.get()));
+ }
+
+ if (!m_opaque_ptr)
+ {
+ result->AppendError ("SBCommandInterpreter is not valid.");
+ result->SetStatus (eReturnStatusFailed);
+ return;
+ }
+
+ if (!file.IsValid())
+ {
+ SBStream s;
+ file.GetDescription (s);
+ result->AppendErrorWithFormat ("File is not valid: %s.", s.GetData());
+ result->SetStatus (eReturnStatusFailed);
+ }
+
+ FileSpec tmp_spec = file.ref();
+ ExecutionContext ctx, *ctx_ptr;
+ if (override_context.get())
+ {
+ ctx = override_context.get()->Lock(true);
+ ctx_ptr = &ctx;
+ }
+ else
+ ctx_ptr = nullptr;
+
+
+ m_opaque_ptr->HandleCommandsFromFile (tmp_spec, ctx_ptr, options.ref(), result.ref());
+
+}
+
+
int
SBCommandInterpreter::HandleCompletion (const char *current_line,
const char *cursor,
@@ -434,6 +594,7 @@ LLDBSwigPythonCallTypeScript (const char *python_function_name,
void *session_dictionary,
const lldb::ValueObjectSP& valobj_sp,
void** pyfunct_wrapper,
+ const lldb::TypeSummaryOptionsSP& options_sp,
std::string& retval);
extern "C" void*
@@ -442,6 +603,17 @@ LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name,
const lldb::ValueObjectSP& valobj_sp);
+extern "C" void*
+LLDBSwigPythonCreateScriptedThreadPlan (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ThreadPlanSP& thread_plan_sp);
+
+extern "C" bool
+LLDBSWIGPythonCallThreadPlan (void *implementor,
+ const char *method_name,
+ Event *event_sp,
+ bool &got_error);
+
extern "C" uint32_t
LLDBSwigPython_CalculateNumChildren (void *implementor);
@@ -463,12 +635,16 @@ LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
extern "C" bool
LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
+extern "C" void *
+LLDBSwigPython_GetValueSynthProviderInstance (void* implementor);
+
extern "C" bool
LLDBSwigPythonCallCommand (const char *python_function_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger,
const char* args,
- lldb_private::CommandReturnObject &cmd_retobj);
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
extern "C" bool
LLDBSwigPythonCallModuleInit (const char *python_module_name,
@@ -504,6 +680,12 @@ LLDBSWIGPythonRunScriptKeywordFrame (const char* python_function_name,
lldb::StackFrameSP& frame,
std::string& output);
+extern "C" bool
+LLDBSWIGPythonRunScriptKeywordValue (const char* python_function_name,
+ const char* session_dictionary_name,
+ lldb::ValueObjectSP& value,
+ std::string& output);
+
extern "C" void*
LLDBSWIGPython_GetDynamicSetting (void* module,
const char* setting,
@@ -532,6 +714,7 @@ SBCommandInterpreter::InitializeSWIG ()
LLDBSWIGPython_GetValueObjectSPFromSBValue,
LLDBSwigPython_UpdateSynthProviderInstance,
LLDBSwigPython_MightHaveChildrenSynthProviderInstance,
+ LLDBSwigPython_GetValueSynthProviderInstance,
LLDBSwigPythonCallCommand,
LLDBSwigPythonCallModuleInit,
LLDBSWIGPythonCreateOSPlugin,
@@ -539,7 +722,10 @@ SBCommandInterpreter::InitializeSWIG ()
LLDBSWIGPythonRunScriptKeywordThread,
LLDBSWIGPythonRunScriptKeywordTarget,
LLDBSWIGPythonRunScriptKeywordFrame,
- LLDBSWIGPython_GetDynamicSetting);
+ LLDBSWIGPythonRunScriptKeywordValue,
+ LLDBSWIGPython_GetDynamicSetting,
+ LLDBSwigPythonCreateScriptedThreadPlan,
+ LLDBSWIGPythonCallThreadPlan);
#endif
}
}
diff --git a/source/API/SBCommunication.cpp b/source/API/SBCommunication.cpp
index df0b864fad94..956b6cfcdd31 100644
--- a/source/API/SBCommunication.cpp
+++ b/source/API/SBCommunication.cpp
@@ -10,8 +10,8 @@
#include "lldb/API/SBCommunication.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Log.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
using namespace lldb;
using namespace lldb_private;
@@ -71,7 +71,7 @@ SBCommunication::Connect (const char *url)
if (m_opaque)
{
if (!m_opaque->HasConnection ())
- m_opaque->SetConnection (new ConnectionFileDescriptor());
+ m_opaque->SetConnection(Connection::CreateDefaultConnection(url));
return m_opaque->Connect (url, NULL);
}
return eConnectionStatusNoConnection;
diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp
index 03c25710a9e4..5d904ce56300 100644
--- a/source/API/SBCompileUnit.cpp
+++ b/source/API/SBCompileUnit.cpp
@@ -228,6 +228,14 @@ SBCompileUnit::FindSupportFileIndex (uint32_t start_idx, const SBFileSpec &sb_fi
return 0;
}
+lldb::LanguageType
+SBCompileUnit::GetLanguage ()
+{
+ if (m_opaque_ptr)
+ return m_opaque_ptr->GetLanguage();
+ return lldb::eLanguageTypeUnknown;
+}
+
bool
SBCompileUnit::IsValid () const
{
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index dae567525a4a..a95f2ffc06d9 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -715,16 +715,13 @@ SBDebugger::CreateTarget (const char *filename)
TargetSP target_sp;
if (m_opaque_sp)
{
- ArchSpec arch = Target::GetDefaultArchitecture ();
Error error;
const bool add_dependent_modules = true;
-
- PlatformSP platform_sp(m_opaque_sp->GetPlatformList().GetSelectedPlatform());
- error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
+ error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
filename,
- arch,
+ NULL,
add_dependent_modules,
- platform_sp,
+ NULL,
target_sp);
if (error.Success())
@@ -972,7 +969,32 @@ SBDebugger::RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread)
{
if (m_opaque_sp)
- m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, spawn_thread);
+ {
+ CommandInterpreterRunOptions options;
+
+ m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events,
+ spawn_thread,
+ options);
+ }
+}
+
+void
+SBDebugger::RunCommandInterpreter (bool auto_handle_events,
+ bool spawn_thread,
+ SBCommandInterpreterRunOptions &options,
+ int &num_errors,
+ bool &quit_requested,
+ bool &stopped_for_crash)
+
+{
+ if (m_opaque_sp)
+ {
+ CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
+ interp.RunCommandInterpreter(auto_handle_events, spawn_thread, options.ref());
+ num_errors = interp.GetNumErrors();
+ quit_requested = interp.GetQuitRequested();
+ stopped_for_crash = interp.GetStoppedForCrash();
+ }
}
void
@@ -1186,19 +1208,42 @@ SBDebugger::GetID()
SBError
-SBDebugger::SetCurrentPlatform (const char *platform_name)
+SBDebugger::SetCurrentPlatform (const char *platform_name_cstr)
{
SBError sb_error;
if (m_opaque_sp)
{
- PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref()));
-
- if (platform_sp)
+ if (platform_name_cstr && platform_name_cstr[0])
{
- bool make_selected = true;
- m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
+ ConstString platform_name (platform_name_cstr);
+ PlatformSP platform_sp (Platform::Find (platform_name));
+
+ if (platform_sp)
+ {
+ // Already have a platform with this name, just select it
+ m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
+ }
+ else
+ {
+ // We don't have a platform by this name yet, create one
+ platform_sp = Platform::Create (platform_name, sb_error.ref());
+ if (platform_sp)
+ {
+ // We created the platform, now append and select it
+ bool make_selected = true;
+ m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
+ }
+ }
+ }
+ else
+ {
+ sb_error.ref().SetErrorString("invalid platform name");
}
}
+ else
+ {
+ sb_error.ref().SetErrorString("invalid debugger");
+ }
return sb_error;
}
diff --git a/source/API/SBEvent.cpp b/source/API/SBEvent.cpp
index 57a699fd739d..c62c495b87c8 100644
--- a/source/API/SBEvent.cpp
+++ b/source/API/SBEvent.cpp
@@ -43,6 +43,12 @@ SBEvent::SBEvent (EventSP &event_sp) :
{
}
+SBEvent::SBEvent (Event *event_ptr) :
+ m_event_sp (),
+ m_opaque_ptr (event_ptr)
+{
+}
+
SBEvent::SBEvent (const SBEvent &rhs) :
m_event_sp (rhs.m_event_sp),
m_opaque_ptr (rhs.m_opaque_ptr)
diff --git a/source/API/SBExecutionContext.cpp b/source/API/SBExecutionContext.cpp
new file mode 100644
index 000000000000..dc20c6092132
--- /dev/null
+++ b/source/API/SBExecutionContext.cpp
@@ -0,0 +1,129 @@
+//===-- SBExecutionContext.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBExecutionContext.h"
+
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBFrame.h"
+
+#include "lldb/Target/ExecutionContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBExecutionContext::SBExecutionContext() :
+m_exe_ctx_sp()
+{
+}
+
+SBExecutionContext::SBExecutionContext (const lldb::SBExecutionContext &rhs) :
+m_exe_ctx_sp(rhs.m_exe_ctx_sp)
+{
+}
+
+SBExecutionContext::SBExecutionContext (lldb::ExecutionContextRefSP exe_ctx_ref_sp) :
+m_exe_ctx_sp(exe_ctx_ref_sp)
+{
+}
+
+SBExecutionContext::SBExecutionContext (const lldb::SBTarget &target) :
+m_exe_ctx_sp(new ExecutionContextRef())
+{
+ m_exe_ctx_sp->SetTargetSP(target.GetSP());
+}
+
+SBExecutionContext::SBExecutionContext (const lldb::SBProcess &process) :
+m_exe_ctx_sp(new ExecutionContextRef())
+{
+ m_exe_ctx_sp->SetProcessSP(process.GetSP());
+}
+
+SBExecutionContext::SBExecutionContext (lldb::SBThread thread) :
+m_exe_ctx_sp(new ExecutionContextRef())
+{
+ m_exe_ctx_sp->SetThreadPtr(thread.get());
+}
+
+SBExecutionContext::SBExecutionContext (const lldb::SBFrame &frame) :
+m_exe_ctx_sp(new ExecutionContextRef())
+{
+ m_exe_ctx_sp->SetFrameSP(frame.GetFrameSP());
+}
+
+SBExecutionContext::~SBExecutionContext()
+{
+}
+
+const SBExecutionContext &
+SBExecutionContext::operator = (const lldb::SBExecutionContext &rhs)
+{
+ m_exe_ctx_sp = rhs.m_exe_ctx_sp;
+ return *this;
+}
+
+ExecutionContextRef *
+SBExecutionContext::get () const
+{
+ return m_exe_ctx_sp.get();
+}
+
+SBTarget
+SBExecutionContext::GetTarget () const
+{
+ SBTarget sb_target;
+ if (m_exe_ctx_sp)
+ {
+ TargetSP target_sp(m_exe_ctx_sp->GetTargetSP());
+ if (target_sp)
+ sb_target.SetSP(target_sp);
+ }
+ return sb_target;
+}
+
+SBProcess
+SBExecutionContext::GetProcess () const
+{
+ SBProcess sb_process;
+ if (m_exe_ctx_sp)
+ {
+ ProcessSP process_sp(m_exe_ctx_sp->GetProcessSP());
+ if (process_sp)
+ sb_process.SetSP(process_sp);
+ }
+ return sb_process;
+}
+
+SBThread
+SBExecutionContext::GetThread () const
+{
+ SBThread sb_thread;
+ if (m_exe_ctx_sp)
+ {
+ ThreadSP thread_sp(m_exe_ctx_sp->GetThreadSP());
+ if (thread_sp)
+ sb_thread.SetThread(thread_sp);
+ }
+ return sb_thread;
+}
+
+SBFrame
+SBExecutionContext::GetFrame () const
+{
+ SBFrame sb_frame;
+ if (m_exe_ctx_sp)
+ {
+ StackFrameSP frame_sp(m_exe_ctx_sp->GetFrameSP());
+ if (frame_sp)
+ sb_frame.SetFrameSP(frame_sp);
+ }
+ return sb_frame;
+}
+
diff --git a/source/API/SBFunction.cpp b/source/API/SBFunction.cpp
index 3d185da17f26..bf5e9180a437 100644
--- a/source/API/SBFunction.cpp
+++ b/source/API/SBFunction.cpp
@@ -227,5 +227,15 @@ SBFunction::GetBlock ()
return sb_block;
}
+lldb::LanguageType
+SBFunction::GetLanguage ()
+{
+ if (m_opaque_ptr)
+ {
+ if (m_opaque_ptr->GetCompileUnit())
+ return m_opaque_ptr->GetCompileUnit()->GetLanguage();
+ }
+ return lldb::eLanguageTypeUnknown;
+}
diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp
index ec1e2f2e9cba..008ca4d9672e 100644
--- a/source/API/SBHostOS.cpp
+++ b/source/API/SBHostOS.cpp
@@ -13,6 +13,9 @@
#include "lldb/Core/Log.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/HostNativeThread.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ThreadLauncher.h"
using namespace lldb;
using namespace lldb_private;
@@ -69,31 +72,54 @@ SBHostOS::ThreadCreate
// FIXME: You should log the return value?
- return Host::ThreadCreate (name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL);
+ HostThread thread(ThreadLauncher::LaunchThread(name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL));
+ return thread.Release();
}
void
SBHostOS::ThreadCreated (const char *name)
{
- Host::ThreadCreated (name);
}
bool
SBHostOS::ThreadCancel (lldb::thread_t thread, SBError *error_ptr)
{
- return Host::ThreadCancel (thread, error_ptr ? error_ptr->get() : NULL);
+ Error error;
+ HostThread host_thread(thread);
+ error = host_thread.Cancel();
+ if (error_ptr)
+ error_ptr->SetError(error);
+ host_thread.Release();
+ return error.Success();
}
bool
SBHostOS::ThreadDetach (lldb::thread_t thread, SBError *error_ptr)
{
- return Host::ThreadDetach (thread, error_ptr ? error_ptr->get() : NULL);
+ Error error;
+#if defined(_WIN32)
+ if (error_ptr)
+ error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
+#else
+ HostThread host_thread(thread);
+ error = host_thread.GetNativeThread().Detach();
+ if (error_ptr)
+ error_ptr->SetError(error);
+ host_thread.Release();
+#endif
+ return error.Success();
}
bool
SBHostOS::ThreadJoin (lldb::thread_t thread, lldb::thread_result_t *result, SBError *error_ptr)
{
- return Host::ThreadJoin (thread, result, error_ptr ? error_ptr->get() : NULL);
+ Error error;
+ HostThread host_thread(thread);
+ error = host_thread.Join(result);
+ if (error_ptr)
+ error_ptr->SetError(error);
+ host_thread.Release();
+ return error.Success();
}
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index 2334cc0d124a..eccc4e29aadf 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -20,6 +20,7 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
@@ -170,9 +171,15 @@ SBInstruction::GetDescription (lldb::SBStream &s)
{
if (m_opaque_sp)
{
+ SymbolContext sc;
+ const Address &addr = m_opaque_sp->GetAddress();
+ ModuleSP module_sp (addr.GetModule());
+ if (module_sp)
+ module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
// Use the "ref()" instead of the "get()" accessor in case the SBStream
// didn't have a stream already created, one will get created...
- m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL);
+ const char *disassemble_format = "${addr-file-or-load}: ";
+ m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, disassemble_format);
return true;
}
return false;
@@ -186,8 +193,14 @@ SBInstruction::Print (FILE *out)
if (m_opaque_sp)
{
+ SymbolContext sc;
+ const Address &addr = m_opaque_sp->GetAddress();
+ ModuleSP module_sp (addr.GetModule());
+ if (module_sp)
+ module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
StreamFile out_stream (out, false);
- m_opaque_sp->Dump (&out_stream, 0, true, false, NULL);
+ const char *disassemble_format = "${addr-file-or-load}: ";
+ m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, disassemble_format);
}
}
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index fe22d9c29e4a..31585b3e6868 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -11,7 +11,9 @@
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/SymbolContext.h"
using namespace lldb;
using namespace lldb_private;
@@ -100,12 +102,24 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
// exist already inside description...
Stream &sref = description.ref();
const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
+ const char *disassemble_format = "${addr-file-or-load}: ";
+ SymbolContext sc;
+ SymbolContext prev_sc;
for (size_t i=0; i<num_instructions; ++i)
{
Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst == NULL)
break;
- inst->Dump (&sref, max_opcode_byte_size, true, false, NULL);
+
+ const Address &addr = inst->GetAddress();
+ prev_sc = sc;
+ ModuleSP module_sp (addr.GetModule());
+ if (module_sp)
+ {
+ module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
+ }
+
+ inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, disassemble_format);
sref.EOL();
}
return true;
diff --git a/source/API/SBListener.cpp b/source/API/SBListener.cpp
index bad9ba82bc91..87318739a3a4 100644
--- a/source/API/SBListener.cpp
+++ b/source/API/SBListener.cpp
@@ -69,6 +69,12 @@ SBListener::SBListener (Listener &listener) :
{
}
+SBListener::SBListener (const lldb::ListenerSP &listener_sp) :
+ m_opaque_sp (listener_sp),
+ m_opaque_ptr (listener_sp.get())
+{
+}
+
SBListener::~SBListener ()
{
}
diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp
index 9914852cead7..d3e769ae675b 100644
--- a/source/API/SBPlatform.cpp
+++ b/source/API/SBPlatform.cpp
@@ -269,7 +269,8 @@ SBPlatform::SBPlatform (const char *platform_name) :
m_opaque_sp ()
{
Error error;
- m_opaque_sp = Platform::Create (platform_name, error);
+ if (platform_name && platform_name[0])
+ m_opaque_sp = Platform::Create (ConstString(platform_name), error);
}
SBPlatform::~SBPlatform()
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index 41efd86177d6..9a0b23bc93d2 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -38,6 +38,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBThread.h"
+#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBUnixSignals.h"
@@ -738,18 +739,10 @@ SBProcess::Continue ()
{
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
- Error error (process_sp->Resume());
- if (error.Success())
- {
- if (process_sp->GetTarget().GetDebugger().GetAsyncExecution () == false)
- {
- if (log)
- log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...",
- static_cast<void*>(process_sp.get()));
- process_sp->WaitForProcessToStop (NULL);
- }
- }
- sb_error.SetError(error);
+ if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ())
+ sb_error.ref() = process_sp->Resume ();
+ else
+ sb_error.ref() = process_sp->ResumeSynchronous (NULL);
}
else
sb_error.SetErrorString ("SBProcess is invalid");
@@ -1381,3 +1374,30 @@ SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx)
}
return NULL;
}
+
+SBThreadCollection
+SBProcess::GetHistoryThreads (addr_t addr)
+{
+ ProcessSP process_sp(GetSP());
+ SBThreadCollection threads;
+ if (process_sp)
+ {
+ threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
+ }
+ return threads;
+}
+
+bool
+SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type)
+{
+ ProcessSP process_sp(GetSP());
+ if (! process_sp)
+ return false;
+
+ InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type);
+
+ if (! runtime_sp.get())
+ return false;
+
+ return runtime_sp->IsActive();
+}
diff --git a/source/API/SBSection.cpp b/source/API/SBSection.cpp
index 3fb84e81465c..809eca60c683 100644
--- a/source/API/SBSection.cpp
+++ b/source/API/SBSection.cpp
@@ -250,6 +250,14 @@ SBSection::GetSectionType ()
return eSectionTypeInvalid;
}
+uint32_t
+SBSection::GetTargetByteSize ()
+{
+ SectionSP section_sp (GetSP());
+ if (section_sp.get())
+ return section_sp->GetTargetByteSize();
+ return 0;
+}
bool
SBSection::operator == (const SBSection &rhs)
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 3d5828c5fe00..b87b1acf45df 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -58,6 +58,7 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "../source/Commands/CommandObjectBreakpoint.h"
+#include "llvm/Support/Regex.h"
using namespace lldb;
@@ -132,6 +133,18 @@ SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg)
m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
}
+SBListener
+SBLaunchInfo::GetListener ()
+{
+ return SBListener(m_opaque_sp->GetListener());
+}
+
+void
+SBLaunchInfo::SetListener (SBListener &listener)
+{
+ m_opaque_sp->SetListener(listener.GetSP());
+}
+
uint32_t
SBLaunchInfo::GetNumArguments ()
{
@@ -235,13 +248,16 @@ SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
const char *
SBLaunchInfo::GetShell ()
{
- return m_opaque_sp->GetShell();
+ // Constify this string so that it is saved in the string pool. Otherwise
+ // it would be freed when this function goes out of scope.
+ ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
+ return shell.AsCString();
}
void
SBLaunchInfo::SetShell (const char * path)
{
- m_opaque_sp->SetShell (path);
+ m_opaque_sp->SetShell (FileSpec(path, false));
}
uint32_t
@@ -516,6 +532,17 @@ SBAttachInfo::ParentProcessIDIsValid()
return m_opaque_sp->ParentProcessIDIsValid();
}
+SBListener
+SBAttachInfo::GetListener ()
+{
+ return SBListener(m_opaque_sp->GetListener());
+}
+
+void
+SBAttachInfo::SetListener (SBListener &listener)
+{
+ m_opaque_sp->SetListener(listener.GetSP());
+}
//----------------------------------------------------------------------
// SBTarget constructor
@@ -583,6 +610,19 @@ SBTarget::GetProcess ()
return sb_process;
}
+SBPlatform
+SBTarget::GetPlatform ()
+{
+ TargetSP target_sp(GetSP());
+ if (!target_sp)
+ return SBPlatform();
+
+ SBPlatform platform;
+ platform.m_opaque_sp = target_sp->GetPlatform();
+
+ return platform;
+}
+
SBDebugger
SBTarget::GetDebugger () const
{
@@ -734,9 +774,9 @@ SBTarget::Launch
launch_info.GetEnvironmentEntries ().SetArguments (envp);
if (listener.IsValid())
- error.SetError (target_sp->Launch(listener.ref(), launch_info));
- else
- error.SetError (target_sp->Launch(target_sp->GetDebugger().GetListener(), launch_info));
+ launch_info.SetListener(listener.GetSP());
+
+ error.SetError (target_sp->Launch(launch_info, NULL));
sb_process.SetSP(target_sp->GetProcessSP());
}
@@ -800,7 +840,7 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
if (arch_spec.IsValid())
launch_info.GetArchitecture () = arch_spec;
- error.SetError (target_sp->Launch (target_sp->GetDebugger().GetListener(), launch_info));
+ error.SetError (target_sp->Launch (launch_info, NULL));
sb_process.SetSP(target_sp->GetProcessSP());
}
else
@@ -1000,7 +1040,7 @@ SBTarget::AttachToProcessWithID
// If we are doing synchronous mode, then wait for the
// process to stop!
if (target_sp->GetDebugger().GetAsyncExecution () == false)
- process_sp->WaitForProcessToStop (NULL);
+ process_sp->WaitForProcessToStop (NULL);
}
}
else
@@ -1227,6 +1267,22 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
return sb_addr;
}
+lldb::SBAddress
+SBTarget::ResolveFileAddress (lldb::addr_t file_addr)
+{
+ lldb::SBAddress sb_addr;
+ Address &addr = sb_addr.ref();
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ if (target_sp->ResolveFileAddress (file_addr, addr))
+ return sb_addr;
+ }
+
+ addr.SetRawAddress(file_addr);
+ return sb_addr;
+}
lldb::SBAddress
SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
@@ -1261,6 +1317,27 @@ SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr,
return sc;
}
+size_t
+SBTarget::ReadMemory (const SBAddress addr,
+ void *buf,
+ size_t size,
+ lldb::SBError &error)
+{
+ SBError sb_error;
+ size_t bytes_read = 0;
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ bytes_read = target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
+ }
+ else
+ {
+ sb_error.SetErrorString("invalid target");
+ }
+
+ return bytes_read;
+}
SBBreakpoint
SBTarget::BreakpointCreateByLocation (const char *file,
@@ -1868,30 +1945,10 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type)
lldb::ValueObjectSP new_value_sp;
if (IsValid() && name && *name && addr.IsValid() && type.IsValid())
{
- lldb::addr_t address(addr.GetLoadAddress(*this));
- lldb::TypeImplSP type_impl_sp (type.GetSP());
- ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType(true).GetPointerType ());
- if (pointer_ast_type)
- {
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
-
- ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
- ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- pointer_ast_type,
- ConstString(name),
- buffer,
- exe_ctx.GetByteOrder(),
- exe_ctx.GetAddressByteSize()));
-
- if (ptr_result_valobj_sp)
- {
- ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
- Error err;
- new_value_sp = ptr_result_valobj_sp->Dereference(err);
- if (new_value_sp)
- new_value_sp->SetName(ConstString(name));
- }
- }
+ lldb::addr_t load_addr(addr.GetLoadAddress(*this));
+ ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
+ ClangASTType ast_type(type.GetSP()->GetClangASTType(true));
+ new_value_sp = ValueObject::CreateValueObjectFromAddress(name, load_addr, exe_ctx, ast_type);
}
sb_value.SetSP(new_value_sp);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -1908,6 +1965,58 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type)
return sb_value;
}
+lldb::SBValue
+SBTarget::CreateValueFromData (const char *name, lldb::SBData data, lldb::SBType type)
+{
+ SBValue sb_value;
+ lldb::ValueObjectSP new_value_sp;
+ if (IsValid() && name && *name && data.IsValid() && type.IsValid())
+ {
+ DataExtractorSP extractor(*data);
+ ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
+ ClangASTType ast_type(type.GetSP()->GetClangASTType(true));
+ new_value_sp = ValueObject::CreateValueObjectFromData(name, *extractor, exe_ctx, ast_type);
+ }
+ sb_value.SetSP(new_value_sp);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ {
+ if (new_value_sp)
+ log->Printf ("SBTarget(%p)::CreateValueFromData => \"%s\"",
+ static_cast<void*>(m_opaque_sp.get()),
+ new_value_sp->GetName().AsCString());
+ else
+ log->Printf ("SBTarget(%p)::CreateValueFromData => NULL",
+ static_cast<void*>(m_opaque_sp.get()));
+ }
+ return sb_value;
+}
+
+lldb::SBValue
+SBTarget::CreateValueFromExpression (const char *name, const char* expr)
+{
+ SBValue sb_value;
+ lldb::ValueObjectSP new_value_sp;
+ if (IsValid() && name && *name && expr && *expr)
+ {
+ ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false)));
+ new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expr, exe_ctx);
+ }
+ sb_value.SetSP(new_value_sp);
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ {
+ if (new_value_sp)
+ log->Printf ("SBTarget(%p)::CreateValueFromExpression => \"%s\"",
+ static_cast<void*>(m_opaque_sp.get()),
+ new_value_sp->GetName().AsCString());
+ else
+ log->Printf ("SBTarget(%p)::CreateValueFromExpression => NULL",
+ static_cast<void*>(m_opaque_sp.get()));
+ }
+ return sb_value;
+}
+
bool
SBTarget::DeleteAllWatchpoints ()
{
@@ -2057,6 +2166,28 @@ SBTarget::GetTriple ()
}
uint32_t
+SBTarget::GetDataByteSize ()
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ return target_sp->GetArchitecture().GetDataByteSize() ;
+ }
+ return 0;
+}
+
+uint32_t
+SBTarget::GetCodeByteSize ()
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ return target_sp->GetArchitecture().GetCodeByteSize() ;
+ }
+ return 0;
+}
+
+uint32_t
SBTarget::GetAddressByteSize()
{
TargetSP target_sp(GetSP());
@@ -2154,6 +2285,34 @@ SBTarget::FindFunctions (const char *name, uint32_t name_type_mask)
return sb_sc_list;
}
+lldb::SBSymbolContextList
+SBTarget::FindGlobalFunctions(const char *name, uint32_t max_matches, MatchType matchtype)
+{
+ lldb::SBSymbolContextList sb_sc_list;
+ if (name && name[0])
+ {
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ std::string regexstr;
+ switch (matchtype)
+ {
+ case eMatchTypeRegex:
+ target_sp->GetImages().FindFunctions(RegularExpression(name), true, true, true, *sb_sc_list);
+ break;
+ case eMatchTypeStartsWith:
+ regexstr = llvm::Regex::escape(name) + ".*";
+ target_sp->GetImages().FindFunctions(RegularExpression(regexstr.c_str()), true, true, true, *sb_sc_list);
+ break;
+ default:
+ target_sp->GetImages().FindFunctions(ConstString(name), eFunctionNameTypeAny, true, true, true, *sb_sc_list);
+ break;
+ }
+ }
+ }
+ return sb_sc_list;
+}
+
lldb::SBType
SBTarget::FindFirstType (const char* typename_cstr)
{
@@ -2188,14 +2347,19 @@ SBTarget::FindFirstType (const char* typename_cstr)
if (objc_language_runtime)
{
- TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
+ DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();
- if (objc_type_vendor)
+ if (objc_decl_vendor)
{
- std::vector <ClangASTType> types;
+ std::vector <clang::NamedDecl *> decls;
- if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0)
- return SBType(types[0]);
+ if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0)
+ {
+ if (ClangASTType type = ClangASTContext::GetTypeForDecl(decls[0]))
+ {
+ return SBType(type);
+ }
+ }
}
}
}
@@ -2261,17 +2425,20 @@ SBTarget::FindTypes (const char* typename_cstr)
if (objc_language_runtime)
{
- TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
+ DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor();
- if (objc_type_vendor)
+ if (objc_decl_vendor)
{
- std::vector <ClangASTType> types;
+ std::vector <clang::NamedDecl *> decls;
- if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types))
+ if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0)
{
- for (ClangASTType &type : types)
+ for (clang::NamedDecl *decl : decls)
{
- sb_type_list.Append(SBType(type));
+ if (ClangASTType type = ClangASTContext::GetTypeForDecl(decl))
+ {
+ sb_type_list.Append(SBType(type));
+ }
}
}
}
@@ -2321,6 +2488,61 @@ SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
return sb_value_list;
}
+SBValueList
+SBTarget::FindGlobalVariables(const char *name, uint32_t max_matches, MatchType matchtype)
+{
+ SBValueList sb_value_list;
+
+ TargetSP target_sp(GetSP());
+ if (name && target_sp)
+ {
+ VariableList variable_list;
+ const bool append = true;
+
+ std::string regexstr;
+ uint32_t match_count;
+ switch (matchtype)
+ {
+ case eMatchTypeNormal:
+ match_count = target_sp->GetImages().FindGlobalVariables(ConstString(name),
+ append,
+ max_matches,
+ variable_list);
+ break;
+ case eMatchTypeRegex:
+ match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(name),
+ append,
+ max_matches,
+ variable_list);
+ break;
+ case eMatchTypeStartsWith:
+ regexstr = llvm::Regex::escape(name) + ".*";
+ match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr.c_str()),
+ append,
+ max_matches,
+ variable_list);
+ break;
+ }
+
+
+ if (match_count > 0)
+ {
+ ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
+ if (exe_scope == NULL)
+ exe_scope = target_sp.get();
+ for (uint32_t i = 0; i<match_count; ++i)
+ {
+ lldb::ValueObjectSP valobj_sp(ValueObjectVariable::Create(exe_scope, variable_list.GetVariableAtIndex(i)));
+ if (valobj_sp)
+ sb_value_list.Append(SBValue(valobj_sp));
+ }
+ }
+ }
+
+ return sb_value_list;
+}
+
+
lldb::SBValue
SBTarget::FindFirstGlobalVariable (const char* name)
{
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index a0bfa4313535..6524d10fb705 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -41,6 +41,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThreadPlan.h"
#include "lldb/API/SBValue.h"
using namespace lldb;
@@ -194,6 +195,7 @@ SBThread::GetStopReasonDataCount ()
case eStopReasonExec:
case eStopReasonPlanComplete:
case eStopReasonThreadExiting:
+ case eStopReasonInstrumentation:
// There is no data for these stop reasons.
return 0;
@@ -254,6 +256,7 @@ SBThread::GetStopReasonDataAtIndex (uint32_t idx)
case eStopReasonExec:
case eStopReasonPlanComplete:
case eStopReasonThreadExiting:
+ case eStopReasonInstrumentation:
// There is no data for these stop reasons.
return 0;
@@ -305,6 +308,26 @@ SBThread::GetStopReasonDataAtIndex (uint32_t idx)
return 0;
}
+bool
+SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
+{
+ Stream &strm = stream.ref();
+
+ ExecutionContext exe_ctx (m_opaque_sp.get());
+ if (! exe_ctx.HasThreadScope())
+ return false;
+
+
+ StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
+ StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
+ if (! info)
+ return false;
+
+ info->Dump(strm);
+
+ return true;
+}
+
size_t
SBThread::GetStopDescription (char *dst, size_t dst_len)
{
@@ -687,15 +710,11 @@ SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
// Why do we need to set the current thread by ID here???
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- sb_error.ref() = process->Resume();
-
- if (sb_error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+
+ if (process->GetTarget().GetDebugger().GetAsyncExecution ())
+ sb_error.ref() = process->Resume ();
+ else
+ sb_error.ref() = process->ResumeSynchronous (NULL);
return sb_error;
}
@@ -918,7 +937,9 @@ SBThread::RunToAddress (lldb::addr_t addr)
Thread *thread = exe_ctx.GetThreadPtr();
- ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
+ ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
+ target_addr,
+ stop_other_threads));
// This returns an error, we should use it!
ResumeNewPlan (exe_ctx, new_plan_sp.get());
@@ -1073,6 +1094,46 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
}
SBError
+SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ SBError sb_error;
+
+ Mutex::Locker api_locker;
+ ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
+
+ if (log)
+ {
+ log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
+ static_cast<void*>(exe_ctx.GetThreadPtr()),
+ script_class_name);
+ }
+
+
+ if (!exe_ctx.HasThreadScope())
+ {
+ sb_error.SetErrorString("this SBThread object is invalid");
+ return sb_error;
+ }
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+ ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
+
+ if (thread_plan_sp)
+ sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
+ else
+ {
+ sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
+ if (log)
+ log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
+ static_cast<void*>(exe_ctx.GetThreadPtr()),
+ script_class_name);
+ }
+
+ return sb_error;
+}
+
+SBError
SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -1473,7 +1534,8 @@ SBThread::GetExtendedBacktraceThread (const char *type)
const char *queue_name = new_thread_sp->GetQueueName();
if (queue_name == NULL)
queue_name = "";
- log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
+ log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
+ "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
static_cast<void*>(exe_ctx.GetThreadPtr()),
static_cast<void*>(new_thread_sp.get()),
new_thread_sp->GetQueueID(),
@@ -1515,3 +1577,24 @@ SBThread::SafeToCallFunctions ()
return thread_sp->SafeToCallFunctions();
return true;
}
+
+lldb_private::Thread *
+SBThread::operator->()
+{
+ ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+ if (thread_sp)
+ return thread_sp.get();
+ else
+ return NULL;
+}
+
+lldb_private::Thread *
+SBThread::get()
+{
+ ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+ if (thread_sp)
+ return thread_sp.get();
+ else
+ return NULL;
+}
+
diff --git a/source/API/SBThreadCollection.cpp b/source/API/SBThreadCollection.cpp
new file mode 100644
index 000000000000..841f93253a53
--- /dev/null
+++ b/source/API/SBThreadCollection.cpp
@@ -0,0 +1,97 @@
+//===-- SBThreadCollection.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBThreadCollection.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/Target/ThreadList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+SBThreadCollection::SBThreadCollection () :
+ m_opaque_sp()
+{
+}
+
+SBThreadCollection::SBThreadCollection(const SBThreadCollection &rhs) :
+ m_opaque_sp (rhs.m_opaque_sp)
+{
+}
+
+const SBThreadCollection &
+SBThreadCollection::operator = (const SBThreadCollection &rhs)
+{
+ if (this != &rhs)
+ m_opaque_sp = rhs.m_opaque_sp;
+ return *this;
+}
+
+SBThreadCollection::SBThreadCollection (const ThreadCollectionSP &threads) :
+ m_opaque_sp(threads)
+{
+}
+
+SBThreadCollection::~SBThreadCollection ()
+{
+}
+
+void
+SBThreadCollection::SetOpaque (const lldb::ThreadCollectionSP &threads)
+{
+ m_opaque_sp = threads;
+}
+
+lldb_private::ThreadCollection *
+SBThreadCollection::get() const
+{
+ return m_opaque_sp.get();
+}
+
+lldb_private::ThreadCollection *
+SBThreadCollection::operator->() const
+{
+ return m_opaque_sp.operator->();
+}
+
+lldb::ThreadCollectionSP &
+SBThreadCollection::operator*()
+{
+ return m_opaque_sp;
+}
+
+const lldb::ThreadCollectionSP &
+SBThreadCollection::operator*() const
+{
+ return m_opaque_sp;
+}
+
+
+bool
+SBThreadCollection::IsValid () const
+{
+ return m_opaque_sp.get() != NULL;
+}
+
+size_t
+SBThreadCollection::GetSize ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetSize();
+ return 0;
+}
+
+SBThread
+SBThreadCollection::GetThreadAtIndex(size_t idx)
+{
+ SBThread thread;
+ if (m_opaque_sp && idx < m_opaque_sp->GetSize())
+ thread = m_opaque_sp->GetThreadAtIndex(idx);
+ return thread;
+}
diff --git a/source/API/SBThreadPlan.cpp b/source/API/SBThreadPlan.cpp
new file mode 100644
index 000000000000..02b1a8d893b6
--- /dev/null
+++ b/source/API/SBThreadPlan.cpp
@@ -0,0 +1,285 @@
+//===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/API/SBThread.h"
+
+#include "lldb/API/SBSymbolContext.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StructuredData.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/SystemRuntime.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Queue.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanPython.h"
+#include "lldb/Target/ThreadPlanStepInstruction.h"
+#include "lldb/Target/ThreadPlanStepOut.h"
+#include "lldb/Target/ThreadPlanStepRange.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
+
+
+#include "lldb/API/SBAddress.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBThreadPlan.h"
+#include "lldb/API/SBValue.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Constructors
+//----------------------------------------------------------------------
+SBThreadPlan::SBThreadPlan ()
+{
+}
+
+SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) :
+ m_opaque_sp (lldb_object_sp)
+{
+}
+
+SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) :
+ m_opaque_sp (rhs.m_opaque_sp)
+{
+
+}
+
+SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name)
+{
+ Thread *thread = sb_thread.get();
+ if (thread)
+ m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name));
+}
+
+//----------------------------------------------------------------------
+// Assignment operator
+//----------------------------------------------------------------------
+
+const lldb::SBThreadPlan &
+SBThreadPlan::operator = (const SBThreadPlan &rhs)
+{
+ if (this != &rhs)
+ m_opaque_sp = rhs.m_opaque_sp;
+ return *this;
+}
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+SBThreadPlan::~SBThreadPlan()
+{
+}
+
+lldb_private::ThreadPlan *
+SBThreadPlan::get()
+{
+ return m_opaque_sp.get();
+}
+
+bool
+SBThreadPlan::IsValid() const
+{
+ return m_opaque_sp.get() != NULL;
+}
+
+void
+SBThreadPlan::Clear ()
+{
+ m_opaque_sp.reset();
+}
+
+lldb::StopReason
+SBThreadPlan::GetStopReason()
+{
+ return eStopReasonNone;
+}
+
+size_t
+SBThreadPlan::GetStopReasonDataCount()
+{
+ return 0;
+}
+
+uint64_t
+SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx)
+{
+ return 0;
+}
+
+SBThread
+SBThreadPlan::GetThread () const
+{
+ if (m_opaque_sp)
+ {
+ return SBThread(m_opaque_sp->GetThread().shared_from_this());
+ }
+ else
+ return SBThread();
+}
+
+bool
+SBThreadPlan::GetDescription (lldb::SBStream &description) const
+{
+ if (m_opaque_sp)
+ {
+ m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
+ }
+ else
+ {
+ description.Printf("Empty SBThreadPlan");
+ }
+ return true;
+}
+
+void
+SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp)
+{
+ m_opaque_sp = lldb_object_sp;
+}
+
+void
+SBThreadPlan::SetPlanComplete (bool success)
+{
+ if (m_opaque_sp)
+ m_opaque_sp->SetPlanComplete (success);
+}
+
+bool
+SBThreadPlan::IsPlanComplete()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->IsPlanComplete();
+ else
+ return true;
+}
+
+bool
+SBThreadPlan::IsValid()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->ValidatePlan(nullptr);
+ else
+ return false;
+}
+
+ // This section allows an SBThreadPlan to push another of the common types of plans...
+ //
+ // FIXME, you should only be able to queue thread plans from inside the methods of a
+ // Scripted Thread Plan. Need a way to enforce that.
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address,
+ lldb::addr_t size)
+{
+ if (m_opaque_sp)
+ {
+ Address *start_address = sb_start_address.get();
+ if (!start_address)
+ {
+ return SBThreadPlan();
+ }
+
+ AddressRange range (*start_address, size);
+ SymbolContext sc;
+ start_address->CalculateSymbolContext(&sc);
+ return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false,
+ range,
+ sc,
+ eAllThreads));
+ }
+ else
+ {
+ return SBThreadPlan();
+ }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address,
+ lldb::addr_t size)
+{
+ if (m_opaque_sp)
+ {
+ Address *start_address = sb_start_address.get();
+ if (!start_address)
+ {
+ return SBThreadPlan();
+ }
+
+ AddressRange range (*start_address, size);
+ SymbolContext sc;
+ start_address->CalculateSymbolContext(&sc);
+ return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false,
+ range,
+ sc,
+ NULL,
+ eAllThreads));
+ }
+ else
+ {
+ return SBThreadPlan();
+ }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn)
+{
+ if (m_opaque_sp)
+ {
+ SymbolContext sc;
+ sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
+ return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false,
+ &sc,
+ first_insn,
+ false,
+ eVoteYes,
+ eVoteNoOpinion,
+ frame_idx_to_step_to));
+ }
+ else
+ {
+ return SBThreadPlan();
+ }
+}
+
+SBThreadPlan
+SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address)
+{
+ if (m_opaque_sp)
+ {
+ Address *address = sb_address.get();
+ if (!address)
+ return SBThreadPlan();
+
+ return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false,
+ *address,
+ false));
+ }
+ else
+ {
+ return SBThreadPlan();
+ }
+}
+
+
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index 064fb32c953f..8a0f5d848a3d 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -156,6 +156,14 @@ SBType::IsPointerType()
}
bool
+SBType::IsArrayType()
+{
+ if (!IsValid())
+ return false;
+ return m_opaque_sp->GetClangASTType(true).IsArrayType(nullptr, nullptr, nullptr);
+}
+
+bool
SBType::IsReferenceType()
{
if (!IsValid())
@@ -204,6 +212,14 @@ SBType::GetDereferencedType()
return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType())));
}
+SBType
+SBType::GetArrayElementType()
+{
+ if (!IsValid())
+ return SBType();
+ return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetClangASTType(true).GetArrayElementType())));
+}
+
bool
SBType::IsFunctionType ()
{
@@ -220,7 +236,13 @@ SBType::IsPolymorphicClass ()
return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass();
}
-
+bool
+SBType::IsTypedefType ()
+{
+ if (!IsValid())
+ return false;
+ return m_opaque_sp->GetClangASTType(true).IsTypedefType();
+}
lldb::SBType
SBType::GetFunctionReturnType ()
@@ -252,6 +274,25 @@ SBType::GetFunctionArgumentTypes ()
return sb_type_list;
}
+uint32_t
+SBType::GetNumberOfMemberFunctions ()
+{
+ if (IsValid())
+ {
+ return m_opaque_sp->GetClangASTType(true).GetNumMemberFunctions();
+ }
+ return 0;
+}
+
+lldb::SBTypeMemberFunction
+SBType::GetMemberFunctionAtIndex (uint32_t idx)
+{
+ SBTypeMemberFunction sb_func_type;
+ if (IsValid())
+ sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx)));
+ return sb_func_type;
+}
+
lldb::SBType
SBType::GetUnqualifiedType()
{
@@ -305,7 +346,7 @@ uint32_t
SBType::GetNumberOfFields ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType(false).GetNumFields();
+ return m_opaque_sp->GetClangASTType(true).GetNumFields();
return 0;
}
@@ -430,6 +471,14 @@ SBType::IsTypeComplete()
return m_opaque_sp->GetClangASTType(false).IsCompleteType();
}
+uint32_t
+SBType::GetTypeFlags ()
+{
+ if (!IsValid())
+ return 0;
+ return m_opaque_sp->GetClangASTType(true).GetTypeInfo();
+}
+
const char*
SBType::GetName()
{
@@ -450,7 +499,7 @@ lldb::TypeClass
SBType::GetTypeClass ()
{
if (IsValid())
- return m_opaque_sp->GetClangASTType(false).GetTypeClass();
+ return m_opaque_sp->GetClangASTType(true).GetTypeClass();
return lldb::eTypeClassInvalid;
}
@@ -684,3 +733,121 @@ SBTypeMember::ref () const
{
return *m_opaque_ap.get();
}
+
+SBTypeMemberFunction::SBTypeMemberFunction() :
+m_opaque_sp()
+{
+}
+
+SBTypeMemberFunction::~SBTypeMemberFunction()
+{
+}
+
+SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) :
+ m_opaque_sp(rhs.m_opaque_sp)
+{
+}
+
+lldb::SBTypeMemberFunction&
+SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs)
+{
+ if (this != &rhs)
+ m_opaque_sp = rhs.m_opaque_sp;
+ return *this;
+}
+
+bool
+SBTypeMemberFunction::IsValid() const
+{
+ return m_opaque_sp.get();
+}
+
+const char *
+SBTypeMemberFunction::GetName ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetName().GetCString();
+ return NULL;
+}
+
+SBType
+SBTypeMemberFunction::GetType ()
+{
+ SBType sb_type;
+ if (m_opaque_sp)
+ {
+ sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
+ }
+ return sb_type;
+}
+
+lldb::SBType
+SBTypeMemberFunction::GetReturnType ()
+{
+ SBType sb_type;
+ if (m_opaque_sp)
+ {
+ sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
+ }
+ return sb_type;
+}
+
+uint32_t
+SBTypeMemberFunction::GetNumberOfArguments ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetNumArguments();
+ return 0;
+}
+
+lldb::SBType
+SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i)
+{
+ SBType sb_type;
+ if (m_opaque_sp)
+ {
+ sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
+ }
+ return sb_type;
+}
+
+lldb::MemberFunctionKind
+SBTypeMemberFunction::GetKind ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetKind();
+ return lldb::eMemberFunctionKindUnknown;
+
+}
+
+bool
+SBTypeMemberFunction::GetDescription (lldb::SBStream &description,
+ lldb::DescriptionLevel description_level)
+{
+ Stream &strm = description.ref();
+
+ if (m_opaque_sp)
+ return m_opaque_sp->GetDescription(strm);
+
+ return false;
+}
+
+void
+SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl)
+{
+ m_opaque_sp.reset(type_member_impl);
+}
+
+TypeMemberFunctionImpl &
+SBTypeMemberFunction::ref ()
+{
+ if (!m_opaque_sp)
+ m_opaque_sp.reset (new TypeMemberFunctionImpl());
+ return *m_opaque_sp.get();
+}
+
+const TypeMemberFunctionImpl &
+SBTypeMemberFunction::ref () const
+{
+ return *m_opaque_sp.get();
+}
diff --git a/source/API/SBTypeSummary.cpp b/source/API/SBTypeSummary.cpp
index aaa09c289cb1..8a235bf50080 100644
--- a/source/API/SBTypeSummary.cpp
+++ b/source/API/SBTypeSummary.cpp
@@ -20,6 +20,103 @@ using namespace lldb_private;
#ifndef LLDB_DISABLE_PYTHON
+SBTypeSummaryOptions::SBTypeSummaryOptions()
+{
+ m_opaque_ap.reset(new TypeSummaryOptions());
+}
+
+SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb::SBTypeSummaryOptions &rhs)
+{
+ if (rhs.m_opaque_ap)
+ m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get()));
+ else
+ m_opaque_ap.reset(new TypeSummaryOptions());
+}
+
+SBTypeSummaryOptions::~SBTypeSummaryOptions ()
+{
+}
+
+bool
+SBTypeSummaryOptions::IsValid()
+{
+ return m_opaque_ap.get();
+}
+
+lldb::LanguageType
+SBTypeSummaryOptions::GetLanguage ()
+{
+ if (IsValid())
+ return m_opaque_ap->GetLanguage();
+ return lldb::eLanguageTypeUnknown;
+}
+
+lldb::TypeSummaryCapping
+SBTypeSummaryOptions::GetCapping ()
+{
+ if (IsValid())
+ return m_opaque_ap->GetCapping();
+ return eTypeSummaryCapped;
+}
+
+void
+SBTypeSummaryOptions::SetLanguage (lldb::LanguageType l)
+{
+ if (IsValid())
+ m_opaque_ap->SetLanguage(l);
+}
+
+void
+SBTypeSummaryOptions::SetCapping (lldb::TypeSummaryCapping c)
+{
+ if (IsValid())
+ m_opaque_ap->SetCapping(c);
+}
+
+lldb_private::TypeSummaryOptions *
+SBTypeSummaryOptions::operator->()
+{
+ return m_opaque_ap.get();
+}
+
+const lldb_private::TypeSummaryOptions *
+SBTypeSummaryOptions::operator->() const
+{
+ return m_opaque_ap.get();
+}
+
+lldb_private::TypeSummaryOptions *
+SBTypeSummaryOptions::get ()
+{
+ return m_opaque_ap.get();
+}
+
+lldb_private::TypeSummaryOptions &
+SBTypeSummaryOptions::ref()
+{
+ return *m_opaque_ap.get();
+}
+
+const lldb_private::TypeSummaryOptions &
+SBTypeSummaryOptions::ref() const
+{
+ return *m_opaque_ap.get();
+}
+
+SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr)
+{
+ SetOptions(lldb_object_ptr);
+}
+
+void
+SBTypeSummaryOptions::SetOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr)
+{
+ if (lldb_object_ptr)
+ m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr));
+ else
+ m_opaque_ap.reset(new TypeSummaryOptions());
+}
+
SBTypeSummary::SBTypeSummary() :
m_opaque_sp()
{
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 3a9621b1e3bc..0d3d7ad956ee 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -543,6 +543,36 @@ SBValue::GetObjectDescription ()
return cstr;
}
+const char *
+SBValue::GetTypeValidatorResult ()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ const char *cstr = NULL;
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (value_sp)
+ {
+ const auto& validation(value_sp->GetValidationStatus());
+ if (TypeValidatorResult::Failure == validation.first)
+ {
+ if (validation.second.empty())
+ cstr = "unknown error";
+ else
+ cstr = validation.second.c_str();
+ }
+ }
+ if (log)
+ {
+ if (cstr)
+ log->Printf ("SBValue(%p)::GetTypeValidatorResult() => \"%s\"",
+ static_cast<void*>(value_sp.get()), cstr);
+ else
+ log->Printf ("SBValue(%p)::GetTypeValidatorResult() => NULL",
+ static_cast<void*>(value_sp.get()));
+ }
+ return cstr;
+}
+
SBType
SBValue::GetType()
{
@@ -610,6 +640,32 @@ SBValue::GetSummary ()
}
return cstr;
}
+
+const char *
+SBValue::GetSummary (lldb::SBStream& stream,
+ lldb::SBTypeSummaryOptions& options)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (value_sp)
+ {
+ std::string buffer;
+ if (value_sp->GetSummaryAsCString(buffer,options.ref()) && !buffer.empty())
+ stream.Printf("%s",buffer.c_str());
+ }
+ const char* cstr = stream.GetData();
+ if (log)
+ {
+ if (cstr)
+ log->Printf ("SBValue(%p)::GetSummary() => \"%s\"",
+ static_cast<void*>(value_sp.get()), cstr);
+ else
+ log->Printf ("SBValue(%p)::GetSummary() => NULL",
+ static_cast<void*>(value_sp.get()));
+ }
+ return cstr;
+}
#endif // LLDB_DISABLE_PYTHON
const char *
@@ -808,21 +864,11 @@ SBValue::CreateValueFromExpression (const char *name, const char *expression, SB
if (value_sp)
{
ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
- Target* target = exe_ctx.GetTargetPtr();
- if (target)
- {
- options.ref().SetKeepInMemory(true);
- target->EvaluateExpression (expression,
- exe_ctx.GetFramePtr(),
- new_value_sp,
- options.ref());
- if (new_value_sp)
- {
- new_value_sp->SetName(ConstString(name));
- sb_value.SetSP(new_value_sp);
- }
- }
+ new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx, options.ref());
+ if (new_value_sp)
+ new_value_sp->SetName(ConstString(name));
}
+ sb_value.SetSP(new_value_sp);
if (log)
{
if (new_value_sp)
@@ -846,30 +892,11 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s
lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
if (value_sp && type_impl_sp)
{
- ClangASTType pointer_ast_type(type_impl_sp->GetClangASTType(false).GetPointerType ());
- if (pointer_ast_type)
- {
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
-
- ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
- ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- pointer_ast_type,
- ConstString(name),
- buffer,
- exe_ctx.GetByteOrder(),
- exe_ctx.GetAddressByteSize()));
-
- if (ptr_result_valobj_sp)
- {
- ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
- Error err;
- new_value_sp = ptr_result_valobj_sp->Dereference(err);
- if (new_value_sp)
- new_value_sp->SetName(ConstString(name));
- }
- sb_value.SetSP(new_value_sp);
- }
+ ClangASTType ast_type(type_impl_sp->GetClangASTType(true));
+ ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
+ new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, ast_type);
}
+ sb_value.SetSP(new_value_sp);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
@@ -894,15 +921,10 @@ SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
if (value_sp)
{
ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
-
- new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- type.m_opaque_sp->GetClangASTType(false),
- ConstString(name),
- *data.m_opaque_sp,
- LLDB_INVALID_ADDRESS);
+ new_value_sp = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type.GetSP()->GetClangASTType(true));
new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
- sb_value.SetSP(new_value_sp);
}
+ sb_value.SetSP(new_value_sp);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
@@ -1836,3 +1858,16 @@ SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &er
sb_watchpoint = Dereference().Watch (resolve_location, read, write, error);
return sb_watchpoint;
}
+
+lldb::SBValue
+SBValue::Persist ()
+{
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ SBValue persisted_sb;
+ if (value_sp)
+ {
+ persisted_sb.SetSP(value_sp->Persist());
+ }
+ return persisted_sb;
+}
diff --git a/source/API/SBValueList.cpp b/source/API/SBValueList.cpp
index 5069ed3f5624..71fabe0dfc0a 100644
--- a/source/API/SBValueList.cpp
+++ b/source/API/SBValueList.cpp
@@ -78,6 +78,21 @@ public:
}
return lldb::SBValue();
}
+
+ lldb::SBValue
+ GetFirstValueByName (const char* name) const
+ {
+ if (name)
+ {
+ for (auto val : m_values)
+ {
+ if (val.IsValid() && val.GetName() &&
+ strcmp(name,val.GetName()) == 0)
+ return val;
+ }
+ }
+ return lldb::SBValue();
+ }
private:
std::vector<lldb::SBValue> m_values;
@@ -261,6 +276,15 @@ SBValueList::FindValueObjectByUID (lldb::user_id_t uid)
return sb_value;
}
+SBValue
+SBValueList::GetFirstValueByName (const char* name) const
+{
+ SBValue sb_value;
+ if (m_opaque_ap.get())
+ sb_value = m_opaque_ap->GetFirstValueByName(name);
+ return sb_value;
+}
+
void *
SBValueList::opaque_ptr ()
{
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 7d08170e4aed..bc269cdb95ac 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -20,11 +20,14 @@
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
@@ -62,6 +65,20 @@ Breakpoint::Breakpoint(Target &target,
m_being_created = false;
}
+Breakpoint::Breakpoint (Target &new_target, Breakpoint &source_bp) :
+ m_being_created(true),
+ m_hardware(source_bp.m_hardware),
+ m_target(new_target),
+ m_name_list (source_bp.m_name_list),
+ m_options (source_bp.m_options),
+ m_locations(*this),
+ m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols)
+{
+ // Now go through and copy the filter & resolver:
+ m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this);
+ m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this);
+}
+
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
@@ -69,24 +86,16 @@ Breakpoint::~Breakpoint()
{
}
-bool
-Breakpoint::IsInternal () const
-{
- return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
-}
-
-
-
-Target&
-Breakpoint::GetTarget ()
+const lldb::TargetSP
+Breakpoint::GetTargetSP ()
{
- return m_target;
+ return m_target.shared_from_this();
}
-const Target&
-Breakpoint::GetTarget () const
+bool
+Breakpoint::IsInternal () const
{
- return m_target;
+ return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
}
BreakpointLocationSP
@@ -349,10 +358,41 @@ Breakpoint::ResolveBreakpoint ()
}
void
-Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
+Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, BreakpointLocationCollection &new_locations)
+{
+ m_locations.StartRecordingNewLocations(new_locations);
+
+ m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
+
+ m_locations.StopRecordingNewLocations();
+}
+
+void
+Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, bool send_event)
{
if (m_resolver_sp)
- m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
+ {
+ // If this is not an internal breakpoint, set up to record the new locations, then dispatch
+ // an event with the new locations.
+ if (!IsInternal() && send_event)
+ {
+ BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
+ shared_from_this());
+
+ ResolveBreakpointInModules (module_list, new_locations_event->GetBreakpointLocationCollection());
+
+ if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
+ {
+ SendBreakpointChangedEvent (new_locations_event);
+ }
+ else
+ delete new_locations_event;
+ }
+ else
+ {
+ m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
+ }
+ }
}
void
@@ -368,6 +408,11 @@ 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);
+
Mutex::Locker modules_mutex(module_list.GetMutex());
if (load)
{
@@ -383,32 +428,27 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca
// them after the locations pass. Have to do it this way because
// resolving breakpoints will add new locations potentially.
- const size_t num_locs = m_locations.GetSize();
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++)
+ for (ModuleSP module_sp : module_list.ModulesNoLocking())
{
bool seen = false;
- ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
if (!m_filter_sp->ModulePasses (module_sp))
continue;
- for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
+ for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations())
{
- BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
- if (!break_loc->IsEnabled())
+ if (!break_loc_sp->IsEnabled())
continue;
- SectionSP section_sp (break_loc->GetAddress().GetSection());
+ SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
if (!section_sp || section_sp->GetModule() == module_sp)
{
if (!seen)
seen = true;
- if (!break_loc->ResolveBreakpointSite())
+ if (!break_loc_sp->ResolveBreakpointSite())
{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
if (log)
log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
- break_loc->GetID(), GetID());
+ break_loc_sp->GetID(), GetID());
}
}
}
@@ -420,28 +460,7 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca
if (new_modules.GetSize() > 0)
{
- // If this is not an internal breakpoint, set up to record the new locations, then dispatch
- // an event with the new locations.
- if (!IsInternal())
- {
- BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
- shared_from_this());
-
- m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
-
- ResolveBreakpointInModules(new_modules);
-
- m_locations.StopRecordingNewLocations();
- if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
- {
- SendBreakpointChangedEvent (new_locations_event);
- }
- else
- delete new_locations_event;
- }
- else
- ResolveBreakpointInModules(new_modules);
-
+ ResolveBreakpointInModules(new_modules);
}
}
else
@@ -498,21 +517,251 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca
}
}
+namespace
+{
+static bool
+SymbolContextsMightBeEquivalent(SymbolContext &old_sc, SymbolContext &new_sc)
+{
+ bool equivalent_scs = false;
+
+ if (old_sc.module_sp.get() == new_sc.module_sp.get())
+ {
+ // If these come from the same module, we can directly compare the pointers:
+ if (old_sc.comp_unit && new_sc.comp_unit
+ && (old_sc.comp_unit == new_sc.comp_unit))
+ {
+ if (old_sc.function && new_sc.function
+ && (old_sc.function == new_sc.function))
+ {
+ equivalent_scs = true;
+ }
+ }
+ else if (old_sc.symbol && new_sc.symbol
+ && (old_sc.symbol == new_sc.symbol))
+ {
+ equivalent_scs = true;
+ }
+ }
+ else
+ {
+ // Otherwise we will compare by name...
+ if (old_sc.comp_unit && new_sc.comp_unit)
+ {
+ if (FileSpec::Equal(*old_sc.comp_unit, *new_sc.comp_unit, true))
+ {
+ // Now check the functions:
+ if (old_sc.function && new_sc.function
+ && (old_sc.function->GetName() == new_sc.function->GetName()))
+ {
+ equivalent_scs = true;
+ }
+ }
+ }
+ else if (old_sc.symbol && new_sc.symbol)
+ {
+ if (Mangled::Compare(old_sc.symbol->GetMangled(), new_sc.symbol->GetMangled()) == 0)
+ {
+ equivalent_scs = true;
+ }
+ }
+ }
+ return equivalent_scs;
+}
+}
+
void
Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
{
- ModuleList temp_list;
- temp_list.Append (new_module_sp);
- ModulesChanged (temp_list, true);
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("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;
+ for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations())
+ {
+ SectionSP section_sp = break_loc_sp->GetAddress().GetSection();
+ if (section_sp && section_sp->GetModule() == old_module_sp)
+ {
+ old_break_locs.Add(break_loc_sp);
+ }
+ }
+
+ size_t num_old_locations = old_break_locs.GetSize();
+
+ if (num_old_locations == 0)
+ {
+ // There were no locations in the old module, so we just need to check if there were any in the new module.
+ ModuleList temp_list;
+ temp_list.Append (new_module_sp);
+ ResolveBreakpointInModules(temp_list);
+ }
+ else
+ {
+ // First search the new module for locations.
+ // Then compare this with the old list, copy over locations that "look the same"
+ // Then delete the old locations.
+ // Finally remember to post the creation event.
+ //
+ // Two locations are the same if they have the same comp unit & function (by name) and there are the same number
+ // of locations in the old function as in the new one.
+
+ ModuleList temp_list;
+ temp_list.Append (new_module_sp);
+ BreakpointLocationCollection new_break_locs;
+ ResolveBreakpointInModules(temp_list, new_break_locs);
+ BreakpointLocationCollection locations_to_remove;
+ BreakpointLocationCollection locations_to_announce;
+
+ size_t num_new_locations = new_break_locs.GetSize();
+
+ if (num_new_locations > 0)
+ {
+ // Break out the case of one location -> one location since that's the most common one, and there's no need
+ // to build up the structures needed for the merge in that case.
+ if (num_new_locations == 1 && num_old_locations == 1)
+ {
+ bool equivalent_locations = false;
+ SymbolContext old_sc, new_sc;
+ // The only way the old and new location can be equivalent is if they have the same amount of information:
+ BreakpointLocationSP old_loc_sp = old_break_locs.GetByIndex(0);
+ BreakpointLocationSP new_loc_sp = new_break_locs.GetByIndex(0);
+
+ if (old_loc_sp->GetAddress().CalculateSymbolContext(&old_sc)
+ == new_loc_sp->GetAddress().CalculateSymbolContext(&new_sc))
+ {
+ equivalent_locations = SymbolContextsMightBeEquivalent(old_sc, new_sc);
+ }
+
+ if (equivalent_locations)
+ {
+ m_locations.SwapLocation (old_loc_sp, new_loc_sp);
+ }
+ else
+ {
+ locations_to_remove.Add(old_loc_sp);
+ locations_to_announce.Add(new_loc_sp);
+ }
+ }
+ else
+ {
+ //We don't want to have to keep computing the SymbolContexts for these addresses over and over,
+ // so lets get them up front:
+
+ typedef std::map<lldb::break_id_t, SymbolContext> IDToSCMap;
+ IDToSCMap old_sc_map;
+ for (size_t idx = 0; idx < num_old_locations; idx++)
+ {
+ SymbolContext sc;
+ BreakpointLocationSP bp_loc_sp = old_break_locs.GetByIndex(idx);
+ lldb::break_id_t loc_id = bp_loc_sp->GetID();
+ bp_loc_sp->GetAddress().CalculateSymbolContext(&old_sc_map[loc_id]);
+ }
+
+ std::map<lldb::break_id_t, SymbolContext> new_sc_map;
+ for (size_t idx = 0; idx < num_new_locations; idx++)
+ {
+ SymbolContext sc;
+ BreakpointLocationSP bp_loc_sp = new_break_locs.GetByIndex(idx);
+ lldb::break_id_t loc_id = bp_loc_sp->GetID();
+ bp_loc_sp->GetAddress().CalculateSymbolContext(&new_sc_map[loc_id]);
+ }
+ // Take an element from the old Symbol Contexts
+ while (old_sc_map.size() > 0)
+ {
+ lldb::break_id_t old_id = old_sc_map.begin()->first;
+ SymbolContext &old_sc = old_sc_map.begin()->second;
+
+ // Count the number of entries equivalent to this SC for the old list:
+ std::vector<lldb::break_id_t> old_id_vec;
+ old_id_vec.push_back(old_id);
+
+ IDToSCMap::iterator tmp_iter;
+ for (tmp_iter = ++old_sc_map.begin(); tmp_iter != old_sc_map.end(); tmp_iter++)
+ {
+ if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second))
+ old_id_vec.push_back (tmp_iter->first);
+ }
+
+ // Now find all the equivalent locations in the new list.
+ std::vector<lldb::break_id_t> new_id_vec;
+ for (tmp_iter = new_sc_map.begin(); tmp_iter != new_sc_map.end(); tmp_iter++)
+ {
+ if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second))
+ new_id_vec.push_back(tmp_iter->first);
+ }
+
+ // Alright, if we have the same number of potentially equivalent locations in the old
+ // and new modules, we'll just map them one to one in ascending ID order (assuming the
+ // resolver's order would match the equivalent ones.
+ // Otherwise, we'll dump all the old ones, and just take the new ones, erasing the elements
+ // from both maps as we go.
+
+ if (old_id_vec.size() == new_id_vec.size())
+ {
+ sort(old_id_vec.begin(), old_id_vec.end());
+ sort(new_id_vec.begin(), new_id_vec.end());
+ size_t num_elements = old_id_vec.size();
+ for (size_t idx = 0; idx < num_elements; idx++)
+ {
+ BreakpointLocationSP old_loc_sp = old_break_locs.FindByIDPair(GetID(), old_id_vec[idx]);
+ BreakpointLocationSP new_loc_sp = new_break_locs.FindByIDPair(GetID(), new_id_vec[idx]);
+ m_locations.SwapLocation(old_loc_sp, new_loc_sp);
+ old_sc_map.erase(old_id_vec[idx]);
+ new_sc_map.erase(new_id_vec[idx]);
+ }
+ }
+ else
+ {
+ for (lldb::break_id_t old_id : old_id_vec)
+ {
+ locations_to_remove.Add(old_break_locs.FindByIDPair(GetID(), old_id));
+ old_sc_map.erase(old_id);
+ }
+ for (lldb::break_id_t new_id : new_id_vec)
+ {
+ locations_to_announce.Add(new_break_locs.FindByIDPair(GetID(), new_id));
+ new_sc_map.erase(new_id);
+ }
+ }
+ }
+ }
+ }
+
+ // Now remove the remaining old locations, and cons up a removed locations event.
+ // Note, we don't put the new locations that were swapped with an old location on the locations_to_remove
+ // list, so we don't need to worry about telling the world about removing a location we didn't tell them
+ // about adding.
+
+ BreakpointEventData *locations_event;
+ if (!IsInternal())
+ locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
+ shared_from_this());
+ else
+ locations_event = NULL;
- // TO DO: For now I'm just adding locations for the new module and removing the
- // breakpoint locations that were in the old module.
- // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
- // carry over the options from the old location to the new.
+ for (BreakpointLocationSP loc_sp : locations_to_remove.BreakpointLocations())
+ {
+ m_locations.RemoveLocation(loc_sp);
+ if (locations_event)
+ locations_event->GetBreakpointLocationCollection().Add(loc_sp);
+ }
+ SendBreakpointChangedEvent (locations_event);
+
+ // And announce the new ones.
+
+ if (!IsInternal())
+ {
+ locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
+ shared_from_this());
+ for (BreakpointLocationSP loc_sp : locations_to_announce.BreakpointLocations())
+ locations_event->GetBreakpointLocationCollection().Add(loc_sp);
- temp_list.Clear();
- temp_list.Append (old_module_sp);
- ModulesChanged (temp_list, false, true);
+ SendBreakpointChangedEvent (locations_event);
+ }
+ m_locations.Compact();
+ }
}
void
@@ -534,6 +783,23 @@ Breakpoint::GetNumLocations() const
return m_locations.GetSize();
}
+bool
+Breakpoint::AddName (const char *new_name, Error &error)
+{
+ if (!new_name)
+ return false;
+ if (!BreakpointID::StringIsBreakpointName(new_name, error))
+ {
+ error.SetErrorStringWithFormat("input name \"%s\" not a breakpoint name.", new_name);
+ return false;
+ }
+ if (!error.Success())
+ return false;
+
+ m_name_list.insert(new_name);
+ return true;
+}
+
void
Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
{
@@ -584,6 +850,20 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l
if (level == lldb::eDescriptionLevelFull)
{
+ if (!m_name_list.empty())
+ {
+ s->EOL();
+ s->Indent();
+ s->Printf ("Names:");
+ s->EOL();
+ s->IndentMore();
+ for (std::string name : m_name_list)
+ {
+ s->Indent();
+ s->Printf("%s\n", name.c_str());
+ }
+ s->IndentLess();
+ }
s->IndentLess();
s->EOL();
}
diff --git a/source/Breakpoint/BreakpointID.cpp b/source/Breakpoint/BreakpointID.cpp
index 9963ed68303a..31823886dd9f 100644
--- a/source/Breakpoint/BreakpointID.cpp
+++ b/source/Breakpoint/BreakpointID.cpp
@@ -18,6 +18,7 @@
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Core/Error.h"
using namespace lldb;
using namespace lldb_private;
@@ -121,3 +122,19 @@ BreakpointID::ParseCanonicalReference (const char *input, break_id_t *break_id_p
return false;
}
+bool
+BreakpointID::StringIsBreakpointName(const char *name, Error &error)
+{
+ error.Clear();
+
+ if (name && (name[0] >= 'A' && name[0] <= 'z'))
+ {
+ if (strcspn(name, ".- ") != strlen(name))
+ {
+ error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"", name);
+ }
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp
index 24101b1442fb..b8b506750b34 100644
--- a/source/Breakpoint/BreakpointIDList.cpp
+++ b/source/Breakpoint/BreakpointIDList.cpp
@@ -159,27 +159,52 @@ BreakpointIDList::InsertStringArray (const char **string_array, size_t array_siz
// NEW_ARGS should be a copy of OLD_ARGS, with and ID range specifiers replaced by the members of the range.
void
-BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result,
+BreakpointIDList::FindAndReplaceIDRanges (Args &old_args,
+ Target *target,
+ bool allow_locations,
+ CommandReturnObject &result,
Args &new_args)
{
std::string range_start;
const char *range_end;
const char *current_arg;
const size_t num_old_args = old_args.GetArgumentCount();
+ std::set<std::string> names_found;
for (size_t i = 0; i < num_old_args; ++i)
{
bool is_range = false;
+
current_arg = old_args.GetArgumentAtIndex (i);
+ if (!allow_locations && strchr(current_arg, '.') != nullptr)
+ {
+ result.AppendErrorWithFormat ("Breakpoint locations not allowed, saw location: %s.", current_arg);
+ new_args.Clear();
+ return;
+ }
size_t range_start_len = 0;
size_t range_end_pos = 0;
+ Error error;
+
if (BreakpointIDList::StringContainsIDRangeExpression (current_arg, &range_start_len, &range_end_pos))
{
is_range = true;
range_start.assign (current_arg, range_start_len);
range_end = current_arg + range_end_pos;
}
+ else if (BreakpointID::StringIsBreakpointName(current_arg, error))
+ {
+ if (!error.Success())
+ {
+ new_args.Clear();
+ result.AppendError (error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ return;
+ }
+ else
+ names_found.insert(current_arg);
+ }
else if ((i + 2 < num_old_args)
&& BreakpointID::IsRangeIdentifier (old_args.GetArgumentAtIndex (i+1))
&& BreakpointID::IsValidIDExpression (current_arg)
@@ -342,6 +367,23 @@ BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, Target *target, Comman
}
}
+ // Okay, now see if we found any names, and if we did, add them:
+ if (target && names_found.size())
+ {
+ for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints())
+ {
+ for (std::string name : names_found)
+ {
+ if (bkpt_sp->MatchesName(name.c_str()))
+ {
+ StreamString canonical_id_str;
+ BreakpointID::GetCanonicalReference (&canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
+ new_args.AppendArgument (canonical_id_str.GetData());
+ }
+ }
+ }
+ }
+
result.SetStatus (eReturnStatusSuccessFinishNoResult);
return;
}
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index e1ac043ae905..11ecfecc5bc7 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -449,8 +449,7 @@ BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
bool should_stop = true;
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
- IncrementHitCount();
-
+ // Do this first, if a location is disabled, it shouldn't increment its hit count.
if (!IsEnabled())
return false;
@@ -474,6 +473,13 @@ BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
return should_stop;
}
+void
+BreakpointLocation::BumpHitCount()
+{
+ if (IsEnabled())
+ IncrementHitCount();
+}
+
bool
BreakpointLocation::IsResolved () const
{
@@ -569,7 +575,7 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
s->PutCString ("re-exported target = ");
else
s->PutCString("where = ");
- sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
+ sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true);
}
else
{
@@ -717,4 +723,13 @@ BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventTyp
m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
}
}
-
+
+void
+BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
+{
+ m_address = swap_from->m_address;
+ m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
+ m_is_reexported = swap_from->m_is_reexported;
+ m_is_indirect = swap_from->m_is_indirect;
+ m_user_expression_sp.reset();
+}
diff --git a/source/Breakpoint/BreakpointLocationCollection.cpp b/source/Breakpoint/BreakpointLocationCollection.cpp
index ee3f56f928d5..5756ccedfaa4 100644
--- a/source/Breakpoint/BreakpointLocationCollection.cpp
+++ b/source/Breakpoint/BreakpointLocationCollection.cpp
@@ -196,3 +196,4 @@ BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel
(*pos)->GetDescription(s, level);
}
}
+
diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp
index ae7f863ad090..06b270a08ce9 100644
--- a/source/Breakpoint/BreakpointLocationList.cpp
+++ b/source/Breakpoint/BreakpointLocationList.cpp
@@ -272,6 +272,20 @@ BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_
return bp_loc_sp;
}
+void
+BreakpointLocationList::SwapLocation (BreakpointLocationSP to_location_sp, BreakpointLocationSP from_location_sp)
+{
+ if (!from_location_sp || !to_location_sp)
+ return;
+
+ m_address_to_location.erase(to_location_sp->GetAddress());
+ to_location_sp->SwapLocation(from_location_sp);
+ RemoveLocation(from_location_sp);
+ m_address_to_location[to_location_sp->GetAddress()] = to_location_sp;
+ to_location_sp->ResolveBreakpointSite();
+}
+
+
bool
BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp)
{
@@ -345,3 +359,16 @@ BreakpointLocationList::StopRecordingNewLocations ()
m_new_location_recorder = NULL;
}
+void
+BreakpointLocationList::Compact()
+{
+ lldb::break_id_t highest_id = 0;
+
+ for (BreakpointLocationSP loc_sp : m_locations)
+ {
+ lldb::break_id_t cur_id = loc_sp->GetID();
+ if (cur_id > highest_id)
+ highest_id = cur_id;
+ }
+ m_next_id = highest_id;
+}
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp
index ea8556d0930b..db76ffb8685c 100644
--- a/source/Breakpoint/BreakpointOptions.cpp
+++ b/source/Breakpoint/BreakpointOptions.cpp
@@ -237,8 +237,7 @@ BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) cons
if (m_thread_spec_ap.get())
m_thread_spec_ap->GetDescription (s, level);
- else if (level == eDescriptionLevelBrief)
- s->PutCString ("thread spec: no ");
+
if (level == lldb::eDescriptionLevelFull)
{
s->IndentLess();
diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp
index 1bcef93aedad..d6647130c54c 100644
--- a/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -109,3 +109,11 @@ BreakpointResolverAddress::Dump (Stream *s) const
{
}
+
+lldb::BreakpointResolverSP
+BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint)
+{
+ lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr));
+ return ret_sp;
+}
+
diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp
index dcee2fd54125..950054c3d720 100644
--- a/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -110,3 +110,14 @@ BreakpointResolverFileLine::Dump (Stream *s) const
}
+lldb::BreakpointResolverSP
+BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint)
+{
+ lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(&breakpoint,
+ m_file_spec,
+ m_line_number,
+ m_inlines,
+ m_skip_prologue));
+
+ return ret_sp;
+}
diff --git a/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp
index 01aecee7b9c2..c71d9bf5ba8c 100644
--- a/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -95,3 +95,10 @@ BreakpointResolverFileRegex::Dump (Stream *s) const
}
+lldb::BreakpointResolverSP
+BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint)
+{
+ lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex));
+ return ret_sp;
+}
+
diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp
index 3ac3ed06fc70..581f7b016173 100644
--- a/source/Breakpoint/BreakpointResolverName.cpp
+++ b/source/Breakpoint/BreakpointResolverName.cpp
@@ -121,6 +121,17 @@ BreakpointResolverName::~BreakpointResolverName ()
{
}
+BreakpointResolverName::BreakpointResolverName(const BreakpointResolverName &rhs) :
+ BreakpointResolver(rhs.m_breakpoint, BreakpointResolver::NameResolver),
+ m_lookups(rhs.m_lookups),
+ m_class_name(rhs.m_class_name),
+ m_regex(rhs.m_regex),
+ m_match_type (rhs.m_match_type),
+ m_skip_prologue (rhs.m_skip_prologue)
+{
+
+}
+
void
BreakpointResolverName::AddNameLookup (const ConstString &name, uint32_t name_type_mask)
{
@@ -371,3 +382,10 @@ BreakpointResolverName::Dump (Stream *s) const
}
+lldb::BreakpointResolverSP
+BreakpointResolverName::CopyForBreakpoint (Breakpoint &breakpoint)
+{
+ lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this));
+ ret_sp->SetBreakpoint(&breakpoint);
+ return ret_sp;
+}
diff --git a/source/Breakpoint/BreakpointSite.cpp b/source/Breakpoint/BreakpointSite.cpp
index 3cf6d37af379..469514b03f8a 100644
--- a/source/Breakpoint/BreakpointSite.cpp
+++ b/source/Breakpoint/BreakpointSite.cpp
@@ -199,6 +199,15 @@ BreakpointSite::ValidForThisThread (Thread *thread)
return m_owners.ValidForThisThread(thread);
}
+void
+BreakpointSite::BumpHitCounts()
+{
+ for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations())
+ {
+ loc_sp->BumpHitCount();
+ }
+}
+
bool
BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const
{
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index f0ad4a896739..c65dd9d460f4 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -112,7 +112,7 @@ CommandCompletions::SourceFiles
if (searcher == NULL)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilter null_searcher (target_sp);
+ SearchFilterForUnconstrainedSearches null_searcher (target_sp);
completer.DoCompletion (&null_searcher);
}
else
@@ -375,7 +375,7 @@ CommandCompletions::Modules
if (searcher == NULL)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilter null_searcher (target_sp);
+ SearchFilterForUnconstrainedSearches null_searcher (target_sp);
completer.DoCompletion (&null_searcher);
}
else
@@ -406,7 +406,7 @@ CommandCompletions::Symbols
if (searcher == NULL)
{
lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilter null_searcher (target_sp);
+ SearchFilterForUnconstrainedSearches null_searcher (target_sp);
completer.DoCompletion (&null_searcher);
}
else
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 13bf1278c78c..3d4b3aff6fff 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -20,6 +20,8 @@
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -145,6 +147,10 @@ public:
m_condition.assign(option_arg);
break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+
case 'E':
{
LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
@@ -236,6 +242,11 @@ public:
m_func_name_type_mask |= eFunctionNameTypeAuto;
break;
+ case 'N':
+ if (BreakpointID::StringIsBreakpointName(option_arg, error))
+ m_breakpoint_names.push_back (option_arg);
+ break;
+
case 'o':
m_one_shot = true;
break;
@@ -324,6 +335,8 @@ public:
m_language = eLanguageTypeUnknown;
m_skip_prologue = eLazyBoolCalculate;
m_one_shot = false;
+ m_use_dummy = false;
+ m_breakpoint_names.clear();
}
const OptionDefinition*
@@ -343,6 +356,7 @@ public:
uint32_t m_line_num;
uint32_t m_column;
std::vector<std::string> m_func_names;
+ std::vector<std::string> m_breakpoint_names;
uint32_t m_func_name_type_mask;
std::string m_func_regexp;
std::string m_source_text_regexp;
@@ -359,16 +373,18 @@ public:
lldb::LanguageType m_language;
LazyBool m_skip_prologue;
bool m_one_shot;
+ bool m_use_dummy;
};
protected:
virtual bool
DoExecute (Args& command,
- CommandReturnObject &result)
+ CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
+ if (target == nullptr)
{
result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
result.SetStatus (eReturnStatusFailed);
@@ -551,6 +567,13 @@ protected:
if (!m_options.m_condition.empty())
bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+
+ if (!m_options.m_breakpoint_names.empty())
+ {
+ Error error; // We don't need to check the error here, since the option parser checked it...
+ for (auto name : m_options.m_breakpoint_names)
+ bp->AddName(name.c_str(), error);
+ }
bp->SetOneShot (m_options.m_one_shot);
}
@@ -560,10 +583,17 @@ protected:
Stream &output_stream = result.GetOutputStream();
const bool show_locations = false;
bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
- // Don't print out this warning for exception breakpoints. They can get set before the target
- // is set, but we won't know how to actually set the breakpoint till we run.
- if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
+ if (target == m_interpreter.GetDebugger().GetDummyTarget())
+ output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
+ else
+ {
+ // Don't print out this warning for exception breakpoints. They can get set before the target
+ // is set, but we won't know how to actually set the breakpoint till we run.
+ if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
+ {
+ output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
+ }
+ }
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else if (!bp)
@@ -709,6 +739,12 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 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, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
+ { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
+ "Adds this to the list of names for this breakopint."},
+
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -766,7 +802,8 @@ public:
m_name_passed (false),
m_queue_passed (false),
m_condition_passed (false),
- m_one_shot_passed (false)
+ m_one_shot_passed (false),
+ m_use_dummy (false)
{
}
@@ -792,6 +829,9 @@ public:
m_enable_passed = true;
m_enable_value = false;
break;
+ case 'D':
+ m_use_dummy = true;
+ break;
case 'e':
m_enable_passed = true;
m_enable_value = true;
@@ -888,6 +928,7 @@ public:
m_name_passed = false;
m_condition_passed = false;
m_one_shot_passed = false;
+ m_use_dummy = false;
}
const OptionDefinition*
@@ -918,6 +959,7 @@ public:
bool m_queue_passed;
bool m_condition_passed;
bool m_one_shot_passed;
+ bool m_use_dummy;
};
@@ -925,7 +967,7 @@ protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
@@ -938,7 +980,7 @@ protected:
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -1024,6 +1066,8 @@ CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
+{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -1055,7 +1099,7 @@ protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
@@ -1088,7 +1132,7 @@ protected:
{
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -1175,7 +1219,7 @@ protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
@@ -1208,7 +1252,7 @@ protected:
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -1293,7 +1337,8 @@ public:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter),
- m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions
+ m_level (lldb::eDescriptionLevelBrief),
+ m_use_dummy(false)
{
}
@@ -1311,6 +1356,9 @@ public:
case 'b':
m_level = lldb::eDescriptionLevelBrief;
break;
+ case 'D':
+ m_use_dummy = true;
+ break;
case 'f':
m_level = lldb::eDescriptionLevelFull;
break;
@@ -1333,6 +1381,7 @@ public:
{
m_level = lldb::eDescriptionLevelFull;
m_internal = false;
+ m_use_dummy = false;
}
const OptionDefinition *
@@ -1350,13 +1399,15 @@ public:
lldb::DescriptionLevel m_level;
bool m_internal;
+ bool m_use_dummy;
};
protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
if (target == NULL)
{
result.AppendError ("Invalid target. No current target or breakpoints.");
@@ -1394,7 +1445,7 @@ protected:
{
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -1438,6 +1489,9 @@ CommandObjectBreakpointList::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
"Explain everything we know about the breakpoint (for debugging debugger bugs)." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -1540,7 +1594,7 @@ protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
@@ -1656,7 +1710,8 @@ public:
CommandObjectParsed (interpreter,
"breakpoint delete",
"Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
- NULL)
+ NULL),
+ m_options (interpreter)
{
CommandArgumentEntry arg;
CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
@@ -1667,11 +1722,78 @@ public:
virtual
~CommandObjectBreakpointDelete () {}
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter),
+ m_use_dummy (false),
+ m_force (false)
+ {
+ }
+
+ virtual
+ ~CommandOptions () {}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'f':
+ m_force = true;
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_use_dummy = false;
+ m_force = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ bool m_use_dummy;
+ bool m_force;
+ };
+
protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
if (target == NULL)
{
result.AppendError ("Invalid target. No existing target or breakpoints.");
@@ -1695,7 +1817,7 @@ protected:
if (command.GetArgumentCount() == 0)
{
- if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
+ if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
{
result.AppendMessage("Operation cancelled...");
}
@@ -1710,7 +1832,7 @@ protected:
{
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -1748,7 +1870,416 @@ protected:
}
return result.Succeeded();
}
+private:
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "Delete all breakpoints without querying for confirmation."},
+
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
+ { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointName
+//-------------------------------------------------------------------------
+
+static OptionDefinition
+g_breakpoint_name_options[] =
+{
+ { LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
+ { LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID, "Specify a breakpoint id to use."},
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
};
+class BreakpointNameOptionGroup : public OptionGroup
+{
+public:
+ BreakpointNameOptionGroup() :
+ OptionGroup(),
+ m_breakpoint(LLDB_INVALID_BREAK_ID),
+ m_use_dummy (false)
+ {
+
+ }
+
+ virtual
+ ~BreakpointNameOptionGroup ()
+ {
+ }
+
+ virtual uint32_t
+ GetNumDefinitions ()
+ {
+ return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
+ }
+
+ virtual const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_breakpoint_name_options;
+ }
+
+ virtual Error
+ SetOptionValue (CommandInterpreter &interpreter,
+ uint32_t option_idx,
+ const char *option_value)
+ {
+ Error error;
+ const int short_option = g_breakpoint_name_options[option_idx].short_option;
+
+ switch (short_option)
+ {
+ case 'N':
+ if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
+ m_name.SetValueFromCString(option_value);
+ break;
+
+ case 'B':
+ if (m_breakpoint.SetValueFromCString(option_value).Fail())
+ error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
+ break;
+ case 'D':
+ if (m_use_dummy.SetValueFromCString(option_value).Fail())
+ error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
+ break;
+ }
+ return error;
+ }
+
+ virtual void
+ OptionParsingStarting (CommandInterpreter &interpreter)
+ {
+ m_name.Clear();
+ m_breakpoint.Clear();
+ m_use_dummy.Clear();
+ m_use_dummy.SetDefaultValue(false);
+ }
+
+ OptionValueString m_name;
+ OptionValueUInt64 m_breakpoint;
+ OptionValueBoolean m_use_dummy;
+};
+
+
+class CommandObjectBreakpointNameAdd : public CommandObjectParsed
+{
+public:
+ CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "add",
+ "Add a name to the breakpoints provided.",
+ "breakpoint name add <command-options> <breakpoint-id-list>"),
+ m_name_options(),
+ m_option_group(interpreter)
+ {
+ // Create the first variant for the first (and only) argument for this command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back (arg1);
+
+ m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ virtual
+ ~CommandObjectBreakpointNameAdd () {}
+
+ Options *
+ GetOptions ()
+ {
+ return &m_option_group;
+ }
+
+protected:
+ virtual bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ if (!m_name_options.m_name.OptionWasSet())
+ {
+ result.SetError("No name option provided.");
+ return false;
+ }
+
+ Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == NULL)
+ {
+ result.AppendError ("Invalid target. No existing target or breakpoints.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0)
+ {
+ result.SetError("No breakpoints, cannot add names.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded())
+ {
+ if (valid_bp_ids.GetSize() == 0)
+ {
+ result.SetError("No breakpoints specified, cannot add names.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++)
+ {
+ lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ Error error; // We don't need to check the error here, since the option parser checked it...
+ bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+ }
+ }
+
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
+};
+
+
+
+class CommandObjectBreakpointNameDelete : public CommandObjectParsed
+{
+public:
+ CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "delete",
+ "Delete a name from the breakpoints provided.",
+ "breakpoint name delete <command-options> <breakpoint-id-list>"),
+ m_name_options(),
+ m_option_group(interpreter)
+ {
+ // Create the first variant for the first (and only) argument for this command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back (arg1);
+
+ m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ virtual
+ ~CommandObjectBreakpointNameDelete () {}
+
+ Options *
+ GetOptions ()
+ {
+ return &m_option_group;
+ }
+
+protected:
+ virtual bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ if (!m_name_options.m_name.OptionWasSet())
+ {
+ result.SetError("No name option provided.");
+ return false;
+ }
+
+ Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == NULL)
+ {
+ result.AppendError ("Invalid target. No existing target or breakpoints.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0)
+ {
+ result.SetError("No breakpoints, cannot delete names.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded())
+ {
+ if (valid_bp_ids.GetSize() == 0)
+ {
+ result.SetError("No breakpoints specified, cannot delete names.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++)
+ {
+ lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+ }
+ }
+
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
+};
+
+class CommandObjectBreakpointNameList : public CommandObjectParsed
+{
+public:
+ CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "list",
+ "List either the names for a breakpoint or the breakpoints for a given name.",
+ "breakpoint name list <command-options>"),
+ m_name_options(),
+ m_option_group(interpreter)
+ {
+ m_option_group.Append (&m_name_options);
+ m_option_group.Finalize();
+ }
+
+ virtual
+ ~CommandObjectBreakpointNameList () {}
+
+ Options *
+ GetOptions ()
+ {
+ return &m_option_group;
+ }
+
+protected:
+protected:
+ virtual bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == NULL)
+ {
+ result.AppendError ("Invalid target. No existing target or breakpoints.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_name_options.m_name.OptionWasSet())
+ {
+ const char *name = m_name_options.m_name.GetCurrentValue();
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ for (BreakpointSP bp_sp : breakpoints.Breakpoints())
+ {
+ if (bp_sp->MatchesName(name))
+ {
+ StreamString s;
+ bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+ s.EOL();
+ result.AppendMessage(s.GetData());
+ }
+ }
+
+ }
+ else if (m_name_options.m_breakpoint.OptionWasSet())
+ {
+ BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
+ if (bp_sp)
+ {
+ std::vector<std::string> names;
+ bp_sp->GetNames (names);
+ result.AppendMessage ("Names:");
+ for (auto name : names)
+ result.AppendMessageWithFormat (" %s\n", name.c_str());
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
+ m_name_options.m_breakpoint.GetCurrentValue());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ result.SetError ("Must specify -N or -B option to list.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiwordBreakpoint
+//-------------------------------------------------------------------------
+class CommandObjectBreakpointName : public CommandObjectMultiword
+{
+public:
+ CommandObjectBreakpointName (CommandInterpreter &interpreter) :
+ CommandObjectMultiword(interpreter,
+ "name",
+ "A set of commands to manage name tags for breakpoints",
+ "breakpoint name <command> [<command-options>]")
+ {
+ CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
+ CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
+ CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
+
+ LoadSubCommand ("add", add_command_object);
+ LoadSubCommand ("delete", delete_command_object);
+ LoadSubCommand ("list", list_command_object);
+
+ }
+
+ virtual
+ ~CommandObjectBreakpointName ()
+ {
+ }
+
+};
+
//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
@@ -1769,6 +2300,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
+ CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
list_command_object->SetCommandName ("breakpoint list");
enable_command_object->SetCommandName("breakpoint enable");
@@ -1778,6 +2310,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
set_command_object->SetCommandName("breakpoint set");
command_command_object->SetCommandName ("breakpoint command");
modify_command_object->SetCommandName ("breakpoint modify");
+ name_command_object->SetCommandName ("breakpoint name");
LoadSubCommand ("list", list_command_object);
LoadSubCommand ("enable", enable_command_object);
@@ -1787,6 +2320,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
LoadSubCommand ("set", set_command_object);
LoadSubCommand ("command", command_command_object);
LoadSubCommand ("modify", modify_command_object);
+ LoadSubCommand ("name", name_command_object);
}
CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
@@ -1794,13 +2328,17 @@ CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
}
void
-CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
- BreakpointIDList *valid_ids)
+CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
+ Target *target,
+ bool allow_locations,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids)
{
// args can be strings representing 1). integers (for breakpoint ids)
// 2). the full breakpoint & location canonical representation
// 3). the word "to" or a hyphen, representing a range (in which case there
// had *better* be an entry both before & after of one of the first two types.
+ // 4). A breakpoint name
// If args is empty, we will use the last created breakpoint (if there is one.)
Args temp_args;
@@ -1824,7 +2362,7 @@ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *targe
// the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
// all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
- BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);
+ BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
// NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
diff --git a/source/Commands/CommandObjectBreakpoint.h b/source/Commands/CommandObjectBreakpoint.h
index 2d674b22d704..3fdd2a5f56be 100644
--- a/source/Commands/CommandObjectBreakpoint.h
+++ b/source/Commands/CommandObjectBreakpoint.h
@@ -38,8 +38,20 @@ public:
~CommandObjectMultiwordBreakpoint ();
static void
- VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, BreakpointIDList *valid_ids);
+ VerifyBreakpointOrLocationIDs (Args &args, Target *target, CommandReturnObject &result, BreakpointIDList *valid_ids)
+ {
+ VerifyIDs (args, target, true, result, valid_ids);
+ }
+ static void
+ VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, BreakpointIDList *valid_ids)
+ {
+ VerifyIDs (args, target, false, result, valid_ids);
+ }
+
+private:
+ static void
+ VerifyIDs (Args &args, Target *target, bool allow_locations, CommandReturnObject &result, BreakpointIDList *valid_ids);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index fdb87d11900b..8f8404b712a5 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -307,17 +307,16 @@ one command per line.\n" );
result.SetImmediateOutputStream (output_stream);
result.SetImmediateErrorStream (error_stream);
- bool stop_on_continue = true;
- bool echo_commands = false;
- bool print_results = true;
-
- debugger.GetCommandInterpreter().HandleCommands (commands,
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue(true);
+ options.SetStopOnError (data->stop_on_error);
+ options.SetEchoCommands (true);
+ options.SetPrintResults (true);
+ options.SetAddToHistory (false);
+
+ debugger.GetCommandInterpreter().HandleCommands (commands,
&exe_ctx,
- stop_on_continue,
- data->stop_on_error,
- echo_commands,
- print_results,
- eLazyBoolNo,
+ options,
result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();
@@ -390,6 +389,10 @@ one command per line.\n" );
}
break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+
default:
break;
}
@@ -406,6 +409,7 @@ one command per line.\n" );
m_stop_on_error = true;
m_one_liner.clear();
m_function_name.clear();
+ m_use_dummy = false;
}
const OptionDefinition*
@@ -429,13 +433,14 @@ one command per line.\n" );
std::string m_one_liner;
bool m_stop_on_error;
std::string m_function_name;
+ bool m_use_dummy;
};
protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
if (target == NULL)
{
@@ -462,7 +467,7 @@ protected:
}
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
m_bp_options_vec.clear();
@@ -581,6 +586,9 @@ CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 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, NULL, NULL, 0, eArgTypeNone,
+ "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -595,7 +603,8 @@ public:
CommandObjectParsed (interpreter,
"delete",
"Delete the set of commands from a breakpoint.",
- NULL)
+ NULL),
+ m_options (interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData bp_id_arg;
@@ -615,11 +624,70 @@ public:
virtual
~CommandObjectBreakpointCommandDelete () {}
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter),
+ m_use_dummy (false)
+ {
+ }
+
+ virtual
+ ~CommandOptions () {}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_use_dummy = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ bool m_use_dummy;
+ };
+
protected:
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
if (target == NULL)
{
@@ -646,7 +714,7 @@ protected:
}
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
@@ -680,8 +748,20 @@ protected:
}
return result.Succeeded();
}
+private:
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+ "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+
+ { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
+
//-------------------------------------------------------------------------
// CommandObjectBreakpointCommandList
//-------------------------------------------------------------------------
@@ -744,7 +824,7 @@ protected:
}
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
if (result.Succeeded())
{
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 7d9bb7dad8fd..f98eac055f24 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -366,7 +366,7 @@ protected:
// Instance variables to hold the values for command options.
OptionValueBoolean m_stop_on_error;
- OptionValueBoolean m_silent_run;
+ OptionValueBoolean m_silent_run;
OptionValueBoolean m_stop_on_continue;
};
@@ -387,14 +387,15 @@ protected:
m_options.m_stop_on_continue.OptionWasSet())
{
// Use user set settings
- LazyBool print_command = m_options.m_silent_run.GetCurrentValue() ? eLazyBoolNo : eLazyBoolYes;
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
+ options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
+ options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
+ options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
+
m_interpreter.HandleCommandsFromFile (cmd_file,
exe_ctx,
- m_options.m_stop_on_continue.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on continue
- m_options.m_stop_on_error.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on error
- print_command, // Echo command
- print_command, // Print command output
- eLazyBoolCalculate, // Add to history
+ options,
result);
}
@@ -402,13 +403,10 @@ protected:
{
// No options were set, inherit any settings from nested "command source" commands,
// or set to sane default settings...
+ CommandInterpreterRunOptions options;
m_interpreter.HandleCommandsFromFile (cmd_file,
exe_ctx,
- eLazyBoolCalculate, // Stop on continue
- eLazyBoolCalculate, // Stop on error
- eLazyBoolCalculate, // Echo command
- eLazyBoolCalculate, // Print command output
- eLazyBoolCalculate, // Add to history
+ options,
result);
}
@@ -830,8 +828,16 @@ protected:
{
if (m_interpreter.CommandExists (command_name))
{
- result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
- command_name);
+ if (cmd_obj->IsRemovable())
+ {
+ result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
+ command_name);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
+ command_name);
+ }
result.SetStatus (eReturnStatusFailed);
}
else
@@ -868,6 +874,77 @@ protected:
}
};
+#pragma mark CommandObjectCommandsDelete
+//-------------------------------------------------------------------------
+// CommandObjectCommandsDelete
+//-------------------------------------------------------------------------
+
+class CommandObjectCommandsDelete : public CommandObjectParsed
+{
+public:
+ CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "command delete",
+ "Allow the user to delete user-defined regular expression, python or multi-word commands.",
+ NULL)
+ {
+ CommandArgumentEntry arg;
+ CommandArgumentData alias_arg;
+
+ // Define the first (and only) variant of this arg.
+ alias_arg.arg_type = eArgTypeCommandName;
+ alias_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (alias_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
+ }
+
+ ~CommandObjectCommandsDelete()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (Args& args, CommandReturnObject &result)
+ {
+ CommandObject::CommandMap::iterator pos;
+
+ if (args.GetArgumentCount() != 0)
+ {
+ const char *command_name = args.GetArgumentAtIndex(0);
+ if (m_interpreter.CommandExists (command_name))
+ {
+ if (m_interpreter.RemoveCommand (command_name))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
+ command_name);
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
+ command_name);
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ return result.Succeeded();
+ }
+};
+
//-------------------------------------------------------------------------
// CommandObjectCommandsAddRegex
//-------------------------------------------------------------------------
@@ -875,7 +952,7 @@ protected:
class CommandObjectCommandsAddRegex :
public CommandObjectParsed,
- public IOHandlerDelegate
+ public IOHandlerDelegateMultiline
{
public:
CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
@@ -883,7 +960,7 @@ public:
"command regex",
"Allow the user to create a regular expression command.",
"command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
- IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
+ IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
m_options (interpreter)
{
SetHelpLong(
@@ -920,8 +997,8 @@ public:
protected:
- virtual void
- IOHandlerActivated (IOHandler &io_handler)
+ void
+ IOHandlerActivated (IOHandler &io_handler) override
{
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
if (output_sp)
@@ -931,8 +1008,8 @@ protected:
}
}
- virtual void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
+ void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
{
io_handler.SetIsDone(true);
if (m_regex_cmd_ap.get())
@@ -944,7 +1021,6 @@ protected:
bool check_only = false;
for (size_t i=0; i<num_lines; ++i)
{
- printf ("regex[%zu] = %s\n", i, lines[i].c_str());
llvm::StringRef bytes_strref (lines[i]);
Error error = AppendRegexSubstitution (bytes_strref, check_only);
if (error.Fail())
@@ -964,54 +1040,9 @@ protected:
}
}
}
-
- virtual LineStatus
- IOHandlerLinesUpdated (IOHandler &io_handler,
- StringList &lines,
- uint32_t line_idx,
- Error &error)
- {
- if (line_idx == UINT32_MAX)
- {
- // Return true to indicate we are done getting lines (this
- // is a "fake" line - the real terminating blank line was
- // removed during a previous call with the code below)
- error.Clear();
- return LineStatus::Done;
- }
- else
- {
- const size_t num_lines = lines.GetSize();
- if (line_idx + 1 == num_lines)
- {
- // The last line was edited, if this line is empty, then we are done
- // getting our multiple lines.
- if (lines[line_idx].empty())
- {
- // Remove the last empty line from "lines" so it doesn't appear
- // in our final expression and return true to indicate we are done
- // getting lines
- lines.PopBack();
- return LineStatus::Done;
- }
- }
- // Check the current line to make sure it is formatted correctly
- bool check_only = true;
- llvm::StringRef regex_sed(lines[line_idx]);
- error = AppendRegexSubstitution (regex_sed, check_only);
- if (error.Fail())
- {
- return LineStatus::Error;
- }
- else
- {
- return LineStatus::Success;
- }
- }
- }
bool
- DoExecute (Args& command, CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result) override
{
const size_t argc = command.GetArgumentCount();
if (argc == 0)
@@ -1027,16 +1058,22 @@ protected:
name,
m_options.GetHelp (),
m_options.GetSyntax (),
- 10));
+ 10,
+ 0,
+ true));
if (argc == 1)
{
Debugger &debugger = m_interpreter.GetDebugger();
+ bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ IOHandler::Type::Other,
"lldb-regex", // Name of input reader for history
- "\033[K> ", // Prompt and clear line
+ "> ", // Prompt
+ NULL, // Continuation prompt
multiple_lines,
+ color_prompt,
0, // Don't show line numbers
*this));
@@ -1110,21 +1147,25 @@ protected:
if (second_separator_char_pos == std::string::npos)
{
- error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
+ error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
separator_char,
(int)(regex_sed.size() - first_separator_char_pos - 1),
- regex_sed.data() + (first_separator_char_pos + 1));
- return error;
+ regex_sed.data() + (first_separator_char_pos + 1),
+ (int)regex_sed.size(),
+ regex_sed.data());
+ return error;
}
const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
if (third_separator_char_pos == std::string::npos)
{
- error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
+ error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
separator_char,
(int)(regex_sed.size() - second_separator_char_pos - 1),
- regex_sed.data() + (second_separator_char_pos + 1));
+ regex_sed.data() + (second_separator_char_pos + 1),
+ (int)regex_sed.size(),
+ regex_sed.data());
return error;
}
@@ -1262,8 +1303,8 @@ private:
std::string m_syntax;
};
- virtual Options *
- GetOptions ()
+ Options *
+ GetOptions () override
{
return &m_options;
}
@@ -1292,15 +1333,24 @@ public:
CommandObjectPythonFunction (CommandInterpreter &interpreter,
std::string name,
std::string funct,
+ std::string help,
ScriptedCommandSynchronicity synch) :
CommandObjectRaw (interpreter,
name.c_str(),
- (std::string("Run Python function ") + funct).c_str(),
+ NULL,
NULL),
m_function_name(funct),
m_synchro(synch),
m_fetched_help_long(false)
{
+ if (!help.empty())
+ SetHelp(help.c_str());
+ else
+ {
+ StreamString stream;
+ stream.Printf("For more information run 'help %s'",name.c_str());
+ SetHelp(stream.GetData());
+ }
}
virtual
@@ -1357,7 +1407,8 @@ protected:
raw_command_line,
m_synchro,
result,
- error) == false)
+ error,
+ m_exe_ctx) == false)
{
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1617,7 +1668,12 @@ protected:
switch (short_option)
{
case 'f':
- m_funct_name = std::string(option_arg);
+ if (option_arg)
+ m_funct_name.assign(option_arg);
+ break;
+ case 'h':
+ if (option_arg)
+ m_short_help.assign(option_arg);
break;
case 's':
m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
@@ -1635,7 +1691,8 @@ protected:
void
OptionParsingStarting ()
{
- m_funct_name = "";
+ m_funct_name.clear();
+ m_short_help.clear();
m_synchronicity = eScriptedCommandSynchronicitySynchronous;
}
@@ -1652,6 +1709,7 @@ protected:
// Instance variables to hold the values for command options.
std::string m_funct_name;
+ std::string m_short_help;
ScriptedCommandSynchronicity m_synchronicity;
};
@@ -1695,6 +1753,7 @@ protected:
CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
m_cmd_name,
funct_name_str.c_str(),
+ m_short_help,
m_synchronicity));
if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
@@ -1748,8 +1807,9 @@ protected:
return false;
}
- // Store the command name and synchronicity in case we get multi-line input
+ // Store the options in case we get multi-line input
m_cmd_name = command.GetArgumentAtIndex(0);
+ m_short_help.assign(m_options.m_short_help);
m_synchronicity = m_options.m_synchronicity;
if (m_options.m_funct_name.empty())
@@ -1764,6 +1824,7 @@ protected:
CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
m_cmd_name,
m_options.m_funct_name,
+ m_options.m_short_help,
m_synchronicity));
if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
{
@@ -1782,6 +1843,7 @@ protected:
CommandOptions m_options;
std::string m_cmd_name;
+ std::string m_short_help;
ScriptedCommandSynchronicity m_synchronicity;
};
@@ -1797,6 +1859,7 @@ OptionDefinition
CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
+ { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
{ LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -1949,11 +2012,11 @@ public:
"A set of commands for managing or customizing script commands.",
"command script <subcommand> [<subcommand-options>]")
{
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
+ LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
+ LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
+ LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
- LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
+ LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
}
~CommandObjectMultiwordCommandsScript ()
@@ -1978,9 +2041,10 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpret
LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
+ LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
- LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
- LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
+ LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
+ LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
}
CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 079c62ddfdff..b4c559c81cc5 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -281,7 +281,7 @@ CommandObjectExpression::EvaluateExpression
Target *target = exe_ctx.GetTargetPtr();
if (!target)
- target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
+ target = GetDummyTarget();
if (target)
{
@@ -425,11 +425,15 @@ CommandObjectExpression::GetMultilineExpression ()
m_expr_line_count = 0;
Debugger &debugger = GetCommandInterpreter().GetDebugger();
+ bool color_prompt = debugger.GetUseColor();
const bool multiple_lines = true; // Get multiple lines
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
+ IOHandler::Type::Expression,
"lldb-expr", // Name of input reader for history
NULL, // No prompt
+ NULL, // Continuation prompt
multiple_lines,
+ color_prompt,
1, // Show line numbers starting at 1
*this));
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index bfbb296158a9..6c06ec831830 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -33,8 +33,10 @@
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
@@ -612,7 +614,16 @@ protected:
}
size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
- size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+
+ // TODO For non-8-bit byte addressable architectures this needs to be
+ // revisited to fully support all lldb's range of formatting options.
+ // Furthermore code memory reads (for those architectures) will not
+ // be correctly formatted even w/o formatting options.
+ size_t item_byte_size =
+ target->GetArchitecture().GetDataByteSize() > 1 ?
+ target->GetArchitecture().GetDataByteSize() :
+ m_format_options.GetByteSizeValue().GetCurrentValue();
+
const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
if (total_byte_size == 0)
@@ -659,7 +670,7 @@ protected:
total_byte_size = end_addr - addr;
item_count = total_byte_size / item_byte_size;
}
-
+
uint32_t max_unforced_size = target->GetMaximumMemReadSize();
if (total_byte_size > max_unforced_size && !m_memory_options.m_force)
@@ -856,7 +867,8 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
DataExtractor data (data_sp,
target->GetArchitecture().GetByteOrder(),
- target->GetArchitecture().GetAddressByteSize());
+ target->GetArchitecture().GetAddressByteSize(),
+ target->GetArchitecture().GetDataByteSize());
Format format = m_format_options.GetFormat();
if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) )
@@ -890,7 +902,7 @@ protected:
format,
item_byte_size,
item_count,
- num_per_line,
+ num_per_line / target->GetArchitecture().GetDataByteSize(),
addr,
0,
0,
@@ -1078,7 +1090,7 @@ protected:
lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error);
if (high_addr == LLDB_INVALID_ADDRESS || error.Fail())
{
- result.AppendError("invalid low address");
+ result.AppendError("invalid high address");
return false;
}
@@ -1667,6 +1679,96 @@ protected:
OptionGroupWriteMemory m_memory_options;
};
+//----------------------------------------------------------------------
+// Get malloc/free history of a memory address.
+//----------------------------------------------------------------------
+class CommandObjectMemoryHistory : public CommandObjectParsed
+{
+public:
+
+ CommandObjectMemoryHistory (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "memory history",
+ "Prints out the recorded stack traces for allocation/deallocation of a memory address.",
+ NULL,
+ eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBePaused | eFlagProcessMustBeLaunched)
+ {
+ CommandArgumentEntry arg1;
+ CommandArgumentData addr_arg;
+
+ // Define the first (and only) variant of this arg.
+ addr_arg.arg_type = eArgTypeAddress;
+ addr_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg1.push_back (addr_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg1);
+ }
+
+ virtual
+ ~CommandObjectMemoryHistory ()
+ {
+ }
+
+ virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
+ {
+ return m_cmd_name.c_str();
+ }
+
+protected:
+ virtual bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc == 0 || argc > 1)
+ {
+ result.AppendErrorWithFormat ("%s takes an address expression", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Error error;
+ lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
+ command.GetArgumentAtIndex(0),
+ LLDB_INVALID_ADDRESS,
+ &error);
+
+ if (addr == LLDB_INVALID_ADDRESS)
+ {
+ result.AppendError("invalid address expression");
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Stream *output_stream = &result.GetOutputStream();
+
+ const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
+ const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp);
+
+ if (! memory_history.get())
+ {
+ result.AppendError("no available memory history provider");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
+
+ for (auto thread : thread_list) {
+ thread->GetStatus(*output_stream, 0, UINT32_MAX, 0);
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return true;
+ }
+
+};
+
//-------------------------------------------------------------------------
// CommandObjectMemory
@@ -1681,6 +1783,7 @@ CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter)));
LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
+ LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter)));
}
CommandObjectMemory::~CommandObjectMemory ()
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 9998dbdccdad..d176d52cb487 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -302,7 +302,7 @@ protected:
Stream &ostrm = result.GetOutputStream();
ostrm.Printf("Available platforms:\n");
- PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
+ PlatformSP host_platform_sp (Platform::GetHostPlatform());
ostrm.Printf ("%s: %s\n",
host_platform_sp->GetPluginName().GetCString(),
host_platform_sp->GetDescription());
@@ -1347,7 +1347,6 @@ protected:
ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
debugger,
target,
- debugger.GetListener(),
error));
if (process_sp && process_sp->IsAlive())
{
@@ -1933,7 +1932,7 @@ public:
{
Error err;
ProcessSP remote_process_sp =
- platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), NULL, m_interpreter.GetDebugger().GetListener(), err);
+ platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), NULL, err);
if (err.Fail())
{
result.AppendError(err.AsCString());
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 6536c6ef1693..ec7b478fbecc 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -258,8 +258,9 @@ protected:
// Save the arguments for subsequent runs in the current target.
target->SetRunArguments (launch_args);
}
-
- Error error = target->Launch(debugger.GetListener(), m_options.launch_info);
+
+ StreamString stream;
+ Error error = target->Launch(m_options.launch_info, &stream);
if (error.Success())
{
@@ -267,6 +268,9 @@ protected:
ProcessSP process_sp (target->GetProcessSP());
if (process_sp)
{
+ const char *data = stream.GetData();
+ if (data && strlen(data) > 0)
+ result.AppendMessage(stream.GetData());
result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
result.SetStatus (eReturnStatusSuccessFinishResult);
result.SetDidChangeProcessState (true);
@@ -564,15 +568,18 @@ protected:
if (error.Success())
{
result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
+ StreamString stream;
+ StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get(), &stream);
process->RestoreProcessEvents();
result.SetDidChangeProcessState (true);
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
+
if (state == eStateStopped)
{
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -791,7 +798,12 @@ protected:
}
}
- Error error(process->Resume());
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous (&stream);
+ else
+ error = process->Resume ();
if (error.Success())
{
@@ -803,10 +815,11 @@ protected:
result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
- state = process->WaitForProcessToStop (NULL);
+ // If any state changed events had anything to say, add that to the result
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 6b1b6aacc857..8fb03e69ac42 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -421,7 +421,7 @@ protected:
{
const bool show_inlines = true;
m_breakpoint_locations.Reset (start_file, 0, show_inlines);
- SearchFilter target_search_filter (m_exe_ctx.GetTargetSP());
+ SearchFilterForUnconstrainedSearches target_search_filter (m_exe_ctx.GetTargetSP());
target_search_filter.Search (m_breakpoint_locations);
}
@@ -682,19 +682,21 @@ protected:
m_breakpoint_locations.Clear();
const bool show_inlines = true;
m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
- SearchFilter target_search_filter (target->shared_from_this());
+ SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
target_search_filter.Search (m_breakpoint_locations);
}
bool show_fullpaths = true;
bool show_module = true;
bool show_inlined_frames = true;
+ const bool show_function_arguments = true;
sc.DumpStopContext(&result.GetOutputStream(),
m_exe_ctx.GetBestExecutionContextScope(),
sc.line_entry.range.GetBaseAddress(),
show_fullpaths,
show_module,
- show_inlined_frames);
+ show_inlined_frames,
+ show_function_arguments);
result.GetOutputStream().EOL();
if (m_options.num_lines == 0)
@@ -741,7 +743,7 @@ protected:
{
const bool show_inlines = true;
m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines);
- SearchFilter target_search_filter (target->shared_from_this());
+ SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
target_search_filter.Search (m_breakpoint_locations);
}
}
@@ -844,7 +846,7 @@ protected:
{
const bool show_inlines = true;
m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
- SearchFilter target_search_filter (target->shared_from_this());
+ SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
target_search_filter.Search (m_breakpoint_locations);
}
else
diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp
index d2021ea3eb19..5093c3b99339 100644
--- a/source/Commands/CommandObjectSyntax.cpp
+++ b/source/Commands/CommandObjectSyntax.cpp
@@ -69,12 +69,18 @@ CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
{
std::string sub_command = command.GetArgumentAtIndex (i);
if (!cmd_obj->IsMultiwordObject())
+ {
all_okay = false;
+ break;
+ }
else
{
cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
if (!cmd_obj)
+ {
all_okay = false;
+ break;
+ }
}
}
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 024f7b5a0415..0d9ffda1e96b 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -39,6 +39,7 @@
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
+#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/FuncUnwinders.h"
@@ -2844,7 +2845,7 @@ public:
"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> ....]"),
m_option_group (interpreter),
- m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeFilename, "Fullpath or basename for module to load."),
+ m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0)
{
m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
@@ -2884,7 +2885,26 @@ protected:
if (m_file_option.GetOptionValue().OptionWasSet())
{
search_using_module_spec = true;
- module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
+ 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 (m_uuid_option_group.GetOptionValue().OptionWasSet())
@@ -3070,7 +3090,7 @@ protected:
OptionGroupOptions m_option_group;
OptionGroupUUID m_uuid_option_group;
- OptionGroupFile m_file_option;
+ OptionGroupString m_file_option;
OptionGroupUInt64 m_slide_option;
};
@@ -3724,45 +3744,85 @@ protected:
if (func_unwinders_sp.get() == NULL)
continue;
- Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
- if (first_non_prologue_insn.IsValid())
- {
- result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr);
- result.GetOutputStream().Printf ("\n");
- }
+ result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1);
if (non_callsite_unwind_plan.get())
{
- result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
- non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf ("\n");
+ result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
}
-
- UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
+ UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
if (callsite_unwind_plan.get())
{
- result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
- callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf ("\n");
+ result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
+ }
+ UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
+ if (fast_unwind_plan.get())
+ {
+ result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
}
- UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
- if (arch_default_unwind_plan.get())
+ result.GetOutputStream().Printf("\n");
+
+ UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0);
+ if (assembly_sp)
{
- result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
- arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf ("\n");
+ result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
+ assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
}
+
- UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
- if (fast_unwind_plan.get())
+ UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
+ if (ehframe_sp)
{
- result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
+ result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
+ ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0);
+ if (ehframe_augmented_sp)
+ {
+ result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
+ ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
+ if (compact_unwind_sp)
+ {
+ result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
+ compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ if (fast_unwind_plan)
+ {
+ result.GetOutputStream().Printf("Fast UnwindPlan:\n");
fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf ("\n");
+ result.GetOutputStream().Printf("\n");
}
+ ABISP abi_sp = process->GetABI();
+ if (abi_sp)
+ {
+ UnwindPlan arch_default(lldb::eRegisterKindGeneric);
+ if (abi_sp->CreateDefaultUnwindPlan (arch_default))
+ {
+ result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
+ arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
+ if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
+ {
+ result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
+ arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+ }
result.GetOutputStream().Printf ("\n");
}
@@ -4999,7 +5059,7 @@ protected:
{
m_stop_hook_sp.reset();
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
Target::StopHookSP new_hook_sp = target->CreateStopHook();
@@ -5151,7 +5211,7 @@ protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
// FIXME: see if we can use the breakpoint id style parser?
@@ -5227,7 +5287,7 @@ protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (target)
{
// FIXME: see if we can use the breakpoint id style parser?
@@ -5297,7 +5357,7 @@ protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ Target *target = GetSelectedOrDummyTarget();
if (!target)
{
result.AppendError ("invalid target\n");
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index e7a8652ac898..bace4e58b4ad 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -46,7 +46,108 @@ using namespace lldb_private;
// CommandObjectThreadBacktrace
//-------------------------------------------------------------------------
-class CommandObjectThreadBacktrace : public CommandObjectParsed
+class CommandObjectIterateOverThreads : public CommandObjectParsed
+{
+public:
+ CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t flags) :
+ CommandObjectParsed (interpreter, name, help, syntax, flags)
+ {
+ }
+
+ virtual ~CommandObjectIterateOverThreads() {}
+ virtual bool
+ DoExecute (Args& command, CommandReturnObject &result)
+ {
+ result.SetStatus (m_success_return);
+
+ if (command.GetArgumentCount() == 0)
+ {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (!HandleOneThread (*thread, result))
+ return false;
+ }
+ else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
+ {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ uint32_t idx = 0;
+ for (ThreadSP thread_sp : process->Threads())
+ {
+ if (idx != 0 && m_add_return)
+ result.AppendMessage("");
+
+ if (!HandleOneThread(*(thread_sp.get()), result))
+ return false;
+ ++idx;
+ }
+ }
+ else
+ {
+ const size_t num_args = command.GetArgumentCount();
+ Process *process = m_exe_ctx.GetProcessPtr();
+ Mutex::Locker locker (process->GetThreadList().GetMutex());
+ std::vector<ThreadSP> thread_sps;
+
+ for (size_t i = 0; i < num_args; i++)
+ {
+ bool success;
+
+ uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success)
+ {
+ result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
+
+ if (!thread_sps[i])
+ {
+ result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ }
+
+ for (uint32_t i = 0; i < num_args; i++)
+ {
+ if (!HandleOneThread (*(thread_sps[i].get()), result))
+ return false;
+
+ if (i < num_args - 1 && m_add_return)
+ result.AppendMessage("");
+ }
+ }
+ return result.Succeeded();
+ }
+
+protected:
+
+ // Override this to do whatever you need to do for one thread.
+ //
+ // If you return false, the iteration will stop, otherwise it will proceed.
+ // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
+ // so you only need to set the return status in HandleOneThread if you want to indicate an error.
+ // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
+
+ virtual bool
+ HandleOneThread (Thread &thread, CommandReturnObject &result) = 0;
+
+ ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
+ bool m_add_return = true;
+
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadBacktrace
+//-------------------------------------------------------------------------
+
+class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
{
public:
@@ -134,7 +235,7 @@ public:
};
CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
+ CommandObjectIterateOverThreads (interpreter,
"thread backtrace",
"Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.",
NULL,
@@ -145,18 +246,6 @@ public:
eFlagProcessMustBePaused ),
m_options(interpreter)
{
- CommandArgumentEntry arg;
- CommandArgumentData thread_idx_arg;
-
- // Define the first (and only) variant of this arg.
- thread_idx_arg.arg_type = eArgTypeThreadIndex;
- thread_idx_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (thread_idx_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
}
~CommandObjectThreadBacktrace()
@@ -197,106 +286,28 @@ protected:
}
virtual bool
- DoExecute (Args& command, CommandReturnObject &result)
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
+ HandleOneThread (Thread &thread, CommandReturnObject &result)
+ {
Stream &strm = result.GetOutputStream();
// Don't show source context when doing backtraces.
const uint32_t num_frames_with_source = 0;
- if (command.GetArgumentCount() == 0)
- {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- // Thread::GetStatus() returns the number of frames shown.
- if (thread->GetStatus (strm,
+
+ if (!thread.GetStatus (strm,
m_options.m_start,
m_options.m_count,
num_frames_with_source))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- if (m_options.m_extended_backtrace)
- {
- DoExtendedBacktrace (thread, result);
- }
- }
- }
- else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
{
- Process *process = m_exe_ctx.GetProcessPtr();
- uint32_t idx = 0;
- for (ThreadSP thread_sp : process->Threads())
- {
- if (idx != 0)
- result.AppendMessage("");
-
- if (!thread_sp->GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
- {
- result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (m_options.m_extended_backtrace)
- {
- DoExtendedBacktrace (thread_sp.get(), result);
- }
-
- ++idx;
- }
+ result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
+ if (m_options.m_extended_backtrace)
{
- const size_t num_args = command.GetArgumentCount();
- Process *process = m_exe_ctx.GetProcessPtr();
- Mutex::Locker locker (process->GetThreadList().GetMutex());
- std::vector<ThreadSP> thread_sps;
-
- for (size_t i = 0; i < num_args; i++)
- {
- bool success;
-
- uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
-
- if (!thread_sps[i])
- {
- result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- }
-
- for (uint32_t i = 0; i < num_args; i++)
- {
- if (!thread_sps[i]->GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
- {
- result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (m_options.m_extended_backtrace)
- {
- DoExtendedBacktrace (thread_sps[i].get(), result);
- }
-
- if (i < num_args - 1)
- result.AppendMessage("");
- }
+ DoExtendedBacktrace (&thread, result);
}
- return result.Succeeded();
+
+ return true;
}
CommandOptions m_options;
@@ -379,6 +390,12 @@ public:
break;
}
break;
+ case 'C':
+ {
+ m_class_name.clear();
+ m_class_name.assign(option_arg);
+ }
+ break;
case 'm':
{
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
@@ -416,6 +433,7 @@ public:
m_run_mode = eOnlyDuringStepping;
m_avoid_regexp.clear();
m_step_in_target.clear();
+ m_class_name.clear();
m_step_count = 1;
}
@@ -435,7 +453,8 @@ public:
RunMode m_run_mode;
std::string m_avoid_regexp;
std::string m_step_in_target;
- int32_t m_step_count;
+ std::string m_class_name;
+ uint32_t m_step_count;
};
CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
@@ -520,6 +539,22 @@ protected:
}
}
+ if (m_step_type == eStepTypeScripted)
+ {
+ if (m_options.m_class_name.empty())
+ {
+ result.AppendErrorWithFormat ("empty class name for scripted step.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
+ {
+ result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
const bool abort_other_plans = false;
const lldb::RunMode stop_other_threads = m_options.m_run_mode;
@@ -530,7 +565,7 @@ protected:
bool_stop_other_threads = false;
else if (m_options.m_run_mode == eOnlyDuringStepping)
{
- if (m_step_type == eStepTypeOut)
+ if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted)
bool_stop_other_threads = false;
else
bool_stop_other_threads = true;
@@ -599,6 +634,12 @@ protected:
thread->GetSelectedFrameIndex(),
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(),
+ bool_stop_other_threads);
+ }
else
{
result.AppendError ("step type is not supported");
@@ -622,8 +663,15 @@ protected:
}
}
+
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous (&stream);
+ else
+ error = process->Resume ();
// There is a race condition where this thread will return up the call stack to the main command handler
// and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
@@ -632,17 +680,12 @@ protected:
if (synchronous_execution)
{
- StateType state = process->WaitForProcessToStop (NULL);
-
- //EventSP event_sp;
- //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
- //while (! StateIsStoppedState (state))
- // {
- // state = process->WaitForStateChangedEvents (NULL, event_sp);
- // }
+ // If any state changed events had anything to say, add that to the result
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
+
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -686,10 +729,11 @@ CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
-{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
-{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
-{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
+{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
+{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
+{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
+{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
+{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -860,17 +904,25 @@ public:
}
}
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous (&stream);
+ else
+ error = process->Resume ();
+
// We should not be holding the thread list lock when we do this.
- Error error (process->Resume());
if (error.Success())
{
result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
- state = process->WaitForProcessToStop (NULL);
+ // If any state changed events had anything to say, add that to the result
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -1191,17 +1243,27 @@ protected:
}
+
+
process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
- Error error (process->Resume ());
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous (&stream);
+ else
+ error = process->Resume ();
+
if (error.Success())
{
result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
- StateType state = process->WaitForProcessToStop (NULL);
+ // If any state changed events had anything to say, add that to the result
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -1358,32 +1420,22 @@ protected:
// CommandObjectThreadInfo
//-------------------------------------------------------------------------
-class CommandObjectThreadInfo : public CommandObjectParsed
+class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
{
public:
CommandObjectThreadInfo (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread info",
- "Show an extended summary of information about thread(s) in a process.",
- "thread info",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused),
+ CommandObjectIterateOverThreads (interpreter,
+ "thread info",
+ "Show an extended summary of information about thread(s) in a process.",
+ "thread info",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused),
m_options (interpreter)
{
- CommandArgumentEntry arg;
- CommandArgumentData thread_idx_arg;
-
- thread_idx_arg.arg_type = eArgTypeThreadIndex;
- thread_idx_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (thread_idx_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ m_add_return = false;
}
class CommandOptions : public Options
@@ -1399,7 +1451,8 @@ public:
void
OptionParsingStarting ()
{
- m_json = false;
+ m_json_thread = false;
+ m_json_stopinfo = false;
}
virtual
@@ -1416,10 +1469,14 @@ public:
switch (short_option)
{
case 'j':
- m_json = true;
+ m_json_thread = true;
+ break;
+
+ case 's':
+ m_json_stopinfo = true;
break;
- default:
+ default:
return Error("invalid short option character '%c'", short_option);
}
@@ -1432,7 +1489,8 @@ public:
return g_option_table;
}
- bool m_json;
+ bool m_json_thread;
+ bool m_json_stopinfo;
static OptionDefinition g_option_table[];
};
@@ -1451,81 +1509,16 @@ public:
}
virtual bool
- DoExecute (Args& command, CommandReturnObject &result)
+ HandleOneThread (Thread &thread, CommandReturnObject &result)
{
- result.SetStatus (eReturnStatusSuccessFinishResult);
Stream &strm = result.GetOutputStream();
-
- if (command.GetArgumentCount() == 0)
- {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
- else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- uint32_t idx = 0;
- for (ThreadSP thread_sp : process->Threads())
- {
- if (idx != 0)
- result.AppendMessage("");
- if (!thread_sp->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
- {
- result.AppendErrorWithFormat ("error displaying info for thread: \"0x%4.4x\"\n", idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- ++idx;
- }
- }
- else
+ if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
{
- const size_t num_args = command.GetArgumentCount();
- Process *process = m_exe_ctx.GetProcessPtr();
- Mutex::Locker locker (process->GetThreadList().GetMutex());
- std::vector<ThreadSP> thread_sps;
-
- for (size_t i = 0; i < num_args; i++)
- {
- bool success;
-
- uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
-
- if (!thread_sps[i])
- {
- result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- }
-
- for (uint32_t i = 0; i < num_args; i++)
- {
- if (!thread_sps[i]->GetDescription (strm, eDescriptionLevelFull, m_options.m_json))
- {
- result.AppendErrorWithFormat ("error displaying info for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (i < num_args - 1)
- result.AppendMessage("");
- }
-
+ result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- return result.Succeeded();
+ return true;
}
CommandOptions m_options;
@@ -1536,6 +1529,7 @@ OptionDefinition
CommandObjectThreadInfo::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."},
+ { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -1958,6 +1952,228 @@ CommandObjectThreadJump::CommandOptions::g_option_table[] =
};
//-------------------------------------------------------------------------
+// Next are the subcommands of CommandObjectMultiwordThreadPlan
+//-------------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------------
+// CommandObjectThreadPlanList
+//-------------------------------------------------------------------------
+class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
+{
+public:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options(interpreter)
+ {
+ // Keep default values of all options in one place: OptionParsingStarting ()
+ OptionParsingStarting ();
+ }
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'i':
+ {
+ m_internal = true;
+ }
+ break;
+ case 'v':
+ {
+ m_verbose = true;
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+ break;
+
+ }
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_verbose = false;
+ m_internal = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ bool m_verbose;
+ bool m_internal;
+ };
+
+ CommandObjectThreadPlanList (CommandInterpreter &interpreter) :
+ CommandObjectIterateOverThreads (interpreter,
+ "thread plan list",
+ "Show thread plans for one or more threads. If no threads are specified, show the "
+ "currently selected thread. Use the thread-index \"all\" to see all threads.",
+ NULL,
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
+ m_options(interpreter)
+ {
+ }
+
+ ~CommandObjectThreadPlanList ()
+ {
+ }
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+protected:
+ virtual bool
+ HandleOneThread (Thread &thread, CommandReturnObject &result)
+ {
+ Stream &strm = result.GetOutputStream();
+ DescriptionLevel desc_level = eDescriptionLevelFull;
+ if (m_options.m_verbose)
+ desc_level = eDescriptionLevelVerbose;
+
+ thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
+ return true;
+ }
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"},
+{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"},
+{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
+class CommandObjectThreadPlanDiscard : public CommandObjectParsed
+{
+public:
+ CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "thread plan discard",
+ "Discards thread plans up to and including the plan passed as the command argument."
+ "Only user visible plans can be discarded, use the index from \"thread plan list\""
+ " without the \"-i\" argument.",
+ NULL,
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
+ {
+ CommandArgumentEntry arg;
+ CommandArgumentData plan_index_arg;
+
+ // Define the first (and only) variant of this arg.
+ plan_index_arg.arg_type = eArgTypeUnsignedInteger;
+ plan_index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (plan_index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
+ }
+
+ virtual ~CommandObjectThreadPlanDiscard () {}
+
+ bool
+ DoExecute (Args& args, CommandReturnObject &result)
+ {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (args.GetArgumentCount() != 1)
+ {
+ result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
+ args.GetArgumentCount());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ bool success;
+ uint32_t thread_plan_idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
+ if (!success)
+ {
+ result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
+ args.GetArgumentAtIndex(0));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (thread_plan_idx == 0)
+ {
+ result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
+ {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
+ args.GetArgumentAtIndex(0));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiwordThreadPlan
+//-------------------------------------------------------------------------
+
+class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
+{
+public:
+ CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) :
+ CommandObjectMultiword (interpreter,
+ "plan",
+ "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.",
+ "thread plan <subcommand> [<subcommand objects]")
+ {
+ LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
+ LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
+ }
+
+ virtual ~CommandObjectMultiwordThreadPlan () {}
+
+
+};
+
+//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
//-------------------------------------------------------------------------
@@ -2014,6 +2230,16 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &
NULL,
eStepTypeTraceOver,
eStepScopeInstruction)));
+
+ LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
+ interpreter,
+ "thread step-scripted",
+ "Step as instructed by the script class passed in the -C option.",
+ NULL,
+ eStepTypeScripted,
+ eStepScopeSource)));
+
+ LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
}
CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 640fd6dd3fa4..3a4c60c00f8b 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -16,6 +16,7 @@
#include <ctype.h>
// C++ Includes
+#include <functional>
#include "llvm/ADT/StringRef.h"
@@ -31,6 +32,11 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadList.h"
using namespace lldb;
using namespace lldb_private;
@@ -2465,22 +2471,7 @@ protected:
if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
{
- // we want to make sure to enable "system" last and "default" first
- DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First);
- uint32_t num_categories = DataVisualization::Categories::GetCount();
- for (uint32_t i = 0; i < num_categories; i++)
- {
- lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
- if (category_sp)
- {
- if ( ::strcmp(category_sp->GetName(), "system") == 0 ||
- ::strcmp(category_sp->GetName(), "default") == 0 )
- continue;
- else
- DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
- }
- }
- DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last);
+ DataVisualization::Categories::EnableStar();
}
else
{
@@ -2630,14 +2621,7 @@ protected:
if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
{
- uint32_t num_categories = DataVisualization::Categories::GetCount();
- for (uint32_t i = 0; i < num_categories; i++)
- {
- lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
- // no need to check if the category is enabled - disabling a disabled category has no effect
- if (category_sp)
- DataVisualization::Categories::Disable(category_sp);
- }
+ DataVisualization::Categories::DisableStar();
}
else
{
@@ -4253,6 +4237,84 @@ CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
+template <typename FormatterType>
+class CommandObjectFormatterInfo : public CommandObjectRaw
+{
+public:
+ typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction;
+ CommandObjectFormatterInfo (CommandInterpreter &interpreter,
+ const char* formatter_name,
+ DiscoveryFunction discovery_func) :
+ CommandObjectRaw(interpreter,
+ nullptr,
+ nullptr,
+ nullptr,
+ eFlagRequiresFrame),
+ m_formatter_name(formatter_name ? formatter_name : ""),
+ m_discovery_function(discovery_func)
+ {
+ StreamString name;
+ name.Printf("type %s info", formatter_name);
+ SetCommandName(name.GetData());
+ StreamString help;
+ help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name);
+ SetHelp(help.GetData());
+ StreamString syntax;
+ syntax.Printf("type %s info <expr>", formatter_name);
+ SetSyntax(syntax.GetData());
+ }
+
+ virtual
+ ~CommandObjectFormatterInfo ()
+ {
+ }
+
+protected:
+ virtual bool
+ DoExecute (const char *command, CommandReturnObject &result)
+ {
+ auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+ auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame();
+ ValueObjectSP result_valobj_sp;
+ EvaluateExpressionOptions options;
+ lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
+ if (expr_result == eExpressionCompleted && result_valobj_sp)
+ {
+ result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue());
+ typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp);
+ if (formatter_sp)
+ {
+ std::string description(formatter_sp->GetDescription());
+ result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n",
+ m_formatter_name.c_str(),
+ result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
+ command,
+ description.c_str());
+ result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendMessageWithFormat("no %s applies to (%s) %s\n",
+ m_formatter_name.c_str(),
+ result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
+ command);
+ result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
+ }
+ return true;
+ }
+ else
+ {
+ result.AppendError("failed to evaluate expression");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ }
+
+private:
+ std::string m_formatter_name;
+ DiscoveryFunction m_discovery_function;
+};
+
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public:
@@ -4266,6 +4328,11 @@ public:
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
+ LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter,
+ "format",
+ [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer {
+ return valobj.GetValueFormat();
+ })));
}
@@ -4289,6 +4356,11 @@ public:
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
+ LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter,
+ "synthetic",
+ [](ValueObject& valobj) -> SyntheticChildren::SharedPointer {
+ return valobj.GetSyntheticChildren();
+ })));
}
@@ -4354,6 +4426,11 @@ public:
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
+ LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter,
+ "summary",
+ [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer {
+ return valobj.GetSummaryFormat();
+ })));
}
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index f46db7a6a82b..275ee925adcc 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -279,17 +279,16 @@ but do NOT enter more than one command per line. \n" );
result.SetImmediateOutputStream (output_stream);
result.SetImmediateErrorStream (error_stream);
- bool stop_on_continue = true;
- bool echo_commands = false;
- bool print_results = true;
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue (true);
+ options.SetStopOnError (data->stop_on_error);
+ options.SetEchoCommands (false);
+ options.SetPrintResults (true);
+ options.SetAddToHistory (false);
debugger.GetCommandInterpreter().HandleCommands (commands,
&exe_ctx,
- stop_on_continue,
- data->stop_on_error,
- echo_commands,
- print_results,
- eLazyBoolNo,
+ options,
result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index fa9197d12b70..a79becbf49c4 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -433,7 +433,9 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
case DumpStyleModuleWithFileAddress:
if (section_sp)
- s->Printf("%s[", section_sp->GetModule()->GetFileSpec().GetFilename().AsCString());
+ {
+ s->Printf("%s[", section_sp->GetModule()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
+ }
// Fall through
case DumpStyleFileAddress:
{
@@ -465,6 +467,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
case DumpStyleResolvedDescription:
case DumpStyleResolvedDescriptionNoModule:
+ case DumpStyleResolvedDescriptionNoFunctionArguments:
if (IsSectionOffset())
{
uint32_t pointer_size = 4;
@@ -550,7 +553,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
#endif
Address cstr_addr(*this);
cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
- func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false);
+ func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true);
if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
{
#if VERBOSE_OUTPUT
@@ -633,7 +636,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (pointer_sc.function || pointer_sc.symbol)
{
s->PutCString(": ");
- pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false);
+ pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true);
}
}
}
@@ -658,6 +661,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
const bool show_module = (style == DumpStyleResolvedDescription);
const bool show_fullpaths = false;
const bool show_inlined_frames = true;
+ const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
if (sc.function == NULL && sc.symbol != NULL)
{
// If we have just a symbol make sure it is in the right section
@@ -679,7 +683,8 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
*this,
show_fullpaths,
show_module,
- show_inlined_frames);
+ show_inlined_frames,
+ show_function_arguments);
}
else
{
diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp
index 3505d56b43e2..ac64833884ee 100644
--- a/source/Core/AddressRange.cpp
+++ b/source/Core/AddressRange.cpp
@@ -179,7 +179,7 @@ AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, Address:
{
ModuleSP module_sp (GetBaseAddress().GetModule());
if (module_sp)
- s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString());
+ s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"));
}
s->AddressRange(vmaddr, vmaddr + GetByteSize(), addr_size);
return true;
diff --git a/source/Core/AddressResolverFileLine.cpp b/source/Core/AddressResolverFileLine.cpp
index f7004c8bb089..6089abd76cbc 100644
--- a/source/Core/AddressResolverFileLine.cpp
+++ b/source/Core/AddressResolverFileLine.cpp
@@ -96,7 +96,7 @@ AddressResolverFileLine::GetDepth()
void
AddressResolverFileLine::GetDescription (Stream *s)
{
- s->Printf ("File and line address - file: \"%s\" line: %u", m_file_spec.GetFilename().AsCString(), m_line_number);
+ s->Printf ("File and line address - file: \"%s\" line: %u", m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number);
}
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index 5f010f066408..e7a5e489af19 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -24,6 +24,11 @@
#include "lldb/Host/Endian.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
using namespace lldb;
using namespace lldb_private;
@@ -84,7 +89,7 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" },
+ { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "powerpc" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
@@ -98,7 +103,7 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
- { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" },
+ { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "powerpc64" },
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
{ eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
@@ -118,7 +123,6 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32 , "unknown-mach-32" },
{ eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64 , "unknown-mach-64" },
- { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba , "kalimba" },
{ eByteOrderBig , 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba3 , "kalimba3" },
{ eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba4 , "kalimba4" },
{ eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba5 , "kalimba5" }
@@ -195,10 +199,10 @@ static const ArchDefinitionEntry g_macho_arch_entries[] =
{ ArchSpec::eCore_arm_armv7k , llvm::MachO::CPU_TYPE_ARM , 12 , UINT32_MAX , SUBTYPE_MASK },
{ ArchSpec::eCore_arm_armv7m , llvm::MachO::CPU_TYPE_ARM , 15 , UINT32_MAX , SUBTYPE_MASK },
{ ArchSpec::eCore_arm_armv7em , llvm::MachO::CPU_TYPE_ARM , 16 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , CPU_ANY, UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 0 , UINT32_MAX , SUBTYPE_MASK },
{ ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 1 , UINT32_MAX , SUBTYPE_MASK },
+ { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 0 , UINT32_MAX , SUBTYPE_MASK },
{ ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 13 , 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 , SUBTYPE_MASK },
{ ArchSpec::eCore_thumbv4t , llvm::MachO::CPU_TYPE_ARM , 5 , UINT32_MAX , SUBTYPE_MASK },
{ ArchSpec::eCore_thumbv5 , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
@@ -264,11 +268,9 @@ static const ArchDefinitionEntry g_elf_arch_entries[] =
{ ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64
{ ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // MIPS
{ ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // HEXAGON
- { ArchSpec::eCore_kalimba , llvm::ELF::EM_CSR_KALIMBA, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
- { ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, 3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
- { ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, 4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
- { ArchSpec::eCore_kalimba5 , llvm::ELF::EM_CSR_KALIMBA, 5, 0xFFFFFFFFu, 0xFFFFFFFFu } // KALIMBA
-
+ { ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
+ { ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
+ { ArchSpec::eCore_kalimba5 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu } // KALIMBA
};
static const ArchDefinition g_elf_arch_def = {
@@ -503,11 +505,11 @@ ArchSpec::GetDataByteSize () const
switch (m_core)
{
case eCore_kalimba3:
- return 3;
+ return 4;
case eCore_kalimba4:
return 1;
case eCore_kalimba5:
- return 3;
+ return 4;
default:
return 1;
}
@@ -1036,16 +1038,6 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
}
break;
- case ArchSpec::eCore_kalimba:
- case ArchSpec::eCore_kalimba3:
- case ArchSpec::eCore_kalimba4:
- case ArchSpec::eCore_kalimba5:
- if (core2 >= ArchSpec::kCore_kalimba_first && core2 <= ArchSpec::kCore_kalimba_last)
- {
- return true;
- }
- break;
-
case ArchSpec::eCore_arm_armv8:
if (!enforce_exact_match)
{
@@ -1094,3 +1086,108 @@ lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
const ArchSpec::Core rhs_core = rhs.GetCore ();
return lhs_core < rhs_core;
}
+
+static void
+StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
+{
+ // We need to check if we are stopped in Thumb mode in a IT instruction
+ // and detect if the condition doesn't pass. If this is the case it means
+ // we won't actually execute this instruction. If this happens we need to
+ // clear the stop reason to no thread plans think we are stopped for a
+ // reason and the plans should keep going.
+ //
+ // We do this because when single stepping many ARM processes, debuggers
+ // often use the BVR/BCR registers that says "stop when the PC is not
+ // equal to its current value". This method of stepping means we can end
+ // up stopping on instructions inside an if/then block that wouldn't get
+ // executed. By fixing this we can stop the debugger from seeming like
+ // you stepped through both the "if" _and_ the "else" clause when source
+ // level stepping because the debugger stops regardless due to the BVR/BCR
+ // triggering a stop.
+ //
+ // It also means we can set breakpoints on instructions inside an an
+ // if/then block and correctly skip them if we use the BKPT instruction.
+ // The ARM and Thumb BKPT instructions are unconditional even when executed
+ // in a Thumb IT block.
+ //
+ // If your debugger inserts software traps in ARM/Thumb code, it will
+ // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
+ // instructions respectively. If your debugger inserts a 16 bit thumb
+ // trap on top of a 32 bit thumb instruction for an opcode that is inside
+ // an if/then, it will change the it/then to conditionally execute your
+ // 16 bit trap and then cause your program to crash if it executes the
+ // trailing 16 bits (the second half of the 32 bit thumb instruction you
+ // partially overwrote).
+
+ RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
+ if (reg_ctx_sp)
+ {
+ const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
+ if (cpsr != 0)
+ {
+ // Read the J and T bits to get the ISETSTATE
+ const uint32_t J = Bit32(cpsr, 24);
+ const uint32_t T = Bit32(cpsr, 5);
+ const uint32_t ISETSTATE = J << 1 | T;
+ if (ISETSTATE == 0)
+ {
+ // NOTE: I am pretty sure we want to enable the code below
+ // that detects when we stop on an instruction in ARM mode
+ // that is conditional and the condition doesn't pass. This
+ // can happen if you set a breakpoint on an instruction that
+ // is conditional. We currently will _always_ stop on the
+ // instruction which is bad. You can also run into this while
+ // single stepping and you could appear to run code in the "if"
+ // and in the "else" clause because it would stop at all of the
+ // conditional instructions in both.
+ // In such cases, we really don't want to stop at this location.
+ // I will check with the lldb-dev list first before I enable this.
+#if 0
+ // ARM mode: check for condition on intsruction
+ const addr_t pc = reg_ctx_sp->GetPC();
+ Error error;
+ // If we fail to read the opcode we will get UINT64_MAX as the
+ // result in "opcode" which we can use to detect if we read a
+ // valid opcode.
+ const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
+ if (opcode <= UINT32_MAX)
+ {
+ const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
+ if (ARMConditionPassed(condition, cpsr) == false)
+ {
+ // We ARE stopped on an ARM instruction whose condition doesn't
+ // pass so this instruction won't get executed.
+ // Regardless of why it stopped, we need to clear the stop info
+ thread.SetStopInfo (StopInfoSP());
+ }
+ }
+#endif
+ }
+ else if (ISETSTATE == 1)
+ {
+ // Thumb mode
+ const uint32_t ITSTATE = Bits32 (cpsr, 15, 10) << 2 | Bits32 (cpsr, 26, 25);
+ if (ITSTATE != 0)
+ {
+ const uint32_t condition = Bits32(ITSTATE, 7, 4);
+ if (ARMConditionPassed(condition, cpsr) == false)
+ {
+ // We ARE stopped in a Thumb IT instruction on an instruction whose
+ // condition doesn't pass so this instruction won't get executed.
+ // Regardless of why it stopped, we need to clear the stop info
+ thread.SetStopInfo (StopInfoSP());
+ }
+ }
+ }
+ }
+ }
+}
+
+ArchSpec::StopInfoOverrideCallbackType
+ArchSpec::GetStopInfoOverrideCallback () const
+{
+ const llvm::Triple::ArchType machine = GetMachine();
+ if (machine == llvm::Triple::arm)
+ return StopInfoOverrideCallbackTypeARM;
+ return NULL;
+}
diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp
index d71c9881a6f3..ea84843fe0b3 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -18,6 +18,8 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Event.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ThreadLauncher.h"
#include <string.h>
using namespace lldb;
@@ -36,7 +38,6 @@ Communication::GetStaticBroadcasterClass ()
Communication::Communication(const char *name) :
Broadcaster (NULL, name),
m_connection_sp (),
- m_read_thread (LLDB_INVALID_HOST_THREAD),
m_read_thread_enabled (false),
m_bytes(),
m_bytes_mutex (Mutex::eMutexTypeRecursive),
@@ -232,7 +233,7 @@ Communication::StartReadThread (Error *error_ptr)
if (error_ptr)
error_ptr->Clear();
- if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
+ if (m_read_thread.IsJoinable())
return true;
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
@@ -243,8 +244,8 @@ Communication::StartReadThread (Error *error_ptr)
snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
m_read_thread_enabled = true;
- m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr);
- if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
+ m_read_thread = ThreadLauncher::LaunchThread(thread_name, Communication::ReadThread, this, error_ptr);
+ if (!m_read_thread.IsJoinable())
m_read_thread_enabled = false;
return m_read_thread_enabled;
}
@@ -252,7 +253,7 @@ Communication::StartReadThread (Error *error_ptr)
bool
Communication::StopReadThread (Error *error_ptr)
{
- if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
+ if (!m_read_thread.IsJoinable())
return true;
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
@@ -262,22 +263,20 @@ Communication::StopReadThread (Error *error_ptr)
BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL);
- //Host::ThreadCancel (m_read_thread, error_ptr);
+ // error = m_read_thread.Cancel();
- bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
- m_read_thread = LLDB_INVALID_HOST_THREAD;
- return status;
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
bool
Communication::JoinReadThread (Error *error_ptr)
{
- if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
+ if (!m_read_thread.IsJoinable())
return true;
- bool success = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
- m_read_thread = LLDB_INVALID_HOST_THREAD;
- return success;
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
size_t
diff --git a/source/Core/Connection.cpp b/source/Core/Connection.cpp
index 3c9bb8b1b7ed..3f740a1ed82a 100644
--- a/source/Core/Connection.cpp
+++ b/source/Core/Connection.cpp
@@ -13,6 +13,12 @@
// Project includes
#include "lldb/Core/Connection.h"
+#if defined(_WIN32)
+#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
+#endif
+
+#include "lldb/Host/ConnectionFileDescriptor.h"
+
using namespace lldb_private;
Connection::Connection ()
@@ -22,3 +28,13 @@ Connection::Connection ()
Connection::~Connection ()
{
}
+
+Connection *
+Connection::CreateDefaultConnection(const char *url)
+{
+#if defined(_WIN32)
+ if (strstr(url, "file://") == url)
+ return new ConnectionGenericFile();
+#endif
+ return new ConnectionFileDescriptor();
+}
diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp
index 5db3d687cdb2..1cbee20cd94a 100644
--- a/source/Core/ConnectionSharedMemory.cpp
+++ b/source/Core/ConnectionSharedMemory.cpp
@@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#ifndef __ANDROID_NDK__
#include "lldb/Core/ConnectionSharedMemory.h"
@@ -156,3 +157,4 @@ ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error
return eConnectionStatusError;
}
+#endif // __ANDROID_NDK__
diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp
index 5657b483a495..37d24e0dec00 100644
--- a/source/Core/ConstString.cpp
+++ b/source/Core/ConstString.cpp
@@ -11,6 +11,8 @@
#include "lldb/Host/Mutex.h"
#include "llvm/ADT/StringMap.h"
+#include <mutex>
+
using namespace lldb_private;
@@ -93,7 +95,7 @@ public:
{
Mutex::Locker locker (m_mutex);
llvm::StringRef string_ref (cstr, cstr_len);
- StringPoolEntryType& entry = m_string_map.GetOrCreateValue (string_ref, (StringPoolValueType)NULL);
+ StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first;
return entry.getKeyData();
}
return NULL;
@@ -105,7 +107,7 @@ public:
if (string_ref.data())
{
Mutex::Locker locker (m_mutex);
- StringPoolEntryType& entry = m_string_map.GetOrCreateValue (string_ref, (StringPoolValueType)NULL);
+ StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first;
return entry.getKeyData();
}
return NULL;
@@ -118,7 +120,7 @@ public:
{
Mutex::Locker locker (m_mutex);
// Make string pool entry with the mangled counterpart already set
- StringPoolEntryType& entry = m_string_map.GetOrCreateValue (llvm::StringRef (demangled_cstr), mangled_ccstr);
+ StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (llvm::StringRef (demangled_cstr), mangled_ccstr)).first;
// Extract the const version of the demangled_cstr
const char *demangled_ccstr = entry.getKeyData();
@@ -184,25 +186,16 @@ protected:
// we can't guarantee that some objects won't get destroyed after the
// global destructor chain is run, and trying to make sure no destructors
// touch ConstStrings is difficult. So we leak the pool instead.
-//
-// FIXME: If we are going to keep it this way we should come up with some
-// abstraction to "pthread_once" so we don't have to check the pointer
-// every time.
//----------------------------------------------------------------------
static Pool &
StringPool()
{
- static Mutex g_pool_initialization_mutex;
+ static std::once_flag g_pool_initialization_flag;
static Pool *g_string_pool = NULL;
- if (g_string_pool == NULL)
- {
- Mutex::Locker initialization_locker(g_pool_initialization_mutex);
- if (g_string_pool == NULL)
- {
- g_string_pool = new Pool();
- }
- }
+ std::call_once(g_pool_initialization_flag, [] () {
+ g_string_pool = new Pool();
+ });
return *g_string_pool;
}
diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp
index a0958bd6b1c6..6e1d63095cf3 100644
--- a/source/Core/DataExtractor.cpp
+++ b/source/Core/DataExtractor.cpp
@@ -22,7 +22,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MathExtras.h"
-
+#include "llvm/Support/MD5.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
@@ -132,7 +132,8 @@ DataExtractor::DataExtractor () :
m_end (NULL),
m_byte_order(lldb::endian::InlHostByteOrder()),
m_addr_size (4),
- m_data_sp ()
+ m_data_sp (),
+ m_target_byte_size(1)
{
}
@@ -140,12 +141,13 @@ DataExtractor::DataExtractor () :
// This constructor allows us to use data that is owned by someone else.
// The data must stay around as long as this object is valid.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endian, uint32_t addr_size) :
+DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
m_start ((uint8_t*)data),
m_end ((uint8_t*)data + length),
m_byte_order(endian),
m_addr_size (addr_size),
- m_data_sp ()
+ m_data_sp (),
+ m_target_byte_size(target_byte_size)
{
}
@@ -156,12 +158,13 @@ DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endia
// as long as any DataExtractor objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size) :
+DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
m_start (NULL),
m_end (NULL),
m_byte_order(endian),
m_addr_size (addr_size),
- m_data_sp ()
+ m_data_sp (),
+ m_target_byte_size(target_byte_size)
{
SetData (data_sp);
}
@@ -173,12 +176,13 @@ DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uin
// as any object contains a reference to that data. The endian
// swap and address size settings are copied from "data".
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset_t length) :
+DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset_t length, uint32_t target_byte_size/*=1*/) :
m_start(NULL),
m_end(NULL),
m_byte_order(data.m_byte_order),
m_addr_size(data.m_addr_size),
- m_data_sp()
+ m_data_sp(),
+ m_target_byte_size(target_byte_size)
{
if (data.ValidOffset(offset))
{
@@ -194,7 +198,8 @@ DataExtractor::DataExtractor (const DataExtractor& rhs) :
m_end (rhs.m_end),
m_byte_order (rhs.m_byte_order),
m_addr_size (rhs.m_addr_size),
- m_data_sp (rhs.m_data_sp)
+ m_data_sp (rhs.m_data_sp),
+ m_target_byte_size(rhs.m_target_byte_size)
{
}
@@ -1480,7 +1485,9 @@ DataExtractor::Dump (Stream *s,
s->EOL();
}
if (base_addr != LLDB_INVALID_ADDRESS)
- s->Printf ("0x%8.8" PRIx64 ": ", (uint64_t)(base_addr + (offset - start_offset)));
+ s->Printf ("0x%8.8" PRIx64 ": ",
+ (uint64_t)(base_addr + (offset - start_offset)/m_target_byte_size ));
+
line_start_offset = offset;
}
else
@@ -1535,6 +1542,7 @@ DataExtractor::Dump (Stream *s,
{
s->Printf ("%2.2x", GetU8(&offset));
}
+
// Put an extra space between the groups of bytes if more than one
// is being dumped in a group (item_byte_size is more than 1).
if (item_byte_size > 1)
@@ -2230,3 +2238,27 @@ DataExtractor::Append(void* buf, offset_t length)
return true;
}
+
+void
+DataExtractor::Checksum (llvm::SmallVectorImpl<uint8_t> &dest,
+ uint64_t max_data)
+{
+ if (max_data == 0)
+ max_data = GetByteSize();
+ else
+ max_data = std::min(max_data, GetByteSize());
+
+ llvm::MD5 md5;
+
+ const llvm::ArrayRef<uint8_t> data(GetDataStart(),max_data);
+ md5.update(data);
+
+ llvm::MD5::MD5Result result;
+ md5.final(result);
+
+ dest.resize(16);
+ std::copy(result,
+ result+16,
+ dest.begin());
+}
+
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 178296347677..c7342ade6cad 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include "lldb/lldb-private.h"
-#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
@@ -34,8 +33,10 @@
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Terminal.h"
+#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueSInt64.h"
#include "lldb/Interpreter/OptionValueString.h"
@@ -44,6 +45,8 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -61,6 +64,7 @@ using namespace lldb_private;
static uint32_t g_shared_debugger_refcount = 0;
static lldb::user_id_t g_unique_id = 1;
+static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
#pragma mark Static Functions
@@ -121,12 +125,13 @@ g_language_enumerators[] =
FILE_AND_LINE\
"\\n"
-
+#define DEFAULT_DISASSEMBLY_FORMAT "${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: "
static PropertyDefinition
g_properties[] =
{
{ "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
+{ "disassembly-format", OptionValue::eTypeString , true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
{ "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
{ "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
@@ -139,7 +144,8 @@ g_properties[] =
{ "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
{ "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
{ "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
-{ "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
+{ "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
+{ "escape-non-printables", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
{ NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL }
};
@@ -147,6 +153,7 @@ g_properties[] =
enum
{
ePropertyAutoConfirm = 0,
+ ePropertyDisassemblyFormat,
ePropertyFrameFormat,
ePropertyNotiftVoid,
ePropertyPrompt,
@@ -159,7 +166,8 @@ enum
ePropertyThreadFormat,
ePropertyUseExternalEditor,
ePropertyUseColor,
- ePropertyAutoOneLineSummaries
+ ePropertyAutoOneLineSummaries,
+ ePropertyEscapeNonPrintables
};
Debugger::LoadPluginCallbackType Debugger::g_load_plugin_callback = NULL;
@@ -171,6 +179,7 @@ Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
const char *value)
{
bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
+ bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
TargetSP target_sp;
LoadScriptFromSymFile load_script_old_value;
if (is_load_script && exe_ctx->GetTargetSP())
@@ -218,6 +227,10 @@ Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
}
}
}
+ else if (is_escape_non_printables)
+ {
+ DataVisualization::ForceUpdate();
+ }
}
return error;
}
@@ -230,6 +243,13 @@ Debugger::GetAutoConfirm () const
}
const char *
+Debugger::GetDisassemblyFormat() const
+{
+ const uint32_t idx = ePropertyDisassemblyFormat;
+ return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
+}
+
+const char *
Debugger::GetFrameFormat() const
{
const uint32_t idx = ePropertyFrameFormat;
@@ -353,7 +373,13 @@ Debugger::GetAutoOneLineSummaries () const
{
const uint32_t idx = ePropertyAutoOneLineSummaries;
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
+}
+bool
+Debugger::GetEscapeNonPrintables () const
+{
+ const uint32_t idx = ePropertyEscapeNonPrintables;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true);
}
#pragma mark Debugger
@@ -620,24 +646,25 @@ Debugger::FindTargetWithProcess (Process *process)
return target_sp;
}
-Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
- UserID (g_unique_id++),
- Properties(OptionValuePropertiesSP(new OptionValueProperties())),
- m_input_file_sp (new StreamFile (stdin, false)),
- m_output_file_sp (new StreamFile (stdout, false)),
- m_error_file_sp (new StreamFile (stderr, false)),
- m_terminal_state (),
- m_target_list (*this),
- m_platform_list (),
- m_listener ("lldb.Debugger"),
+Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
+ UserID(g_unique_id++),
+ Properties(OptionValuePropertiesSP(new OptionValueProperties())),
+ m_input_file_sp(new StreamFile(stdin, false)),
+ m_output_file_sp(new StreamFile(stdout, false)),
+ m_error_file_sp(new StreamFile(stderr, false)),
+ m_terminal_state(),
+ m_target_list(*this),
+ m_platform_list(),
+ m_listener("lldb.Debugger"),
m_source_manager_ap(),
m_source_file_cache(),
- m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
- m_input_reader_stack (),
- m_instance_name (),
- m_loaded_plugins (),
- m_event_handler_thread (LLDB_INVALID_HOST_THREAD),
- m_io_handler_thread (LLDB_INVALID_HOST_THREAD)
+ m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
+ m_input_reader_stack(),
+ m_instance_name(),
+ m_loaded_plugins(),
+ m_event_handler_thread (),
+ m_io_handler_thread (),
+ m_sync_broadcaster (NULL, "lldb.debugger.sync")
{
char instance_cstr[256];
snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
@@ -646,7 +673,7 @@ Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) :
m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
m_command_interpreter_ap->Initialize ();
// Always add our default platform to the platform list
- PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
+ PlatformSP default_platform_sp (Platform::GetHostPlatform());
assert (default_platform_sp.get());
m_platform_list.Append (default_platform_sp, true);
@@ -903,7 +930,6 @@ Debugger::GetTopIOHandlerControlSequence(char ch)
void
Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
{
- Mutex::Locker locker (m_input_reader_stack.GetMutex());
PushIOHandler (reader_sp);
IOHandlerSP top_reader_sp = reader_sp;
@@ -1129,6 +1155,8 @@ TestPromptFormats (StackFrame *frame)
StreamString s;
const char *prompt_format =
"{addr = '${addr}'\n}"
+ "{addr-file-or-load = '${addr-file-or-load}'\n}"
+ "{current-pc-arrow = '${current-pc-arrow}'\n}"
"{process.id = '${process.id}'\n}"
"{process.name = '${process.name}'\n}"
"{process.file.basename = '${process.file.basename}'\n}"
@@ -1156,9 +1184,13 @@ TestPromptFormats (StackFrame *frame)
"{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
"{frame.reg.carp = '${frame.reg.carp}'\n}"
"{function.id = '${function.id}'\n}"
+ "{function.changed = '${function.changed}'\n}"
+ "{function.initial-function = '${function.initial-function}'\n}"
"{function.name = '${function.name}'\n}"
+ "{function.name-without-args = '${function.name-without-args}'\n}"
"{function.name-with-args = '${function.name-with-args}'\n}"
"{function.addr-offset = '${function.addr-offset}'\n}"
+ "{function.concrete-only-addr-offset-no-padding = '${function.concrete-only-addr-offset-no-padding}'\n}"
"{function.line-offset = '${function.line-offset}'\n}"
"{function.pc-offset = '${function.pc-offset}'\n}"
"{line.file.basename = '${line.file.basename}'\n}"
@@ -1556,7 +1588,9 @@ FormatPromptRecurse
const Address *addr,
Stream &s,
const char **end,
- ValueObject* valobj
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function
)
{
ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
@@ -1598,7 +1632,7 @@ FormatPromptRecurse
++p; // Skip the '{'
- if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
+ if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
{
// The stream had all it needed
s.Write(sub_strm.GetData(), sub_strm.GetSize());
@@ -1632,6 +1666,12 @@ FormatPromptRecurse
const char *cstr = NULL;
std::string token_format;
Address format_addr;
+
+ // normally "addr" means print a raw address but
+ // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
+ bool print_file_addr_or_load_addr = false;
+ bool addr_offset_concrete_func_only = false;
+ bool addr_offset_print_with_no_padding = false;
bool calculate_format_addr_function_offset = false;
// Set reg_kind and reg_num to invalid values
RegisterKind reg_kind = kNumRegisterKinds;
@@ -1710,6 +1750,15 @@ FormatPromptRecurse
target = valobj;
val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
}
+ else if (IsToken (var_name_begin, "var.script:"))
+ {
+ var_name_begin += ::strlen("var.script:");
+ std::string script_name(var_name_begin,var_name_end);
+ ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
+ var_success = true;
+ break;
+ }
else if (IsToken (var_name_begin,"var%"))
{
was_var_format = true;
@@ -1778,6 +1827,7 @@ FormatPromptRecurse
log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
" final_value_type %d",
first_unparsed, reason_to_stop, final_value_type);
+ target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
}
}
else
@@ -1826,8 +1876,8 @@ FormatPromptRecurse
// TODO use flags for these
const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
- bool is_array = (type_info_flags & ClangASTType::eTypeIsArray) != 0;
- bool is_pointer = (type_info_flags & ClangASTType::eTypeIsPointer) != 0;
+ bool is_array = (type_info_flags & eTypeIsArray) != 0;
+ bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
bool is_aggregate = target->GetClangType().IsAggregateType();
if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
@@ -1942,7 +1992,7 @@ FormatPromptRecurse
if (!special_directions)
var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
else
- var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item);
+ var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
if (--max_num_children == 0)
{
@@ -1958,7 +2008,12 @@ FormatPromptRecurse
}
break;
case 'a':
- if (IsToken (var_name_begin, "addr}"))
+ if (IsToken (var_name_begin, "addr-file-or-load}"))
+ {
+ print_file_addr_or_load_addr = true;
+ }
+ if (IsToken (var_name_begin, "addr}")
+ || IsToken (var_name_begin, "addr-file-or-load}"))
{
if (addr && addr->IsValid())
{
@@ -2160,8 +2215,7 @@ FormatPromptRecurse
}
}
break;
-
-
+
case 'm':
if (IsToken (var_name_begin, "module."))
{
@@ -2289,6 +2343,14 @@ FormatPromptRecurse
var_success = true;
}
+ if (IsToken (var_name_begin, "changed}") && function_changed)
+ {
+ var_success = true;
+ }
+ if (IsToken (var_name_begin, "initial-function}") && initial_function)
+ {
+ var_success = true;
+ }
else if (IsToken (var_name_begin, "name}"))
{
if (sc->function)
@@ -2315,6 +2377,19 @@ FormatPromptRecurse
var_success = true;
}
}
+ else if (IsToken (var_name_begin, "name-without-args}"))
+ {
+ ConstString name;
+ if (sc->function)
+ name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
+ else if (sc->symbol)
+ name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
+ if (name)
+ {
+ s.PutCString(name.GetCString());
+ var_success = true;
+ }
+ }
else if (IsToken (var_name_begin, "name-with-args}"))
{
// Print the function name with arguments in it
@@ -2418,7 +2493,7 @@ FormatPromptRecurse
.SetHideItemNames(false)
.SetShowMembersOneLiner(true),
"");
- format.FormatObject(var_value_sp.get(), buffer);
+ format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
var_representation = buffer.c_str();
}
else
@@ -2458,8 +2533,14 @@ FormatPromptRecurse
}
}
}
- else if (IsToken (var_name_begin, "addr-offset}"))
+ else if (IsToken (var_name_begin, "addr-offset}")
+ || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
{
+ if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
+ {
+ addr_offset_print_with_no_padding = true;
+ addr_offset_concrete_func_only = true;
+ }
var_success = addr != NULL;
if (var_success)
{
@@ -2530,6 +2611,35 @@ FormatPromptRecurse
}
}
break;
+ case 'c':
+ if (IsToken (var_name_begin, "current-pc-arrow"))
+ {
+ if (addr && exe_ctx && exe_ctx->GetFramePtr())
+ {
+ RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
+ if (reg_ctx.get())
+ {
+ addr_t pc_loadaddr = reg_ctx->GetPC();
+ if (pc_loadaddr != LLDB_INVALID_ADDRESS)
+ {
+ Address pc;
+ pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
+ if (pc == *addr)
+ {
+ s.Printf ("-> ");
+ var_success = true;
+ }
+ }
+ }
+ if (var_success == false)
+ {
+ s.Printf(" ");
+ var_success = true;
+ }
+ }
+ var_success = true;
+ }
+ break;
}
if (var_success)
@@ -2587,7 +2697,7 @@ FormatPromptRecurse
if (sc->function)
{
func_addr = sc->function->GetAddressRange().GetBaseAddress();
- if (sc->block)
+ if (sc->block && addr_offset_concrete_func_only == false)
{
// Check to make sure we aren't in an inline
// function. If we are, use the inline block
@@ -2605,14 +2715,19 @@ FormatPromptRecurse
if (func_addr.IsValid())
{
+ const char *addr_offset_padding = " ";
+ if (addr_offset_print_with_no_padding)
+ {
+ addr_offset_padding = "";
+ }
if (func_addr.GetSection() == format_addr.GetSection())
{
addr_t func_file_addr = func_addr.GetFileAddress();
addr_t addr_file_addr = format_addr.GetFileAddress();
if (addr_file_addr > func_file_addr)
- s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
else if (addr_file_addr < func_file_addr)
- s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
var_success = true;
}
else
@@ -2623,9 +2738,9 @@ FormatPromptRecurse
addr_t func_load_addr = func_addr.GetLoadAddress (target);
addr_t addr_load_addr = format_addr.GetLoadAddress (target);
if (addr_load_addr > func_load_addr)
- s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
else if (addr_load_addr < func_load_addr)
- s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
var_success = true;
}
}
@@ -2642,10 +2757,21 @@ FormatPromptRecurse
if (vaddr != LLDB_INVALID_ADDRESS)
{
- int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
+ int addr_width = 0;
+ if (exe_ctx && target)
+ {
+ addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
+ }
if (addr_width == 0)
addr_width = 16;
- s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
+ if (print_file_addr_or_load_addr)
+ {
+ format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
+ }
+ else
+ {
+ s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
+ }
var_success = true;
}
}
@@ -2759,9 +2885,55 @@ Debugger::FormatPrompt
std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
if (format_str.length())
format = format_str.c_str();
- return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj);
+ return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
+}
+
+bool
+Debugger::FormatDisassemblerAddress (const char *format,
+ const SymbolContext *sc,
+ const SymbolContext *prev_sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ Stream &s)
+{
+ if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
+ {
+ format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ }
+ bool function_changed = false;
+ bool initial_function = false;
+ if (prev_sc && (prev_sc->function || prev_sc->symbol))
+ {
+ if (sc && (sc->function || sc->symbol))
+ {
+ if (prev_sc->symbol && sc->symbol)
+ {
+ if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
+ {
+ function_changed = true;
+ }
+ }
+ else if (prev_sc->function && sc->function)
+ {
+ if (prev_sc->function->GetMangled() != sc->function->GetMangled())
+ {
+ function_changed = true;
+ }
+ }
+ }
+ }
+ // The first context on a list of instructions will have a prev_sc that
+ // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
+ // would return false. But we do get a prev_sc pointer.
+ if ((sc && (sc->function || sc->symbol))
+ && prev_sc && (prev_sc->function == NULL && prev_sc->symbol == NULL))
+ {
+ initial_function = true;
+ }
+ return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
}
+
void
Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
{
@@ -2952,6 +3124,7 @@ Debugger::GetProcessSTDERR (Process *process, Stream *stream)
return total_bytes;
}
+
// This function handles events that were broadcast by the process.
void
Debugger::HandleProcessEvent (const EventSP &event_sp)
@@ -2959,7 +3132,7 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
using namespace lldb;
const uint32_t event_type = event_sp->GetType();
ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
-
+
StreamString output_stream;
StreamString error_stream;
const bool gui_enabled = IsForwardingEvents();
@@ -2968,191 +3141,27 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
{
bool pop_process_io_handler = false;
assert (process_sp);
-
+
if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged)
{
GetProcessSTDOUT (process_sp.get(), &output_stream);
}
-
+
if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged)
{
GetProcessSTDERR (process_sp.get(), &error_stream);
}
-
+
if (event_type & Process::eBroadcastBitStateChanged)
{
-
- // Drain all stout and stderr so we don't see any output come after
- // we print our prompts
- // Something changed in the process; get the event and report the process's current status and location to
- // the user.
- StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
- if (event_state == eStateInvalid)
- return;
-
- switch (event_state)
- {
- case eStateInvalid:
- case eStateUnloaded:
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateStepping:
- case eStateDetached:
- {
- output_stream.Printf("Process %" PRIu64 " %s\n",
- process_sp->GetID(),
- StateAsCString (event_state));
-
- if (event_state == eStateDetached)
- pop_process_io_handler = true;
- }
- break;
-
- case eStateRunning:
- // Don't be chatty when we run...
- break;
-
- case eStateExited:
- process_sp->GetStatus(output_stream);
- pop_process_io_handler = true;
- break;
-
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- // Make sure the program hasn't been auto-restarted:
- if (Process::ProcessEventData::GetRestartedFromEvent (event_sp.get()))
- {
- size_t num_reasons = Process::ProcessEventData::GetNumRestartedReasons(event_sp.get());
- if (num_reasons > 0)
- {
- // FIXME: Do we want to report this, or would that just be annoyingly chatty?
- if (num_reasons == 1)
- {
- const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0);
- output_stream.Printf("Process %" PRIu64 " stopped and restarted: %s\n",
- process_sp->GetID(),
- reason ? reason : "<UNKNOWN REASON>");
- }
- else
- {
- output_stream.Printf("Process %" PRIu64 " stopped and restarted, reasons:\n",
- process_sp->GetID());
-
-
- for (size_t i = 0; i < num_reasons; i++)
- {
- const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i);
- output_stream.Printf("\t%s\n", reason ? reason : "<UNKNOWN REASON>");
- }
- }
- }
- }
- else
- {
- // Lock the thread list so it doesn't change on us, this is the scope for the locker:
- {
- ThreadList &thread_list = process_sp->GetThreadList();
- Mutex::Locker locker (thread_list.GetMutex());
-
- ThreadSP curr_thread (thread_list.GetSelectedThread());
- ThreadSP thread;
- StopReason curr_thread_stop_reason = eStopReasonInvalid;
- if (curr_thread)
- curr_thread_stop_reason = curr_thread->GetStopReason();
- if (!curr_thread ||
- !curr_thread->IsValid() ||
- curr_thread_stop_reason == eStopReasonInvalid ||
- curr_thread_stop_reason == eStopReasonNone)
- {
- // Prefer a thread that has just completed its plan over another thread as current thread.
- ThreadSP plan_thread;
- ThreadSP other_thread;
- const size_t num_threads = thread_list.GetSize();
- size_t i;
- for (i = 0; i < num_threads; ++i)
- {
- thread = thread_list.GetThreadAtIndex(i);
- StopReason thread_stop_reason = thread->GetStopReason();
- switch (thread_stop_reason)
- {
- case eStopReasonInvalid:
- case eStopReasonNone:
- break;
-
- case eStopReasonTrace:
- case eStopReasonBreakpoint:
- case eStopReasonWatchpoint:
- case eStopReasonSignal:
- case eStopReasonException:
- case eStopReasonExec:
- case eStopReasonThreadExiting:
- if (!other_thread)
- other_thread = thread;
- break;
- case eStopReasonPlanComplete:
- if (!plan_thread)
- plan_thread = thread;
- break;
- }
- }
- if (plan_thread)
- thread_list.SetSelectedThreadByID (plan_thread->GetID());
- else if (other_thread)
- thread_list.SetSelectedThreadByID (other_thread->GetID());
- else
- {
- if (curr_thread && curr_thread->IsValid())
- thread = curr_thread;
- else
- thread = thread_list.GetThreadAtIndex(0);
-
- if (thread)
- thread_list.SetSelectedThreadByID (thread->GetID());
- }
- }
- }
- // Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code,
- // e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to
- // have a hard time restarting the process.
-
- if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget())
- {
- const bool only_threads_with_stop_reason = true;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- process_sp->GetStatus(output_stream);
- process_sp->GetThreadStatus (output_stream,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
- }
- else
- {
- uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this());
- if (target_idx != UINT32_MAX)
- output_stream.Printf ("Target %d: (", target_idx);
- else
- output_stream.Printf ("Target <unknown index>: (");
- process_sp->GetTarget().Dump (&output_stream, eDescriptionLevelBrief);
- output_stream.Printf (") stopped.\n");
- }
-
- // Pop the process IO handler
- pop_process_io_handler = true;
- }
- break;
- }
+ Process::HandleProcessStateChangedEvent (event_sp, &output_stream, pop_process_io_handler);
}
-
+
if (output_stream.GetSize() || error_stream.GetSize())
{
StreamFileSP error_stream_sp (GetOutputFile());
bool top_io_handler_hid = false;
-
+
if (process_sp->ProcessIOHandlerIsActive() == false)
top_io_handler_hid = HideTopIOHandler();
@@ -3245,17 +3254,14 @@ Debugger::DefaultEventHandler()
CommandInterpreter::eBroadcastBitQuitCommandReceived |
CommandInterpreter::eBroadcastBitAsynchronousOutputData |
CommandInterpreter::eBroadcastBitAsynchronousErrorData );
-
+
+ // Let the thread that spawned us know that we have started up and
+ // that we are now listening to all required events so no events get missed
+ m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
+
bool done = false;
while (!done)
{
-// Mutex::Locker locker;
-// if (locker.TryLock(m_input_reader_stack.GetMutex()))
-// {
-// if (m_input_reader_stack.IsEmpty())
-// break;
-// }
-//
EventSP event_sp;
if (listener.WaitForEvent(NULL, event_sp))
{
@@ -3337,19 +3343,38 @@ Debugger::EventHandlerThread (lldb::thread_arg_t arg)
bool
Debugger::StartEventHandlerThread()
{
- if (!IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
- m_event_handler_thread = Host::ThreadCreate("lldb.debugger.event-handler", EventHandlerThread, this, NULL);
- return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread);
+ if (!m_event_handler_thread.IsJoinable())
+ {
+ // We must synchronize with the DefaultEventHandler() thread to ensure
+ // it is up and running and listening to events before we return from
+ // this function. We do this by listening to events for the
+ // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
+ Listener listener("lldb.debugger.event-handler");
+ listener.StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
+
+ // Use larger 8MB stack for this thread
+ m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler", EventHandlerThread,
+ this,
+ NULL,
+ g_debugger_event_thread_stack_bytes);
+
+ // Make sure DefaultEventHandler() is running and listening to events before we return
+ // from this function. We are only listening for events of type
+ // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
+ // to wait an infinite amount of time for it (NULL timeout as the first parameter)
+ lldb::EventSP event_sp;
+ listener.WaitForEvent(NULL, event_sp);
+ }
+ return m_event_handler_thread.IsJoinable();
}
void
Debugger::StopEventHandlerThread()
{
- if (IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread))
+ if (m_event_handler_thread.IsJoinable())
{
GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
- Host::ThreadJoin(m_event_handler_thread, NULL, NULL);
- m_event_handler_thread = LLDB_INVALID_HOST_THREAD;
+ m_event_handler_thread.Join(nullptr);
}
}
@@ -3366,21 +3391,43 @@ Debugger::IOHandlerThread (lldb::thread_arg_t arg)
bool
Debugger::StartIOHandlerThread()
{
- if (!IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
- m_io_handler_thread = Host::ThreadCreate("lldb.debugger.io-handler", IOHandlerThread, this, NULL);
- return IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread);
+ if (!m_io_handler_thread.IsJoinable())
+ m_io_handler_thread = ThreadLauncher::LaunchThread ("lldb.debugger.io-handler",
+ IOHandlerThread,
+ this,
+ NULL,
+ 8*1024*1024); // Use larger 8MB stack for this thread
+ return m_io_handler_thread.IsJoinable();
}
void
Debugger::StopIOHandlerThread()
{
- if (IS_VALID_LLDB_HOST_THREAD(m_io_handler_thread))
+ if (m_io_handler_thread.IsJoinable())
{
if (m_input_file_sp)
m_input_file_sp->GetFile().Close();
- Host::ThreadJoin(m_io_handler_thread, NULL, NULL);
- m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
+ m_io_handler_thread.Join(nullptr);
}
}
+Target *
+Debugger::GetDummyTarget()
+{
+ return m_target_list.GetDummyTarget (*this).get();
+}
+
+Target *
+Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
+{
+ Target *target = nullptr;
+ if (!prefer_dummy)
+ {
+ target = m_target_list.GetSelectedTarget().get();
+ if (target)
+ return target;
+ }
+
+ return GetDummyTarget();
+}
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index 1d2b8cf04c32..649f0c5bcb26 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -410,17 +410,18 @@ Disassembler::PrintInstructions
SymbolContext prev_sc;
AddressRange sc_range;
const Address *pc_addr_ptr = NULL;
- ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
StackFrame *frame = exe_ctx.GetFramePtr();
TargetSP target_sp (exe_ctx.GetTargetSP());
SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
if (frame)
+ {
pc_addr_ptr = &frame->GetFrameCodeAddress();
+ }
const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
- for (size_t i=0; i<num_instructions_found; ++i)
+ for (size_t i = 0; i < num_instructions_found; ++i)
{
Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
if (inst)
@@ -447,7 +448,7 @@ Disassembler::PrintInstructions
if (offset != 0)
strm.EOL();
- sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
+ sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false);
strm.EOL();
if (sc.comp_unit && sc.line_entry.IsValid())
@@ -462,23 +463,6 @@ Disassembler::PrintInstructions
}
}
}
- else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
- {
- if (prev_sc.function || prev_sc.symbol)
- strm.EOL();
-
- bool show_fullpaths = false;
- bool show_module = true;
- bool show_inlined_frames = true;
- sc.DumpStopContext (&strm,
- exe_scope,
- addr,
- show_fullpaths,
- show_module,
- show_inlined_frames);
-
- strm << ":\n";
- }
}
else
{
@@ -486,12 +470,13 @@ Disassembler::PrintInstructions
}
}
- if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
+ const bool show_bytes = (options & eOptionShowBytes) != 0;
+ const char *disassembly_format = "${addr-file-or-load}: ";
+ if (exe_ctx.HasTargetScope())
{
- strm.PutCString(inst_is_at_pc ? "-> " : " ");
+ disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
}
- const bool show_bytes = (options & eOptionShowBytes) != 0;
- inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
+ inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, disassembly_format);
strm.EOL();
}
else
@@ -578,7 +563,10 @@ Instruction::Dump (lldb_private::Stream *s,
uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
- const ExecutionContext* exe_ctx)
+ const ExecutionContext* exe_ctx,
+ const SymbolContext *sym_ctx,
+ const SymbolContext *prev_sym_ctx,
+ const char *disassembly_addr_format_spec)
{
size_t opcode_column_width = 7;
const size_t operand_column_width = 25;
@@ -589,13 +577,7 @@ Instruction::Dump (lldb_private::Stream *s,
if (show_address)
{
- m_address.Dump(&ss,
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
- Address::DumpStyleLoadAddress,
- Address::DumpStyleModuleWithFileAddress,
- 0);
-
- ss.PutCString(": ");
+ Debugger::FormatDisassemblerAddress (disassembly_addr_format_spec, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
}
if (show_bytes)
@@ -621,7 +603,7 @@ Instruction::Dump (lldb_private::Stream *s,
}
}
- const size_t opcode_pos = ss.GetSize();
+ const size_t opcode_pos = ss.GetSizeOfLastLine();
// The default opcode size of 7 characters is plenty for most architectures
// but some like arm can pull out the occasional vqrshrun.s16. We won't get
@@ -1003,13 +985,18 @@ InstructionList::Dump (Stream *s,
{
const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
collection::const_iterator pos, begin, end;
+ const char *disassemble_format = "${addr-file-or-load}: ";
+ if (exe_ctx)
+ {
+ disassemble_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
+ }
for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
pos != end;
++pos)
{
if (pos != begin)
s->EOL();
- (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
+ (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassemble_format);
}
}
diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp
index 00a75425b689..53e8972e8048 100644
--- a/source/Core/FastDemangle.cpp
+++ b/source/Core/FastDemangle.cpp
@@ -18,7 +18,7 @@
//#define DEBUG_REORDERING 1
namespace {
-
+
/// @brief Represents the collection of qualifiers on a type
enum Qualifiers
@@ -51,7 +51,7 @@ enum class OperatorKind
struct Operator
{
- const char * name;
+ const char *name;
OperatorKind kind;
};
@@ -87,28 +87,28 @@ struct NameState
class SymbolDemangler
{
public:
-
+
//----------------------------------------------------
// Public API
//----------------------------------------------------
-
+
/// @brief Create a SymbolDemangler
///
/// The newly created demangler allocates and owns scratch memory sufficient
/// for demangling typical symbols. Additional memory will be allocated if
/// needed and managed by the demangler instance.
-
+
SymbolDemangler()
{
- buffer = (char *) malloc(8192);
- buffer_end = buffer + 8192;
- owns_buffer = true;
-
- rewrite_ranges = (BufferRange *) malloc(128 * sizeof(BufferRange));
- rewrite_ranges_size = 128;
- owns_rewrite_ranges = true;
+ m_buffer = (char *) malloc(8192);
+ m_buffer_end = m_buffer + 8192;
+ m_owns_buffer = true;
+
+ m_rewrite_ranges = (BufferRange *) malloc(128 * sizeof (BufferRange));
+ m_rewrite_ranges_size = 128;
+ m_owns_m_rewrite_ranges = true;
}
-
+
/// @brief Create a SymbolDemangler that uses provided scratch memory
///
/// The provided memory is not owned by the demangler. It will be
@@ -124,34 +124,36 @@ public:
///
/// @param storage_size Number of bytes of space available scratch memory
/// referenced by storage_ptr
-
- SymbolDemangler(void * storage_ptr, int storage_size)
+
+ SymbolDemangler(void *storage_ptr, int storage_size)
{
// Use up to 1/8th of the provided space for rewrite ranges
- rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange);
- rewrite_ranges = (BufferRange *) storage_ptr;
- owns_rewrite_ranges = false;
-
+ m_rewrite_ranges_size = (storage_size >> 3) / sizeof (BufferRange);
+ m_rewrite_ranges = (BufferRange *) storage_ptr;
+ m_owns_m_rewrite_ranges = false;
+
// Use the rest for the character buffer
- buffer = (char *) storage_ptr + rewrite_ranges_size * sizeof(BufferRange);
- buffer_end = (const char *)storage_ptr + storage_size;
- owns_buffer = false;
+ m_buffer = (char *) storage_ptr + m_rewrite_ranges_size * sizeof (BufferRange);
+ m_buffer_end = (const char *)storage_ptr + storage_size;
+ m_owns_buffer = false;
}
-
+
/// @brief Destroys the SymbolDemangler and deallocates any scratch
/// memory that it owns
-
+
~SymbolDemangler()
{
- if (owns_buffer) free(buffer);
- if (owns_rewrite_ranges) free(rewrite_ranges);
+ if (m_owns_buffer)
+ free(m_buffer);
+ if (m_owns_m_rewrite_ranges)
+ free(m_rewrite_ranges);
}
-
+
#ifdef DEBUG_HIGHWATER
int highwater_store = 0;
int highwater_buffer = 0;
#endif
-
+
/// @brief Parses the provided mangled name and returns a newly allocated
/// demangling
///
@@ -161,293 +163,334 @@ public:
/// @result Newly allocated null-terminated demangled name when demangling
/// is succesful, and nullptr when demangling fails. The caller is
/// responsible for freeing the allocated memory.
-
- char * GetDemangledCopy(const char * mangled_name,
- long mangled_name_length = 0)
+
+ char *
+ GetDemangledCopy(const char *mangled_name,
+ long mangled_name_length = 0)
{
- if (!ParseMangling(mangled_name, mangled_name_length)) return nullptr;
-
+ if (!ParseMangling(mangled_name, mangled_name_length))
+ return nullptr;
+
#ifdef DEBUG_HIGHWATER
- int rewrite_count = next_substitute_index +
- (rewrite_ranges_size - 1 - next_template_arg_index);
- int buffer_size = (int)(write_ptr - buffer);
- if (rewrite_count > highwater_store) highwater_store = rewrite_count;
- if (buffer_size > highwater_buffer) highwater_buffer = buffer_size;
+ int rewrite_count = m_next_substitute_index +
+ (m_rewrite_ranges_size - 1 - m_next_template_arg_index);
+ int buffer_size = (int)(m_write_ptr - m_buffer);
+ if (rewrite_count > highwater_store)
+ highwater_store = rewrite_count;
+ if (buffer_size > highwater_buffer)
+ highwater_buffer = buffer_size;
#endif
-
- int length = (int)(write_ptr - buffer);
- char * copy = (char *)malloc(length + 1);
- memcpy(copy, buffer, length);
+
+ int length = (int)(m_write_ptr - m_buffer);
+ char *copy = (char *)malloc(length + 1);
+ memcpy(copy, m_buffer, length);
copy[length] = '\0';
return copy;
}
-
+
private:
-
+
//----------------------------------------------------
// Grow methods
//
// Manage the storage used during demangling
//----------------------------------------------------
-
+
void GrowBuffer(long min_growth = 0)
{
// By default, double the size of the buffer
- long growth = buffer_end - buffer;
-
+ long growth = m_buffer_end - m_buffer;
+
// Avoid growing by more than 1MB at a time
- if (growth > 1 << 20) growth = 1 << 20;
-
+ if (growth > 1 << 20)
+ growth = 1 << 20;
+
// ... but never grow by less than requested,
// or 1K, whichever is greater
- if (min_growth < 1024) min_growth = 1024;
- if (growth < min_growth) growth = min_growth;
-
- // Allocate the new buffer and migrate content
- long new_size = (buffer_end - buffer) + growth;
- char * new_buffer = (char *)malloc(new_size);
- memcpy(new_buffer, buffer, write_ptr - buffer);
- if (owns_buffer) free(buffer);
- owns_buffer = true;
-
+ if (min_growth < 1024)
+ min_growth = 1024;
+ if (growth < min_growth)
+ growth = min_growth;
+
+ // Allocate the new m_buffer and migrate content
+ long new_size = (m_buffer_end - m_buffer) + growth;
+ char *new_buffer = (char *) malloc(new_size);
+ memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer);
+ if (m_owns_buffer)
+ free(m_buffer);
+ m_owns_buffer = true;
+
// Update references to the new buffer
- write_ptr = new_buffer + (write_ptr - buffer);
- buffer = new_buffer;
- buffer_end = buffer + new_size;
+ m_write_ptr = new_buffer + (m_write_ptr - m_buffer);
+ m_buffer = new_buffer;
+ m_buffer_end = m_buffer + new_size;
}
-
- void GrowRewriteRanges()
+
+ void
+ GrowRewriteRanges()
{
// By default, double the size of the array
- int growth = rewrite_ranges_size;
-
+ int growth = m_rewrite_ranges_size;
+
// Apply reasonable minimum and maximum sizes for growth
- if (growth > 128) growth = 128;
- if (growth < 16) growth = 16;
-
+ if (growth > 128)
+ growth = 128;
+ if (growth < 16)
+ growth = 16;
+
// Allocate the new array and migrate content
- int bytes = (rewrite_ranges_size + growth) * sizeof(BufferRange);
- BufferRange * new_ranges = (BufferRange *) malloc(bytes);
- for (int index = 0; index < next_substitute_index; index++)
+ int bytes = (m_rewrite_ranges_size + growth) * sizeof (BufferRange);
+ BufferRange *new_ranges = (BufferRange *) malloc (bytes);
+ for (int index = 0; index < m_next_substitute_index; index++)
{
- new_ranges[index] = rewrite_ranges[index];
+ new_ranges[index] = m_rewrite_ranges[index];
}
- for (int index = rewrite_ranges_size - 1;
- index > next_template_arg_index; index--)
+ for (int index = m_rewrite_ranges_size - 1;
+ index > m_next_template_arg_index; index--)
{
- new_ranges[index + growth] = rewrite_ranges[index];
+ new_ranges[index + growth] = m_rewrite_ranges[index];
}
- if (owns_rewrite_ranges) free(rewrite_ranges);
- owns_rewrite_ranges = true;
-
+ if (m_owns_m_rewrite_ranges)
+ free(m_rewrite_ranges);
+ m_owns_m_rewrite_ranges = true;
+
// Update references to the new array
- rewrite_ranges = new_ranges;
- rewrite_ranges_size += growth;
- next_template_arg_index += growth;
+ m_rewrite_ranges = new_ranges;
+ m_rewrite_ranges_size += growth;
+ m_next_template_arg_index += growth;
}
-
+
//----------------------------------------------------
// Range and state management
//----------------------------------------------------
-
- int GetStartCookie()
+
+ int
+ GetStartCookie()
{
- return (int)(write_ptr - buffer);
+ return (int)(m_write_ptr - m_buffer);
}
-
- BufferRange EndRange(int start_cookie)
+
+ BufferRange
+ EndRange(int start_cookie)
{
- return { start_cookie, (int)(write_ptr - (buffer + start_cookie)) };
+ return { start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie)) };
}
-
- void ReorderRange(BufferRange source_range, int insertion_point_cookie)
+
+ void
+ ReorderRange(BufferRange source_range, int insertion_point_cookie)
{
// Ensure there's room the preserve the source range
- if (write_ptr + source_range.length > buffer_end)
+ if (m_write_ptr + source_range.length > m_buffer_end)
{
- GrowBuffer(write_ptr + source_range.length - buffer_end);
+ GrowBuffer(m_write_ptr + source_range.length - m_buffer_end);
}
-
+
// Reorder the content
- memcpy(write_ptr, buffer + source_range.offset, source_range.length);
- memmove(buffer + insertion_point_cookie + source_range.length,
- buffer + insertion_point_cookie,
+ memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length);
+ memmove(m_buffer + insertion_point_cookie + source_range.length,
+ m_buffer + insertion_point_cookie,
source_range.offset - insertion_point_cookie);
- memcpy(buffer + insertion_point_cookie, write_ptr, source_range.length);
-
+ memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length);
+
// Fix up rewritable ranges, covering both substitutions and templates
int index = 0;
while (true)
{
- if (index == next_substitute_index) index = next_template_arg_index + 1;
- if (index == rewrite_ranges_size) break;
-
+ if (index == m_next_substitute_index)
+ index = m_next_template_arg_index + 1;
+ if (index == m_rewrite_ranges_size)
+ break;
+
// Affected ranges are either shuffled forward when after the
// insertion but before the source, or backward when inside the
// source
- int candidate_offset = rewrite_ranges[index].offset;
+ int candidate_offset = m_rewrite_ranges[index].offset;
if (candidate_offset >= insertion_point_cookie)
{
if (candidate_offset < source_range.offset)
{
- rewrite_ranges[index].offset += source_range.length;
+ m_rewrite_ranges[index].offset += source_range.length;
}
else if (candidate_offset >= source_range.offset)
{
- rewrite_ranges[index].offset -=
- (source_range.offset - insertion_point_cookie);
+ m_rewrite_ranges[index].offset -= (source_range.offset - insertion_point_cookie);
}
}
++index;
}
}
-
- void EndSubstitution(int start_cookie)
+
+ void
+ EndSubstitution(int start_cookie)
{
- if (next_substitute_index == next_template_arg_index) GrowRewriteRanges();
-
- int index = next_substitute_index++;
- rewrite_ranges[index] = EndRange(start_cookie);
+ if (m_next_substitute_index == m_next_template_arg_index)
+ GrowRewriteRanges();
+
+ int index = m_next_substitute_index++;
+ m_rewrite_ranges[index] = EndRange(start_cookie);
#ifdef DEBUG_SUBSTITUTIONS
printf("Saved substitution # %d = %.*s\n", index,
- rewrite_ranges[index].length, buffer + start_cookie);
+ m_rewrite_ranges[index].length, m_buffer + start_cookie);
#endif
}
-
- void EndTemplateArg(int start_cookie)
+
+ void
+ EndTemplateArg(int start_cookie)
{
- if (next_substitute_index == next_template_arg_index) GrowRewriteRanges();
-
- int index = next_template_arg_index--;
- rewrite_ranges[index] = EndRange(start_cookie);
+ if (m_next_substitute_index == m_next_template_arg_index)
+ GrowRewriteRanges();
+
+ int index = m_next_template_arg_index--;
+ m_rewrite_ranges[index] = EndRange(start_cookie);
#ifdef DEBUG_TEMPLATE_ARGS
printf("Saved template arg # %d = %.*s\n",
- rewrite_ranges_size - index - 1,
- rewrite_ranges[index].length, buffer + start_cookie);
+ m_rewrite_ranges_size - index - 1,
+ m_rewrite_ranges[index].length, m_buffer + start_cookie);
#endif
}
-
- void ResetTemplateArgs()
+
+ void
+ ResetTemplateArgs()
{
//TODO: this works, but is it the right thing to do?
// Should we push/pop somehow at the call sites?
- next_template_arg_index = rewrite_ranges_size - 1;
+ m_next_template_arg_index = m_rewrite_ranges_size - 1;
}
-
+
//----------------------------------------------------
// Write methods
//
// Appends content to the existing output buffer
//----------------------------------------------------
-
- void Write(char character)
+
+ void
+ Write(char character)
{
- if (write_ptr == buffer_end) GrowBuffer();
- *write_ptr++ = character;
+ if (m_write_ptr == m_buffer_end)
+ GrowBuffer();
+ *m_write_ptr++ = character;
}
-
- void Write(const char * content)
+
+ void
+ Write(const char *content)
{
Write(content, strlen(content));
}
-
- void Write(const char * content, long content_length)
+
+ void
+ Write(const char *content, long content_length)
{
- char * end_write_ptr = write_ptr + content_length;
- if (end_write_ptr > buffer_end)
+ char *end_m_write_ptr = m_write_ptr + content_length;
+ if (end_m_write_ptr > m_buffer_end)
{
- GrowBuffer(end_write_ptr - buffer_end);
- end_write_ptr = write_ptr + content_length;
+ GrowBuffer(end_m_write_ptr - m_buffer_end);
+ end_m_write_ptr = m_write_ptr + content_length;
}
- memcpy(write_ptr, content, content_length);
- write_ptr = end_write_ptr;
+ memcpy(m_write_ptr, content, content_length);
+ m_write_ptr = end_m_write_ptr;
}
-#define WRITE(x) Write(x, sizeof(x) - 1)
-
- void WriteTemplateStart()
+#define WRITE(x) Write(x, sizeof (x) - 1)
+
+ void
+ WriteTemplateStart()
{
Write('<');
}
-
- void WriteTemplateEnd()
+
+ void
+ WriteTemplateEnd()
{
// Put a space between terminal > characters when nesting templates
- if (write_ptr != buffer && *(write_ptr - 1) == '>') WRITE(" >");
+ if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>')
+ WRITE(" >");
else Write('>');
}
-
- void WriteCommaSpace()
+
+ void
+ WriteCommaSpace()
{
WRITE(", ");
}
-
- void WriteNamespaceSeparator()
+
+ void
+ WriteNamespaceSeparator()
{
WRITE("::");
}
-
- void WriteStdPrefix()
+
+ void
+ WriteStdPrefix()
{
WRITE("std::");
}
-
- void WriteQualifiers(int qualifiers, bool space_before_reference = true)
- {
- if (qualifiers & QualifierPointer) Write('*');
- if (qualifiers & QualifierConst) WRITE(" const");
- if (qualifiers & QualifierVolatile) WRITE(" volatile");
- if (qualifiers & QualifierRestrict) WRITE(" restrict");
+
+ void
+ WriteQualifiers(int qualifiers, bool space_before_reference = true)
+ {
+ if (qualifiers & QualifierPointer)
+ Write('*');
+ if (qualifiers & QualifierConst)
+ WRITE(" const");
+ if (qualifiers & QualifierVolatile)
+ WRITE(" volatile");
+ if (qualifiers & QualifierRestrict)
+ WRITE(" restrict");
if (qualifiers & QualifierReference)
{
- if (space_before_reference) WRITE(" &");
+ if (space_before_reference)
+ WRITE(" &");
else Write('&');
}
if (qualifiers & QualifierRValueReference)
{
- if (space_before_reference) WRITE(" &&");
+ if (space_before_reference)
+ WRITE(" &&");
else WRITE("&&");
}
}
-
+
//----------------------------------------------------
// Rewrite methods
//
// Write another copy of content already present
// earlier in the output buffer
//----------------------------------------------------
-
- void RewriteRange(BufferRange range)
+
+ void
+ RewriteRange(BufferRange range)
{
- Write(buffer + range.offset, range.length);
+ Write(m_buffer + range.offset, range.length);
}
-
- bool RewriteSubstitution(int index)
+
+ bool
+ RewriteSubstitution(int index)
{
- if (index < 0 || index >= next_substitute_index)
+ if (index < 0 || index >= m_next_substitute_index)
{
#ifdef DEBUG_FAILURES
printf("*** Invalid substitution #%d\n", index);
#endif
return false;
}
- RewriteRange(rewrite_ranges[index]);
+ RewriteRange(m_rewrite_ranges[index]);
return true;
}
-
- bool RewriteTemplateArg(int template_index)
+
+ bool
+ RewriteTemplateArg(int template_index)
{
- int index = rewrite_ranges_size - 1 - template_index;
- if (template_index < 0 || index <= next_template_arg_index)
+ int index = m_rewrite_ranges_size - 1 - template_index;
+ if (template_index < 0 || index <= m_next_template_arg_index)
{
#ifdef DEBUG_FAILURES
printf("*** Invalid template arg reference #%d\n", template_index);
#endif
return false;
}
- RewriteRange(rewrite_ranges[index]);
+ RewriteRange(m_rewrite_ranges[index]);
return true;
}
-
+
//----------------------------------------------------
// TryParse methods
//
@@ -455,45 +498,53 @@ private:
// writing to the output buffer
//
// Values indicating failure guarantee that the pre-
- // call read_ptr is unchanged
+ // call m_read_ptr is unchanged
//----------------------------------------------------
-
- int TryParseNumber()
+
+ int
+ TryParseNumber()
{
- unsigned char digit = *read_ptr - '0';
- if (digit > 9) return -1;
-
+ unsigned char digit = *m_read_ptr - '0';
+ if (digit > 9)
+ return -1;
+
int count = digit;
while (true)
{
- digit = *++read_ptr - '0';
- if (digit > 9) break;
-
+ digit = *++m_read_ptr - '0';
+ if (digit > 9)
+ break;
+
count = count * 10 + digit;
}
return count;
}
-
- int TryParseBase36Number()
+
+ int
+ TryParseBase36Number()
{
- char digit = *read_ptr;
+ char digit = *m_read_ptr;
int count;
- if (digit >= '0' && digit <= '9') count = digit -= '0';
- else if (digit >= 'A' && digit <= 'Z') count = digit -= ('A' - 10);
+ if (digit >= '0' && digit <= '9')
+ count = digit -= '0';
+ else if (digit >= 'A' && digit <= 'Z')
+ count = digit -= ('A' - 10);
else return -1;
-
+
while (true)
{
- digit = *++read_ptr;
- if (digit >= '0' && digit <= '9') digit -= '0';
- else if (digit >= 'A' && digit <= 'Z') digit -= ('A' - 10);
+ digit = *++m_read_ptr;
+ if (digit >= '0' && digit <= '9')
+ digit -= '0';
+ else if (digit >= 'A' && digit <= 'Z')
+ digit -= ('A' - 10);
else break;
-
+
count = count * 36 + digit;
}
return count;
}
-
+
// <builtin-type> ::= v # void
// ::= w # wchar_t
// ::= b # bool
@@ -524,10 +575,11 @@ private:
// ::= Da # auto (in dependent new-expressions)
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
// ::= u <source-name> # vendor extended type
-
- const char * TryParseBuiltinType()
+
+ const char *
+ TryParseBuiltinType()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'v': return "void";
case 'w': return "wchar_t";
@@ -552,7 +604,7 @@ private:
case 'z': return "...";
case 'D':
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'd': return "decimal64";
case 'e': return "decimal128";
@@ -564,14 +616,14 @@ private:
case 'c': return "decltype(auto)";
case 'n': return "std::nullptr_t";
default:
- --read_ptr;
+ --m_read_ptr;
}
}
}
- --read_ptr;
+ --m_read_ptr;
return nullptr;
}
-
+
// <operator-name>
// ::= aa # &&
// ::= ad # & (unary)
@@ -622,13 +674,14 @@ private:
// ::= rS # >>=
// ::= cv <type> # (cast)
// ::= v <digit> <source-name> # vendor extended operator
-
- Operator TryParseOperator()
+
+ Operator
+ TryParseOperator()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'a':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'a': return { "&&", OperatorKind::Binary };
case 'd': return { "&", OperatorKind::Unary };
@@ -636,20 +689,20 @@ private:
case 'N': return { "&=", OperatorKind::Binary };
case 'S': return { "=", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'c':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'l': return { "()", OperatorKind::Other };
case 'm': return { ",", OperatorKind::Other };
case 'o': return { "~", OperatorKind::Unary };
case 'v': return { nullptr, OperatorKind::ConversionOperator };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'd':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'a': return { " delete[]", OperatorKind::Other };
case 'e': return { "*", OperatorKind::Unary };
@@ -657,34 +710,34 @@ private:
case 'v': return { "/", OperatorKind::Binary };
case 'V': return { "/=", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'e':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'o': return { "^", OperatorKind::Binary };
case 'O': return { "^=", OperatorKind::Binary };
case 'q': return { "==", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'g':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'e': return { ">=", OperatorKind::Binary };
case 't': return { ">", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'i':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'x': return { "[]", OperatorKind::Other };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'l':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'e': return { "<=", OperatorKind::Binary };
case 's': return { "<<", OperatorKind::Binary };
@@ -692,10 +745,10 @@ private:
case 't': return { "<", OperatorKind::Binary };
// case 'i': return { "?", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'm':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'i': return { "-", OperatorKind::Binary };
case 'I': return { "-=", OperatorKind::Binary };
@@ -703,10 +756,10 @@ private:
case 'L': return { "*=", OperatorKind::Binary };
case 'm': return { "--", OperatorKind::Postfix };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'n':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'a': return { " new[]", OperatorKind::Other };
case 'e': return { "!=", OperatorKind::Binary };
@@ -714,19 +767,19 @@ private:
case 't': return { "!", OperatorKind::Unary };
case 'w': return { " new", OperatorKind::Other };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'o':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'o': return { "||", OperatorKind::Binary };
case 'r': return { "|", OperatorKind::Binary };
case 'R': return { "|=", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'p':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'm': return { "->*", OperatorKind::Binary };
case 's': return { "+", OperatorKind::Unary };
@@ -735,154 +788,161 @@ private:
case 'p': return { "++", OperatorKind::Postfix };
case 't': return { "->", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'q':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'u': return { "?", OperatorKind::Ternary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'r':
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'm': return { "%", OperatorKind::Binary };
case 'M': return { "%=", OperatorKind::Binary };
case 's': return { ">>", OperatorKind::Binary };
case 'S': return { ">=", OperatorKind::Binary };
}
- --read_ptr;
+ --m_read_ptr;
break;
case 'v':
- char digit = *read_ptr;
+ char digit = *m_read_ptr;
if (digit >= '0' && digit <= '9')
{
- read_ptr++;
+ m_read_ptr++;
return { nullptr, OperatorKind::Vendor };
}
- --read_ptr;
+ --m_read_ptr;
break;
}
- --read_ptr;
+ --m_read_ptr;
return { nullptr, OperatorKind::NoMatch };
}
-
+
// <CV-qualifiers> ::= [r] [V] [K]
// <ref-qualifier> ::= R # & ref-qualifier
// <ref-qualifier> ::= O # && ref-qualifier
-
- int TryParseQualifiers(bool allow_cv, bool allow_ro)
+
+ int
+ TryParseQualifiers(bool allow_cv, bool allow_ro)
{
int qualifiers = QualifierNone;
- char next = *read_ptr;
+ char next = *m_read_ptr;
if (allow_cv)
{
if (next == 'r') // restrict
{
qualifiers |= QualifierRestrict;
- next = *++read_ptr;
+ next = *++m_read_ptr;
}
if (next == 'V') // volatile
{
qualifiers |= QualifierVolatile;
- next = *++read_ptr;
+ next = *++m_read_ptr;
}
if (next == 'K') // const
{
qualifiers |= QualifierConst;
- next = *++read_ptr;
+ next = *++m_read_ptr;
}
}
if (allow_ro)
{
if (next == 'R')
{
- ++read_ptr;
+ ++m_read_ptr;
qualifiers |= QualifierReference;
}
else if (next =='O')
{
- ++read_ptr;
+ ++m_read_ptr;
qualifiers |= QualifierRValueReference;
}
}
return qualifiers;
}
-
+
// <discriminator> := _ <non-negative number> # when number < 10
// := __ <non-negative number> _ # when number >= 10
// extension := decimal-digit+
-
- int TryParseDiscriminator()
+
+ int
+ TryParseDiscriminator()
{
- const char * discriminator_start = read_ptr;
-
+ const char *discriminator_start = m_read_ptr;
+
// Test the extension first, since it's what Clang uses
int discriminator_value = TryParseNumber();
- if (discriminator_value != -1) return discriminator_value;
-
- char next = *read_ptr;
+ if (discriminator_value != -1)
+ return discriminator_value;
+
+ char next = *m_read_ptr;
if (next == '_')
{
- next = *++read_ptr;
+ next = *++m_read_ptr;
if (next == '_')
{
- ++read_ptr;
+ ++m_read_ptr;
discriminator_value = TryParseNumber();
- if (discriminator_value != -1 && *read_ptr++ != '_')
+ if (discriminator_value != -1 && *m_read_ptr++ != '_')
{
return discriminator_value;
}
}
else if (next >= '0' && next <= '9')
{
- ++read_ptr;
+ ++m_read_ptr;
return next - '0';
}
}
-
+
// Not a valid discriminator
- read_ptr = discriminator_start;
+ m_read_ptr = discriminator_start;
return -1;
}
-
+
//----------------------------------------------------
// Parse methods
//
- // Consume input starting from read_ptr and produce
- // buffered output at write_ptr
+ // Consume input starting from m_read_ptr and produce
+ // buffered output at m_write_ptr
//
- // Failures return false and may leave read_ptr in an
+ // Failures return false and may leave m_read_ptr in an
// indeterminate state
//----------------------------------------------------
-
- bool Parse(char character)
+
+ bool
+ Parse(char character)
{
- if (*read_ptr++ == character) return true;
+ if (*m_read_ptr++ == character)
+ return true;
#ifdef DEBUG_FAILURES
printf("*** Expected '%c'\n", character);
#endif
return false;
}
-
+
// <number> ::= [n] <non-negative decimal integer>
-
- bool ParseNumber(bool allow_negative = false)
+
+ bool
+ ParseNumber(bool allow_negative = false)
{
- if (allow_negative && *read_ptr == 'n')
+ if (allow_negative && *m_read_ptr == 'n')
{
Write('-');
- ++read_ptr;
+ ++m_read_ptr;
}
- const char * before_digits = read_ptr;
+ const char *before_digits = m_read_ptr;
while (true)
{
- unsigned char digit = *read_ptr - '0';
- if (digit > 9) break;
- ++read_ptr;
+ unsigned char digit = *m_read_ptr - '0';
+ if (digit > 9)
+ break;
+ ++m_read_ptr;
}
- if (int digit_count = (int)(read_ptr - before_digits))
+ if (int digit_count = (int)(m_read_ptr - before_digits))
{
Write(before_digits, digit_count);
return true;
@@ -892,7 +952,7 @@ private:
#endif
return false;
}
-
+
// <substitution> ::= S <seq-id> _
// ::= S_
// <substitution> ::= Sa # ::std::allocator
@@ -903,11 +963,12 @@ private:
// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
-
- bool ParseSubstitution()
+
+ bool
+ ParseSubstitution()
{
- const char * substitution;
- switch (*read_ptr)
+ const char *substitution;
+ switch (*m_read_ptr)
{
case 'a': substitution = "std::allocator"; break;
case 'b': substitution = "std::basic_string"; break;
@@ -919,25 +980,26 @@ private:
// A failed attempt to parse a number will return -1 which turns out to be
// perfect here as S_ is the first substitution, S0_ the next and so forth
int substitution_index = TryParseBase36Number();
- if (*read_ptr++ != '_')
+ if (*m_read_ptr++ != '_')
{
#ifdef DEBUG_FAILURES
printf("*** Expected terminal _ in substitution\n");
#endif
return false;
}
- return RewriteSubstitution(substitution_index + 1);
+ return RewriteSubstitution (substitution_index + 1);
}
Write(substitution);
- ++read_ptr;
+ ++m_read_ptr;
return true;
}
-
+
// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
//
// <bare-function-type> ::= <signature type>+ # types are possible return type, then parameter types
-
- bool ParseFunctionType(int inner_qualifiers = QualifierNone)
+
+ bool
+ ParseFunctionType (int inner_qualifiers = QualifierNone)
{
#ifdef DEBUG_FAILURES
printf("*** Function types not supported\n");
@@ -947,70 +1009,77 @@ private:
// int (*)() when used as the type for "name" becomes int (*name)().
// This makes substitution et al ... interesting.
return false;
-
- if (*read_ptr == 'Y') ++read_ptr;;
-
+
+#if 0 // TODO
+ if (*m_read_ptr == 'Y')
+ ++m_read_ptr;
+
int return_type_start_cookie = GetStartCookie();
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
Write(' ');
-
+
int insert_cookie = GetStartCookie();
Write('(');
bool first_param = true;
int qualifiers = QualifierNone;
while (true)
{
- switch (*read_ptr)
+ switch (*m_read_ptr)
{
case 'E':
- ++read_ptr;
+ ++m_read_ptr;
Write(')');
break;
case 'v':
- ++read_ptr;
+ ++m_read_ptr;
continue;
case 'R':
case 'O':
- if (*(read_ptr + 1) == 'E')
+ if (*(m_read_ptr + 1) == 'E')
{
- qualifiers = TryParseQualifiers(false, true);
+ qualifiers = TryParseQualifiers (false, true);
Parse('E');
break;
}
// fallthrough
default:
{
- if (first_param) first_param = false;
+ if (first_param)
+ first_param = false;
else WriteCommaSpace();
-
- if (!ParseType()) return false;
+
+ if (!ParseType())
+ return false;
continue;
}
}
break;
}
-
+
if (qualifiers)
{
- WriteQualifiers(qualifiers);
- EndSubstitution(return_type_start_cookie);
+ WriteQualifiers (qualifiers);
+ EndSubstitution (return_type_start_cookie);
}
-
+
if (inner_qualifiers)
{
int qualifier_start_cookie = GetStartCookie();
- Write('(');
- WriteQualifiers(inner_qualifiers);
- Write(')');
- ReorderRange(EndRange(qualifier_start_cookie), insert_cookie);
+ Write ('(');
+ WriteQualifiers (inner_qualifiers);
+ Write (')');
+ ReorderRange (EndRange (qualifier_start_cookie), insert_cookie);
}
return true;
+#endif // TODO
}
-
+
// <array-type> ::= A <positive dimension number> _ <element type>
// ::= A [<dimension expression>] _ <element type>
-
- bool ParseArrayType(int qualifiers = QualifierNone)
+
+ bool
+ ParseArrayType(int qualifiers = QualifierNone)
{
#ifdef DEBUG_FAILURES
printf("*** Array type unsupported\n");
@@ -1021,26 +1090,32 @@ private:
//
//TODO: Chances are we don't do any better with references and pointers
// that should be type (&) [] instead of type & []
-
+
return false;
-
- if (*read_ptr == '_')
+
+#if 0 // TODO
+ if (*m_read_ptr == '_')
{
- ++read_ptr;
- if (!ParseType()) return false;
- if (qualifiers) WriteQualifiers(qualifiers);
+ ++m_read_ptr;
+ if (!ParseType())
+ return false;
+ if (qualifiers)
+ WriteQualifiers(qualifiers);
WRITE(" []");
return true;
}
else
{
- const char * before_digits = read_ptr;
+ const char *before_digits = m_read_ptr;
if (TryParseNumber() != -1)
{
- const char * after_digits = read_ptr;
- if (!Parse('_')) return false;
- if (!ParseType()) return false;
- if (qualifiers) WriteQualifiers(qualifiers);
+ const char *after_digits = m_read_ptr;
+ if (!Parse('_'))
+ return false;
+ if (!ParseType())
+ return false;
+ if (qualifiers)
+ WriteQualifiers(qualifiers);
Write(' ');
Write('[');
Write(before_digits, after_digits - before_digits);
@@ -1048,51 +1123,61 @@ private:
else
{
int type_insertion_cookie = GetStartCookie();
- if (!ParseExpression()) return false;
- if (!Parse('_')) return false;
-
+ if (!ParseExpression())
+ return false;
+ if (!Parse('_'))
+ return false;
+
int type_start_cookie = GetStartCookie();
- if (!ParseType()) return false;
- if (qualifiers) WriteQualifiers(qualifiers);
+ if (!ParseType())
+ return false;
+ if (qualifiers)
+ WriteQualifiers(qualifiers);
Write(' ');
Write('[');
- ReorderRange(EndRange(type_start_cookie), type_insertion_cookie);
+ ReorderRange (EndRange (type_start_cookie), type_insertion_cookie);
}
Write(']');
return true;
}
+#endif // TODO
}
-
+
// <pointer-to-member-type> ::= M <class type> <member type>
-
+
//TODO: Determine how to handle pointers to function members correctly,
// currently not an issue because we don't have function types at all...
- bool ParsePointerToMemberType()
+ bool
+ ParsePointerToMemberType()
{
int insertion_cookie = GetStartCookie();
Write(' ');
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
WRITE("::*");
-
+
int type_cookie = GetStartCookie();
- if (!ParseType()) return false;
- ReorderRange(EndRange(type_cookie), insertion_cookie);
+ if (!ParseType())
+ return false;
+ ReorderRange (EndRange (type_cookie), insertion_cookie);
return true;
}
-
+
// <template-param> ::= T_ # first template parameter
// ::= T <parameter-2 non-negative number> _
-
- bool ParseTemplateParam()
+
+ bool
+ ParseTemplateParam()
{
int count = TryParseNumber();
- if (!Parse('_')) return false;
-
+ if (!Parse('_'))
+ return false;
+
// When no number is present we get -1, which is convenient since
// T_ is the zeroth element T0_ is element 1, and so on
- return RewriteTemplateArg(count + 1);
+ return RewriteTemplateArg (count + 1);
}
-
+
// <type> ::= <builtin-type>
// ::= <function-type>
// ::= <class-enum-type>
@@ -1112,27 +1197,29 @@ private:
// ::= U <source-name> <type> # vendor extended type qualifier
// extension := U <objc-name> <objc-type> # objc-type<identifier>
// extension := <vector-type> # <vector-type> starts with Dv
-
+
// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
-
- bool ParseType()
+
+ bool
+ ParseType()
{
#ifdef DEBUG_FAILURES
- const char * failed_type = read_ptr;
+ const char *failed_type = m_read_ptr;
#endif
int type_start_cookie = GetStartCookie();
bool suppress_substitution = false;
-
- int qualifiers = TryParseQualifiers(true, false);
- switch (*read_ptr)
+
+ int qualifiers = TryParseQualifiers (true, false);
+ switch (*m_read_ptr)
{
case 'D':
- ++read_ptr;
- switch (*read_ptr++)
+ ++m_read_ptr;
+ switch (*m_read_ptr++)
{
case 'p':
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
break;
case 'T':
case 't':
@@ -1145,44 +1232,52 @@ private:
}
break;
case 'T':
- ++read_ptr;
- if (!ParseTemplateParam()) return false;
+ ++m_read_ptr;
+ if (!ParseTemplateParam())
+ return false;
break;
case 'M':
- ++read_ptr;
- if (!ParsePointerToMemberType()) return false;
+ ++m_read_ptr;
+ if (!ParsePointerToMemberType())
+ return false;
break;
case 'A':
- ++read_ptr;
- if (!ParseArrayType()) return false;
+ ++m_read_ptr;
+ if (!ParseArrayType())
+ return false;
break;
case 'F':
- ++read_ptr;
- if (!ParseFunctionType()) return false;
+ ++m_read_ptr;
+ if (!ParseFunctionType())
+ return false;
break;
case 'S':
- if (*++read_ptr == 't')
+ if (*++m_read_ptr == 't')
{
- ++read_ptr;
+ ++m_read_ptr;
WriteStdPrefix();
- if (!ParseName()) return false;
+ if (!ParseName())
+ return false;
}
else
{
suppress_substitution = true;
- if (!ParseSubstitution()) return false;
+ if (!ParseSubstitution())
+ return false;
}
break;
case 'P':
{
- switch (*++read_ptr)
+ switch (*++m_read_ptr)
{
case 'F':
- ++read_ptr;
- if (!ParseFunctionType(QualifierPointer)) return false;
+ ++m_read_ptr;
+ if (!ParseFunctionType(QualifierPointer))
+ return false;
break;
default:
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
Write('*');
break;
}
@@ -1190,15 +1285,17 @@ private:
}
case 'R':
{
- ++read_ptr;
- if (!ParseType()) return false;
+ ++m_read_ptr;
+ if (!ParseType())
+ return false;
Write('&');
break;
}
case 'O':
{
- ++read_ptr;
- if (!ParseType()) return false;
+ ++m_read_ptr;
+ if (!ParseType())
+ return false;
Write('&');
Write('&');
break;
@@ -1214,24 +1311,27 @@ private:
case 'N':
case 'Z':
case 'L':
- if (!ParseName()) return false;
+ if (!ParseName())
+ return false;
break;
default:
- if (const char * builtin = TryParseBuiltinType())
+ if (const char *builtin = TryParseBuiltinType())
{
Write(builtin);
suppress_substitution = true;
}
else
{
- if (!ParseName()) return false;
+ if (!ParseName())
+ return false;
}
break;
}
-
+
// Allow base substitutions to be suppressed, but always record
// substitutions for the qualified variant
- if (!suppress_substitution) EndSubstitution(type_start_cookie);
+ if (!suppress_substitution)
+ EndSubstitution(type_start_cookie);
if (qualifiers)
{
WriteQualifiers(qualifiers, false);
@@ -1239,40 +1339,43 @@ private:
}
return true;
}
-
+
// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
// ::= <closure-type-name>
//
// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
//
// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
-
- bool ParseUnnamedTypeName(NameState & name_state)
+
+ bool
+ ParseUnnamedTypeName(NameState & name_state)
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 't':
{
int cookie = GetStartCookie();
WRITE("'unnamed");
- const char * before_digits = read_ptr;
- if (TryParseNumber() != -1) Write(before_digits,
- read_ptr - before_digits);
- if (!Parse('_')) return false;
+ const char *before_digits = m_read_ptr;
+ if (TryParseNumber() != -1) Write (before_digits,
+ m_read_ptr - before_digits);
+ if (!Parse('_'))
+ return false;
Write('\'');
- name_state.last_name_range = EndRange(cookie);
+ name_state.last_name_range = EndRange (cookie);
return true;
}
case 'b':
{
int cookie = GetStartCookie();
WRITE("'block");
- const char * before_digits = read_ptr;
- if (TryParseNumber() != -1) Write(before_digits,
- read_ptr - before_digits);
- if (!Parse('_')) return false;
+ const char *before_digits = m_read_ptr;
+ if (TryParseNumber() != -1) Write (before_digits,
+ m_read_ptr - before_digits);
+ if (!Parse('_'))
+ return false;
Write('\'');
- name_state.last_name_range = EndRange(cookie);
+ name_state.last_name_range = EndRange (cookie);
return true;
}
case 'l':
@@ -1282,23 +1385,24 @@ private:
return false;
}
#ifdef DEBUG_FAILURES
- printf("*** Unknown unnamed type %.3s\n", read_ptr - 2);
+ printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2);
#endif
return false;
}
-
+
// <ctor-dtor-name> ::= C1 # complete object constructor
// ::= C2 # base object constructor
// ::= C3 # complete object allocating constructor
-
- bool ParseCtor(NameState & name_state)
+
+ bool
+ ParseCtor(NameState & name_state)
{
- char next = *read_ptr;
+ char next = *m_read_ptr;
if (next == '1' || next == '2' || next == '3' || next == '5')
{
- RewriteRange(name_state.last_name_range);
+ RewriteRange (name_state.last_name_range);
name_state.has_no_return_type = true;
- ++read_ptr;
+ ++m_read_ptr;
return true;
}
#ifdef DEBUG_FAILURES
@@ -1306,20 +1410,21 @@ private:
#endif
return false;
}
-
+
// <ctor-dtor-name> ::= D0 # deleting destructor
// ::= D1 # complete object destructor
// ::= D2 # base object destructor
-
- bool ParseDtor(NameState & name_state)
+
+ bool
+ ParseDtor(NameState & name_state)
{
- char next = *read_ptr;
+ char next = *m_read_ptr;
if (next == '0' || next == '1' || next == '2' || next == '5')
{
Write('~');
RewriteRange(name_state.last_name_range);
name_state.has_no_return_type = true;
- ++read_ptr;
+ ++m_read_ptr;
return true;
}
#ifdef DEBUG_FAILURES
@@ -1327,13 +1432,14 @@ private:
#endif
return false;
}
-
+
// See TryParseOperator()
-
- bool ParseOperatorName(NameState & name_state)
+
+ bool
+ ParseOperatorName(NameState & name_state)
{
#ifdef DEBUG_FAILURES
- const char * operator_ptr = read_ptr;
+ const char *operator_ptr = m_read_ptr;
#endif
Operator parsed_operator = TryParseOperator();
if (parsed_operator.name)
@@ -1342,7 +1448,7 @@ private:
Write(parsed_operator.name);
return true;
}
-
+
// Handle special operators
switch (parsed_operator.kind)
{
@@ -1361,10 +1467,11 @@ private:
return false;
}
}
-
+
// <source-name> ::= <positive length number> <identifier>
-
- bool ParseSourceName()
+
+ bool
+ ParseSourceName()
{
int count = TryParseNumber();
if (count == -1)
@@ -1374,43 +1481,45 @@ private:
#endif
return false;
}
-
- const char * next_read_ptr = read_ptr + count;
- if (next_read_ptr > read_end)
+
+ const char *next_m_read_ptr = m_read_ptr + count;
+ if (next_m_read_ptr > m_read_end)
{
#ifdef DEBUG_FAILURES
printf("*** Malformed source name, premature termination\n");
#endif
return false;
}
-
- if (count >= 10 && strncmp(read_ptr, "_GLOBAL__N", 10) == 0) WRITE("(anonymous namespace)");
- else Write(read_ptr, count);
-
- read_ptr = next_read_ptr;
+
+ if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0)
+ WRITE("(anonymous namespace)");
+ else Write(m_read_ptr, count);
+
+ m_read_ptr = next_m_read_ptr;
return true;
}
-
+
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
// ::= <source-name>
// ::= <unnamed-type-name>
-
- bool ParseUnqualifiedName(NameState & name_state)
+
+ bool
+ ParseUnqualifiedName(NameState & name_state)
{
// Note that these are detected directly in ParseNestedName for
// performance rather than switching on the same options twice
- char next = *read_ptr;
+ char next = *m_read_ptr;
switch (next)
{
case 'C':
- ++read_ptr;
+ ++m_read_ptr;
return ParseCtor(name_state);
case 'D':
- ++read_ptr;
+ ++m_read_ptr;
return ParseDtor(name_state);
case 'U':
- ++read_ptr;
+ ++m_read_ptr;
return ParseUnnamedTypeName(name_state);
case '0':
case '1':
@@ -1424,7 +1533,8 @@ private:
case '9':
{
int name_start_cookie = GetStartCookie();
- if (!ParseSourceName()) return false;
+ if (!ParseSourceName())
+ return false;
name_state.last_name_range = EndRange(name_start_cookie);
return true;
}
@@ -1432,33 +1542,40 @@ private:
return ParseOperatorName(name_state);
};
}
-
+
// <unscoped-name> ::= <unqualified-name>
// ::= St <unqualified-name> # ::std::
// extension ::= StL<unqualified-name>
-
- bool ParseUnscopedName(NameState & name_state)
+
+ bool
+ ParseUnscopedName(NameState & name_state)
{
- if (*read_ptr == 'S' && *(read_ptr + 1) == 't')
+ if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't')
{
WriteStdPrefix();
- if (*(read_ptr += 2) == 'L') ++read_ptr;
+ if (*(m_read_ptr += 2) == 'L')
+ ++m_read_ptr;
}
return ParseUnqualifiedName(name_state);
}
-
- bool ParseIntegerLiteral(const char * prefix, const char * suffix,
+
+ bool
+ ParseIntegerLiteral(const char *prefix, const char *suffix,
bool allow_negative)
{
- if (prefix) Write(prefix);
- if (!ParseNumber(allow_negative)) return false;
- if (suffix) Write(suffix);
+ if (prefix)
+ Write(prefix);
+ if (!ParseNumber(allow_negative))
+ return false;
+ if (suffix)
+ Write(suffix);
return Parse('E');
}
-
- bool ParseBooleanLiteral()
+
+ bool
+ ParseBooleanLiteral()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case '0': WRITE("false"); break;
case '1': WRITE("true"); break;
@@ -1470,17 +1587,18 @@ private:
}
return Parse('E');
}
-
+
// <expr-primary> ::= L <type> <value number> E # integer literal
// ::= L <type> <value float> E # floating literal
// ::= L <string type> E # string literal
// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
// ::= L <mangled-name> E # external name
-
- bool ParseExpressionPrimary()
+
+ bool
+ ParseExpressionPrimary()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'b': return ParseBooleanLiteral();
case 'x': return ParseIntegerLiteral(nullptr, "ll", true);
@@ -1493,12 +1611,13 @@ private:
case 'o': return ParseIntegerLiteral("(unsigned __int128)",
nullptr, false);
case '_':
- if (*read_ptr++ == 'Z')
+ if (*m_read_ptr++ == 'Z')
{
- if (!ParseEncoding()) return false;
+ if (!ParseEncoding())
+ return false;
return Parse('E');
}
- --read_ptr;
+ --m_read_ptr;
// fallthrough
case 'w':
case 'c':
@@ -1510,7 +1629,7 @@ private:
case 'd':
case 'e':
#ifdef DEBUG_FAILURES
- printf("*** Unsupported primary expression %.5s\n", read_ptr - 1);
+ printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
#endif
return false;
case 'T':
@@ -1521,49 +1640,55 @@ private:
#endif
return false;
default:
- --read_ptr;
+ --m_read_ptr;
Write('(');
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
Write(')');
- if (!ParseNumber()) return false;
+ if (!ParseNumber())
+ return false;
return Parse('E');
}
}
-
+
// <unresolved-type> ::= <template-param>
// ::= <decltype>
// ::= <substitution>
-
- bool ParseUnresolvedType()
+
+ bool
+ ParseUnresolvedType()
{
int type_start_cookie = GetStartCookie();
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'T':
- if (!ParseTemplateParam()) return false;
+ if (!ParseTemplateParam())
+ return false;
EndSubstitution(type_start_cookie);
return true;
case 'S':
{
- if (*read_ptr != 't') return ParseSubstitution();
-
- ++read_ptr;
+ if (*m_read_ptr != 't')
+ return ParseSubstitution();
+
+ ++m_read_ptr;
WriteStdPrefix();
NameState type_name = {};
- if (!ParseUnqualifiedName(type_name)) return false;
+ if (!ParseUnqualifiedName(type_name))
+ return false;
EndSubstitution(type_start_cookie);
return true;
-
+
}
case 'D':
default:
#ifdef DEBUG_FAILURES
- printf("*** Unsupported unqualified type: %3s\n", read_ptr - 1);
+ printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1);
#endif
return false;
}
}
-
+
// <base-unresolved-name> ::= <simple-id> # unresolved name
// extension ::= <operator-name> # unresolved operator-function-id
// extension ::= <operator-name> <template-args> # unresolved operator template-id
@@ -1571,15 +1696,16 @@ private:
// ::= on <operator-name> <template-args> # unresolved operator template-id
// ::= dn <destructor-name> # destructor or pseudo-destructor;
// # e.g. ~X or ~X<N-1>
-
- bool ParseBaseUnresolvedName()
+
+ bool
+ ParseBaseUnresolvedName()
{
#ifdef DEBUG_FAILURES
printf("*** Base unresolved name unsupported\n");
#endif
return false;
}
-
+
// <unresolved-name>
// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
@@ -1589,22 +1715,25 @@ private:
// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
// # T::N::x /decltype(p)::N::x
// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
-
- bool ParseUnresolvedName()
+
+ bool
+ ParseUnresolvedName()
{
#ifdef DEBUG_FAILURES
printf("*** Unresolved names not supported\n");
#endif
//TODO: grammar for all of this seems unclear...
return false;
-
- if (*read_ptr == 'g' && *(read_ptr + 1) == 's')
+
+#if 0 // TODO
+ if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's')
{
- read_ptr += 2;
+ m_read_ptr += 2;
WriteNamespaceSeparator();
}
+#endif // TODO
}
-
+
// <expression> ::= <unary operator-name> <expression>
// ::= <binary operator-name> <expression> <expression>
// ::= <ternary operator-name> <expression> <expression> <expression>
@@ -1644,8 +1773,9 @@ private:
// # freestanding dependent name (e.g., T::x),
// # objectless nonstatic member reference
// ::= <expr-primary>
-
- bool ParseExpression()
+
+ bool
+ ParseExpression()
{
Operator expression_operator = TryParseOperator();
switch (expression_operator.kind)
@@ -1653,17 +1783,21 @@ private:
case OperatorKind::Unary:
Write(expression_operator.name);
Write('(');
- if (!ParseExpression()) return false;
+ if (!ParseExpression())
+ return false;
Write(')');
return true;
case OperatorKind::Binary:
- if (!ParseExpression()) return false;
+ if (!ParseExpression())
+ return false;
Write(expression_operator.name);
return ParseExpression();
case OperatorKind::Ternary:
- if (!ParseExpression()) return false;
+ if (!ParseExpression())
+ return false;
Write('?');
- if (!ParseExpression()) return false;
+ if (!ParseExpression())
+ return false;
Write(':');
return ParseExpression();
case OperatorKind::NoMatch:
@@ -1675,67 +1809,75 @@ private:
#endif
return false;
}
-
- switch (*read_ptr++)
+
+ switch (*m_read_ptr++)
{
case 'T': return ParseTemplateParam();
case 'L': return ParseExpressionPrimary();
case 's':
- if (*read_ptr++ == 'r') return ParseUnresolvedName();
- --read_ptr;
+ if (*m_read_ptr++ == 'r')
+ return ParseUnresolvedName();
+ --m_read_ptr;
// fallthrough
default:
return ParseExpressionPrimary();
}
}
-
+
// <template-arg> ::= <type> # type or template
// ::= X <expression> E # expression
// ::= <expr-primary> # simple expressions
// ::= J <template-arg>* E # argument pack
// ::= LZ <encoding> E # extension
-
- bool ParseTemplateArg()
+
+ bool
+ ParseTemplateArg()
{
- switch (*read_ptr) {
+ switch (*m_read_ptr) {
case 'J':
#ifdef DEBUG_FAILURES
printf("*** Template argument packs unsupported\n");
#endif
return false;
case 'X':
- ++read_ptr;
- if (!ParseExpression()) return false;
+ ++m_read_ptr;
+ if (!ParseExpression())
+ return false;
return Parse('E');
case 'L':
- ++read_ptr;
+ ++m_read_ptr;
return ParseExpressionPrimary();
default:
return ParseType();
}
}
-
+
// <template-args> ::= I <template-arg>* E
// extension, the abi says <template-arg>+
-
- bool ParseTemplateArgs(bool record_template_args = false)
+
+ bool
+ ParseTemplateArgs(bool record_template_args = false)
{
- if (record_template_args) ResetTemplateArgs();
-
+ if (record_template_args)
+ ResetTemplateArgs();
+
bool first_arg = true;
- while (*read_ptr != 'E')
+ while (*m_read_ptr != 'E')
{
- if (first_arg) first_arg = false;
+ if (first_arg)
+ first_arg = false;
else WriteCommaSpace();
-
+
int template_start_cookie = GetStartCookie();
- if (!ParseTemplateArg()) return false;
- if (record_template_args) EndTemplateArg(template_start_cookie);
+ if (!ParseTemplateArg())
+ return false;
+ if (record_template_args)
+ EndTemplateArg(template_start_cookie);
}
- ++read_ptr;
+ ++m_read_ptr;
return true;
}
-
+
// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
//
@@ -1756,8 +1898,9 @@ private:
// ::= <ctor-dtor-name>
// ::= <source-name>
// ::= <unnamed-type-name>
-
- bool ParseNestedName(NameState & name_state, bool parse_discriminator = false)
+
+ bool
+ ParseNestedName(NameState & name_state, bool parse_discriminator = false)
{
int qualifiers = TryParseQualifiers(true, true);
bool first_part = true;
@@ -1765,30 +1908,33 @@ private:
int name_start_cookie = GetStartCookie();
while (true)
{
- char next = *read_ptr;
+ char next = *m_read_ptr;
if (next == 'E')
{
- ++read_ptr;
+ ++m_read_ptr;
break;
}
-
+
// Record a substitution candidate for all prefixes, but not the full name
- if (suppress_substitution) suppress_substitution = false;
+ if (suppress_substitution)
+ suppress_substitution = false;
else EndSubstitution(name_start_cookie);
-
+
if (next == 'I')
{
- ++read_ptr;
+ ++m_read_ptr;
name_state.is_last_generic = true;
WriteTemplateStart();
- if (!ParseTemplateArgs(name_state.parse_function_params)) return false;
+ if (!ParseTemplateArgs(name_state.parse_function_params))
+ return false;
WriteTemplateEnd();
continue;
}
-
- if (first_part) first_part = false;
+
+ if (first_part)
+ first_part = false;
else WriteNamespaceSeparator();
-
+
name_state.is_last_generic = false;
switch (next)
{
@@ -1804,34 +1950,39 @@ private:
case '9':
{
int name_start_cookie = GetStartCookie();
- if (!ParseSourceName()) return false;
+ if (!ParseSourceName())
+ return false;
name_state.last_name_range = EndRange(name_start_cookie);
continue;
}
case 'S':
- if (*++read_ptr == 't')
+ if (*++m_read_ptr == 't')
{
WriteStdPrefix();
- ++read_ptr;
- if (!ParseUnqualifiedName(name_state)) return false;
+ ++m_read_ptr;
+ if (!ParseUnqualifiedName(name_state))
+ return false;
}
else
{
- if (!ParseSubstitution()) return false;
+ if (!ParseSubstitution())
+ return false;
suppress_substitution = true;
}
continue;
case 'T':
- ++read_ptr;
- if (!ParseTemplateParam()) return false;
+ ++m_read_ptr;
+ if (!ParseTemplateParam())
+ return false;
continue;
case 'C':
- ++read_ptr;
- if (!ParseCtor(name_state)) return false;
+ ++m_read_ptr;
+ if (!ParseCtor(name_state))
+ return false;
continue;
case 'D':
{
- switch (*(read_ptr + 1))
+ switch (*(m_read_ptr + 1))
{
case 't':
case 'T':
@@ -1840,109 +1991,135 @@ private:
#endif
return false;
}
- ++read_ptr;
- if (!ParseDtor(name_state)) return false;
+ ++m_read_ptr;
+ if (!ParseDtor(name_state))
+ return false;
continue;
}
case 'U':
- ++read_ptr;
- if (!ParseUnnamedTypeName(name_state)) return false;
+ ++m_read_ptr;
+ if (!ParseUnnamedTypeName(name_state))
+ return false;
continue;
case 'L':
- ++read_ptr;
- if (!ParseUnqualifiedName(name_state)) return false;
+ ++m_read_ptr;
+ if (!ParseUnqualifiedName(name_state))
+ return false;
continue;
default:
- if (!ParseOperatorName(name_state)) return false;
+ if (!ParseOperatorName(name_state))
+ return false;
}
}
-
- if (parse_discriminator) TryParseDiscriminator();
- if (name_state.parse_function_params &&
- !ParseFunctionArgs(name_state, name_start_cookie)) return false;
- if (qualifiers) WriteQualifiers(qualifiers);
+
+ if (parse_discriminator)
+ TryParseDiscriminator();
+ if (name_state.parse_function_params
+ && !ParseFunctionArgs(name_state, name_start_cookie))
+ {
+ return false;
+ }
+ if (qualifiers)
+ WriteQualifiers(qualifiers);
return true;
}
-
+
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
// := Z <function encoding> E s [<discriminator>]
// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
-
- bool ParseLocalName(bool parse_function_params)
+
+ bool
+ ParseLocalName(bool parse_function_params)
{
- if (!ParseEncoding()) return false;
- if (!Parse('E')) return false;
-
- switch (*read_ptr)
+ if (!ParseEncoding())
+ return false;
+ if (!Parse('E'))
+ return false;
+
+ switch (*m_read_ptr)
{
case 's':
+ ++m_read_ptr;
TryParseDiscriminator(); // Optional and ignored
WRITE("::string literal");
break;
case 'd':
+ ++m_read_ptr;
TryParseNumber(); // Optional and ignored
+ if (!Parse('_'))
+ return false;
WriteNamespaceSeparator();
- if (!ParseName()) return false;
+ if (!ParseName())
+ return false;
break;
default:
WriteNamespaceSeparator();
- if (!ParseName(parse_function_params, true)) return false;
+ if (!ParseName(parse_function_params, true))
+ return false;
TryParseDiscriminator(); // Optional and ignored
}
return true;
}
-
+
// <name> ::= <nested-name>
// ::= <local-name>
// ::= <unscoped-template-name> <template-args>
// ::= <unscoped-name>
-
+
// <unscoped-template-name> ::= <unscoped-name>
// ::= <substitution>
-
- bool ParseName(bool parse_function_params = false,
+
+ bool
+ ParseName(bool parse_function_params = false,
bool parse_discriminator = false)
{
- NameState name_state = { parse_function_params };
+ NameState name_state = { parse_function_params, false, false, {0, 0}};
int name_start_cookie = GetStartCookie();
-
- switch (*read_ptr)
+
+ switch (*m_read_ptr)
{
case 'N':
- ++read_ptr;
+ ++m_read_ptr;
return ParseNestedName(name_state, parse_discriminator);
case 'Z':
{
- ++read_ptr;
- if (!ParseLocalName(parse_function_params)) return false;
+ ++m_read_ptr;
+ if (!ParseLocalName(parse_function_params))
+ return false;
break;
}
case 'L':
- ++read_ptr;
+ ++m_read_ptr;
// fallthrough
default:
{
- if (!ParseUnscopedName(name_state)) return false;
-
- if (*read_ptr == 'I')
+ if (!ParseUnscopedName(name_state))
+ return false;
+
+ if (*m_read_ptr == 'I')
{
EndSubstitution(name_start_cookie);
-
- ++read_ptr;
+
+ ++m_read_ptr;
name_state.is_last_generic = true;
WriteTemplateStart();
- if (!ParseTemplateArgs(parse_function_params)) return false;
+ if (!ParseTemplateArgs(parse_function_params))
+ return false;
WriteTemplateEnd();
}
break;
}
}
- if (parse_discriminator) TryParseDiscriminator();
+ if (parse_discriminator)
+ TryParseDiscriminator();
if (parse_function_params &&
- !ParseFunctionArgs(name_state, name_start_cookie)) return false;
+ !ParseFunctionArgs(name_state, name_start_cookie))
+ {
+ return false;
+ }
return true;
}
-
+
// <call-offset> ::= h <nv-offset> _
// ::= v <v-offset> _
//
@@ -1951,20 +2128,27 @@ private:
//
// <v-offset> ::= <offset number> _ <virtual offset number>
// # virtual base override, with vcall offset
-
- bool ParseCallOffset()
+
+ bool
+ ParseCallOffset()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'h':
- if (*read_ptr == 'n') ++read_ptr;
- if (TryParseNumber() == -1 || *read_ptr++ != '_') break;
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
return true;
case 'v':
- if (*read_ptr == 'n') ++read_ptr;
- if (TryParseNumber() == -1 || *read_ptr++ != '_') break;
- if (*read_ptr == 'n') ++read_ptr;
- if (TryParseNumber() == -1 || *read_ptr++ != '_') break;
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
return true;
}
#ifdef DEBUG_FAILURES
@@ -1972,7 +2156,7 @@ private:
#endif
return false;
}
-
+
// <special-name> ::= TV <type> # virtual table
// ::= TT <type> # VTT structure (construction vtable index)
// ::= TI <type> # typeinfo structure
@@ -1984,10 +2168,11 @@ private:
// ::= T <call-offset> <base encoding>
// # base is the nominal target function of thunk
// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
-
- bool ParseSpecialNameT()
+
+ bool
+ ParseSpecialNameT()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'V':
WRITE("vtable for ");
@@ -2004,11 +2189,11 @@ private:
case 'c':
case 'C':
#ifdef DEBUG_FAILURES
- printf("*** Unsupported thunk or construction vtable name: %.3s\n", read_ptr - 1);
+ printf("*** Unsupported thunk or construction vtable name: %.3s\n", m_read_ptr - 1);
#endif
return false;
default:
- if (*--read_ptr == 'v')
+ if (*--m_read_ptr == 'v')
{
WRITE("virtual thunk to ");
}
@@ -2016,26 +2201,30 @@ private:
{
WRITE("non-virtual thunk to ");
}
- if (!ParseCallOffset()) return false;
+ if (!ParseCallOffset())
+ return false;
return ParseEncoding();
}
}
-
+
// <special-name> ::= GV <object name> # Guard variable for one-time initialization
// # No <type>
// extension ::= GR <object name> # reference temporary for object
-
- bool ParseSpecialNameG()
+
+ bool
+ ParseSpecialNameG()
{
- switch (*read_ptr++)
+ switch (*m_read_ptr++)
{
case 'V':
WRITE("guard variable for ");
- if (!ParseName(true)) return false;
+ if (!ParseName(true))
+ return false;
break;
case 'R':
WRITE("reference temporary for ");
- if (!ParseName(true)) return false;
+ if (!ParseName(true))
+ return false;
break;
default:
#ifdef DEBUG_FAILURES
@@ -2045,58 +2234,64 @@ private:
}
return true;
}
-
+
// <bare-function-type> ::= <signature type>+ # types are possible return type, then parameter types
-
- bool ParseFunctionArgs(NameState & name_state, int return_insert_cookie)
+
+ bool
+ ParseFunctionArgs(NameState & name_state, int return_insert_cookie)
{
- char next = *read_ptr;
- if (next == 'E' || next == '\0' || next == '.') return true;
-
+ char next = *m_read_ptr;
+ if (next == 'E' || next == '\0' || next == '.')
+ return true;
+
// Clang has a bad habit of making unique manglings by just sticking numbers on the end of a symbol,
// which is ambiguous with malformed source name manglings
- const char * before_clang_uniquing_test = read_ptr;
+ const char *before_clang_uniquing_test = m_read_ptr;
if (TryParseNumber())
{
- if (*read_ptr == '\0') return true;
- read_ptr = before_clang_uniquing_test;
+ if (*m_read_ptr == '\0')
+ return true;
+ m_read_ptr = before_clang_uniquing_test;
}
-
+
if (name_state.is_last_generic && !name_state.has_no_return_type)
{
int return_type_start_cookie = GetStartCookie();
- if (!ParseType()) return false;
+ if (!ParseType())
+ return false;
Write(' ');
ReorderRange(EndRange(return_type_start_cookie),
return_insert_cookie);
}
-
+
Write('(');
bool first_param = true;
while (true)
{
- switch (*read_ptr)
+ switch (*m_read_ptr)
{
case '\0':
case 'E':
case '.':
break;
case 'v':
- ++read_ptr;
+ ++m_read_ptr;
continue;
case '_':
// Not a formal part of the mangling specification, but clang emits suffixes starting with _block_invoke
- if (strncmp(read_ptr, "_block_invoke", 13) == 0)
+ if (strncmp(m_read_ptr, "_block_invoke", 13) == 0)
{
- read_ptr += strlen(read_ptr);
+ m_read_ptr += strlen(m_read_ptr);
break;
}
// fallthrough
default:
- if (first_param) first_param = false;
+ if (first_param)
+ first_param = false;
else WriteCommaSpace();
-
- if (!ParseType()) return false;
+
+ if (!ParseType())
+ return false;
continue;
}
break;
@@ -2104,53 +2299,60 @@ private:
Write(')');
return true;
}
-
+
// <encoding> ::= <function name> <bare-function-type>
// ::= <data name>
// ::= <special-name>
-
- bool ParseEncoding()
+
+ bool
+ ParseEncoding()
{
- switch (*read_ptr)
+ switch (*m_read_ptr)
{
case 'T':
- ++read_ptr;
- if (!ParseSpecialNameT()) return false;
+ ++m_read_ptr;
+ if (!ParseSpecialNameT())
+ return false;
break;
case 'G':
- ++read_ptr;
- if (!ParseSpecialNameG()) return false;
+ ++m_read_ptr;
+ if (!ParseSpecialNameG())
+ return false;
break;
default:
- if (!ParseName(true)) return false;
+ if (!ParseName(true))
+ return false;
break;
}
return true;
}
-
- bool ParseMangling(const char * mangled_name, long mangled_name_length = 0)
- {
- if (!mangled_name_length) mangled_name_length = strlen(mangled_name);
- read_end = mangled_name + mangled_name_length;
- read_ptr = mangled_name;
- write_ptr = buffer;
- next_substitute_index = 0;
- next_template_arg_index = rewrite_ranges_size - 1;
-
- if (*read_ptr++ != '_' || *read_ptr++ != 'Z')
+
+ bool
+ ParseMangling(const char *mangled_name, long mangled_name_length = 0)
+ {
+ if (!mangled_name_length)
+ mangled_name_length = strlen(mangled_name);
+ m_read_end = mangled_name + mangled_name_length;
+ m_read_ptr = mangled_name;
+ m_write_ptr = m_buffer;
+ m_next_substitute_index = 0;
+ m_next_template_arg_index = m_rewrite_ranges_size - 1;
+
+ if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z')
{
#ifdef DEBUG_FAILURES
printf("*** Missing _Z prefix\n");
#endif
return false;
}
- if (!ParseEncoding()) return false;
- switch (*read_ptr)
+ if (!ParseEncoding())
+ return false;
+ switch (*m_read_ptr)
{
case '.':
Write(' ');
Write('(');
- Write(read_ptr, read_end - read_ptr);
+ Write(m_read_ptr, m_read_end - m_read_ptr);
Write(')');
case '\0':
return true;
@@ -2161,25 +2363,25 @@ private:
return false;
}
}
-
+
private:
-
+
// External scratch storage used during demanglings
-
- char * buffer;
- const char * buffer_end;
- BufferRange * rewrite_ranges;
- int rewrite_ranges_size;
- bool owns_buffer;
- bool owns_rewrite_ranges;
-
+
+ char *m_buffer;
+ const char *m_buffer_end;
+ BufferRange *m_rewrite_ranges;
+ int m_rewrite_ranges_size;
+ bool m_owns_buffer;
+ bool m_owns_m_rewrite_ranges;
+
// Internal state used during demangling
-
- const char * read_ptr;
- const char * read_end;
- char * write_ptr;
- int next_template_arg_index;
- int next_substitute_index;
+
+ const char *m_read_ptr;
+ const char *m_read_end;
+ char *m_write_ptr;
+ int m_next_template_arg_index;
+ int m_next_substitute_index;
};
} // Anonymous namespace
@@ -2187,17 +2389,19 @@ private:
// Public entry points referenced from Mangled.cpp
namespace lldb_private
{
- char * FastDemangle(const char* mangled_name)
+ char *
+ FastDemangle(const char *mangled_name)
{
char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof(buffer));
+ SymbolDemangler demangler(buffer, sizeof (buffer));
return demangler.GetDemangledCopy(mangled_name);
}
- char * FastDemangle(const char* mangled_name, long mangled_name_length)
+ char *
+ FastDemangle(const char *mangled_name, long mangled_name_length)
{
char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof(buffer));
+ SymbolDemangler demangler(buffer, sizeof (buffer));
return demangler.GetDemangledCopy(mangled_name, mangled_name_length);
}
} // lldb_private namespace
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index 0cec8faa6bc4..4b1c991c6be4 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -107,7 +107,7 @@ FileSpecList::Dump(Stream *s, const char *separator_cstr) const
// it is found, else UINT32_MAX is returned.
//------------------------------------------------------------------
size_t
-FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full) const
+FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full, bool remove_dots) const
{
const size_t num_files = m_files.size();
@@ -124,7 +124,7 @@ FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool f
}
else
{
- if (FileSpec::Equal (m_files[idx], file_spec, full))
+ if (FileSpec::Equal (m_files[idx], file_spec, full, remove_dots))
return idx;
}
}
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index add3ad8c5ba3..21ba965ba212 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -19,7 +19,9 @@
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectRegister.h"
+#ifndef LLDB_DISABLE_LIBEDIT
#include "lldb/Host/Editline.h"
+#endif
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/Block.h"
@@ -36,8 +38,9 @@
using namespace lldb;
using namespace lldb_private;
-IOHandler::IOHandler (Debugger &debugger) :
+IOHandler::IOHandler (Debugger &debugger, IOHandler::Type type) :
IOHandler (debugger,
+ type,
StreamFileSP(), // Adopt STDIN from top input reader
StreamFileSP(), // Adopt STDOUT from top input reader
StreamFileSP(), // Adopt STDERR from top input reader
@@ -47,6 +50,7 @@ IOHandler::IOHandler (Debugger &debugger) :
IOHandler::IOHandler (Debugger &debugger,
+ IOHandler::Type type,
const lldb::StreamFileSP &input_sp,
const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp,
@@ -55,7 +59,9 @@ IOHandler::IOHandler (Debugger &debugger,
m_input_sp (input_sp),
m_output_sp (output_sp),
m_error_sp (error_sp),
+ m_popped (false),
m_flags (flags),
+ m_type (type),
m_user_data (NULL),
m_done (false),
m_active (false)
@@ -151,13 +157,28 @@ IOHandler::GetIsRealTerminal ()
return GetInputStreamFile()->GetFile().GetIsRealTerminal();
}
+void
+IOHandler::SetPopped (bool b)
+{
+ m_popped.SetValue(b, eBroadcastOnChange);
+}
+
+void
+IOHandler::WaitForPop ()
+{
+ m_popped.WaitForValueEqualTo(true);
+}
+
IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
const char *prompt,
bool default_response) :
IOHandlerEditline(debugger,
+ IOHandler::Type::Confirm,
NULL, // NULL editline_name means no history loaded/saved
- NULL,
+ NULL, // No prompt
+ NULL, // No continuation prompt
false, // Multi-line
+ false, // Don't colorize the prompt (i.e. the confirm message.)
0,
*this),
m_default_response (default_response),
@@ -310,83 +331,121 @@ IOHandlerDelegate::IOHandlerComplete (IOHandler &io_handler,
IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
+ IOHandler::Type type,
const char *editline_name, // Used for saving history files
const char *prompt,
+ const char *continuation_prompt,
bool multi_line,
+ bool color_prompts,
uint32_t line_number_start,
IOHandlerDelegate &delegate) :
IOHandlerEditline(debugger,
+ type,
StreamFileSP(), // Inherit input from top input reader
StreamFileSP(), // Inherit output from top input reader
StreamFileSP(), // Inherit error from top input reader
0, // Flags
editline_name, // Used for saving history files
prompt,
+ continuation_prompt,
multi_line,
+ color_prompts,
line_number_start,
delegate)
{
}
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,
const char *editline_name, // Used for saving history files
const char *prompt,
+ const char *continuation_prompt,
bool multi_line,
+ bool color_prompts,
uint32_t line_number_start,
IOHandlerDelegate &delegate) :
- IOHandler (debugger, input_sp, output_sp, error_sp, flags),
+ IOHandler (debugger, type, input_sp, output_sp, error_sp, flags),
+#ifndef LLDB_DISABLE_LIBEDIT
m_editline_ap (),
+#endif
m_delegate (delegate),
m_prompt (),
+ m_continuation_prompt(),
+ m_current_lines_ptr (NULL),
m_base_line_number (line_number_start),
- m_multi_line (multi_line)
+ m_curr_line_idx (UINT32_MAX),
+ m_multi_line (multi_line),
+ m_color_prompts (color_prompts),
+ m_interrupt_exits (true)
{
SetPrompt(prompt);
+#ifndef LLDB_DISABLE_LIBEDIT
bool use_editline = false;
-#ifndef _MSC_VER
use_editline = m_input_sp->GetFile().GetIsRealTerminal();
-#else
- // Editline is causing issues on Windows, so use the fallback.
- use_editline = false;
-#endif
if (use_editline)
{
m_editline_ap.reset(new Editline (editline_name,
- prompt ? prompt : "",
- multi_line,
GetInputFILE (),
GetOutputFILE (),
- GetErrorFILE ()));
- if (m_base_line_number > 0)
- m_editline_ap->ShowLineNumbers(true, m_base_line_number);
- m_editline_ap->SetLineCompleteCallback (LineCompletedCallback, this);
+ GetErrorFILE (),
+ m_color_prompts));
+ m_editline_ap->SetIsInputCompleteCallback (IsInputCompleteCallback, this);
m_editline_ap->SetAutoCompleteCallback (AutoCompleteCallback, this);
+ // See if the delegate supports fixing indentation
+ const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
+ if (indent_chars)
+ {
+ // The delegate does support indentation, hook it up so when any indentation
+ // character is typed, the delegate gets a chance to fix it
+ m_editline_ap->SetFixIndentationCallback (FixIndentationCallback, this, indent_chars);
+ }
}
-
+#endif
+ SetBaseLineNumber (m_base_line_number);
+ SetPrompt(prompt ? prompt : "");
+ SetContinuationPrompt(continuation_prompt);
}
IOHandlerEditline::~IOHandlerEditline ()
{
+#ifndef LLDB_DISABLE_LIBEDIT
m_editline_ap.reset();
+#endif
+}
+
+void
+IOHandlerEditline::Activate ()
+{
+ IOHandler::Activate();
+ m_delegate.IOHandlerActivated(*this);
+}
+
+void
+IOHandlerEditline::Deactivate ()
+{
+ IOHandler::Deactivate();
+ m_delegate.IOHandlerDeactivated(*this);
}
bool
IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
{
- return m_editline_ap->GetLine(line, interrupted).Success();
+ return m_editline_ap->GetLine (line, interrupted);
}
else
{
+#endif
line.clear();
FILE *in = GetInputFILE();
@@ -394,7 +453,14 @@ IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
{
if (GetIsInteractive())
{
- const char *prompt = GetPrompt();
+ const char *prompt = NULL;
+
+ if (m_multi_line && m_curr_line_idx > 0)
+ prompt = GetContinuationPrompt();
+
+ if (prompt == NULL)
+ prompt = GetPrompt();
+
if (prompt && prompt[0])
{
FILE *out = GetOutputFILE();
@@ -452,19 +518,30 @@ IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
SetIsDone(true);
}
return false;
+#ifndef LLDB_DISABLE_LIBEDIT
}
+#endif
}
-LineStatus
-IOHandlerEditline::LineCompletedCallback (Editline *editline,
+#ifndef LLDB_DISABLE_LIBEDIT
+bool
+IOHandlerEditline::IsInputCompleteCallback (Editline *editline,
StringList &lines,
- uint32_t line_idx,
- Error &error,
void *baton)
{
IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
- return editline_reader->m_delegate.IOHandlerLinesUpdated(*editline_reader, lines, line_idx, error);
+ return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader, lines);
+}
+
+int
+IOHandlerEditline::FixIndentationCallback (Editline *editline,
+ const StringList &lines,
+ int cursor_position,
+ void *baton)
+{
+ IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
+ return editline_reader->m_delegate.IOHandlerFixIndentation(*editline_reader, lines, cursor_position);
}
int
@@ -487,14 +564,24 @@ IOHandlerEditline::AutoCompleteCallback (const char *current_line,
matches);
return 0;
}
+#endif
const char *
IOHandlerEditline::GetPrompt ()
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
+ {
return m_editline_ap->GetPrompt ();
- else if (m_prompt.empty())
- return NULL;
+ }
+ else
+ {
+#endif
+ if (m_prompt.empty())
+ return NULL;
+#ifndef LLDB_DISABLE_LIBEDIT
+ }
+#endif
return m_prompt.c_str();
}
@@ -505,34 +592,71 @@ IOHandlerEditline::SetPrompt (const char *p)
m_prompt = p;
else
m_prompt.clear();
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
m_editline_ap->SetPrompt (m_prompt.empty() ? NULL : m_prompt.c_str());
+#endif
return true;
}
+const char *
+IOHandlerEditline::GetContinuationPrompt ()
+{
+ if (m_continuation_prompt.empty())
+ return NULL;
+ return m_continuation_prompt.c_str();
+}
+
+
+void
+IOHandlerEditline::SetContinuationPrompt (const char *p)
+{
+ if (p && p[0])
+ m_continuation_prompt = p;
+ else
+ m_continuation_prompt.clear();
+
+#ifndef LLDB_DISABLE_LIBEDIT
+ if (m_editline_ap)
+ m_editline_ap->SetContinuationPrompt (m_continuation_prompt.empty() ? NULL : m_continuation_prompt.c_str());
+#endif
+}
+
+
void
IOHandlerEditline::SetBaseLineNumber (uint32_t line)
{
m_base_line_number = line;
+}
+
+uint32_t
+IOHandlerEditline::GetCurrentLineIndex () const
+{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
- m_editline_ap->ShowLineNumbers (true, line);
-
+ return m_editline_ap->GetCurrentLine();
+#endif
+ return m_curr_line_idx;
}
+
bool
IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
{
+ m_current_lines_ptr = &lines;
+
bool success = false;
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
{
- std::string end_token;
- success = m_editline_ap->GetLines(end_token, lines, interrupted).Success();
+ return m_editline_ap->GetLines (m_base_line_number, lines, interrupted);
}
else
{
- LineStatus lines_status = LineStatus::Success;
+#endif
+ bool done = false;
Error error;
- while (lines_status == LineStatus::Success)
+ while (!done)
{
// Show line numbers if we are asked to
std::string line;
@@ -543,31 +667,23 @@ IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(), GetPrompt() == NULL ? " " : "");
}
+ m_curr_line_idx = lines.GetSize();
+
bool interrupted = false;
- if (GetLine(line, interrupted))
+ if (GetLine(line, interrupted) && !interrupted)
{
- if (interrupted)
- {
- lines_status = LineStatus::Done;
- }
- else
- {
- lines.AppendString(line);
- lines_status = m_delegate.IOHandlerLinesUpdated(*this, lines, lines.GetSize() - 1, error);
- }
+ lines.AppendString(line);
+ done = m_delegate.IOHandlerIsInputComplete(*this, lines);
}
else
{
- lines_status = LineStatus::Done;
+ done = true;
}
}
-
- // Call the IOHandlerLinesUpdated function with UINT32_MAX as the line
- // number to indicate all lines are complete
- m_delegate.IOHandlerLinesUpdated(*this, lines, UINT32_MAX, error);
-
success = lines.GetSize() > 0;
+#ifndef LLDB_DISABLE_LIBEDIT
}
+#endif
return success;
}
@@ -588,12 +704,14 @@ IOHandlerEditline::Run ()
{
if (interrupted)
{
- m_done = true;
+ m_done = m_interrupt_exits;
+ m_delegate.IOHandlerInputInterrupted (*this, line);
+
}
else
{
line = lines.CopyList();
- m_delegate.IOHandlerInputComplete(*this, line);
+ m_delegate.IOHandlerInputComplete (*this, line);
}
}
else
@@ -605,8 +723,10 @@ IOHandlerEditline::Run ()
{
if (GetLine(line, interrupted))
{
- if (!interrupted)
- m_delegate.IOHandlerInputComplete(*this, line);
+ if (interrupted)
+ m_delegate.IOHandlerInputInterrupted (*this, line);
+ else
+ m_delegate.IOHandlerInputComplete (*this, line);
}
else
{
@@ -619,20 +739,24 @@ IOHandlerEditline::Run ()
void
IOHandlerEditline::Hide ()
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
m_editline_ap->Hide();
+#endif
}
void
IOHandlerEditline::Refresh ()
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
{
m_editline_ap->Refresh();
}
else
{
+#endif
const char *prompt = GetPrompt();
if (prompt && prompt[0])
{
@@ -643,14 +767,18 @@ IOHandlerEditline::Refresh ()
::fflush(out);
}
}
+#ifndef LLDB_DISABLE_LIBEDIT
}
+#endif
}
void
IOHandlerEditline::Cancel ()
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
m_editline_ap->Interrupt ();
+#endif
}
bool
@@ -660,16 +788,20 @@ IOHandlerEditline::Interrupt ()
if (m_delegate.IOHandlerInterrupt(*this))
return true;
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
return m_editline_ap->Interrupt();
+#endif
return false;
}
void
IOHandlerEditline::GotEOF()
{
+#ifndef LLDB_DISABLE_LIBEDIT
if (m_editline_ap)
m_editline_ap->Interrupt();
+#endif
}
// we may want curses to be disabled for some builds
@@ -5333,7 +5465,7 @@ protected:
DisplayOptions ValueObjectListDelegate::g_options = { true };
IOHandlerCursesGUI::IOHandlerCursesGUI (Debugger &debugger) :
- IOHandler (debugger)
+ IOHandler (debugger, IOHandler::Type::Curses)
{
}
diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp
index 3adca6e5385c..d205d363b764 100644
--- a/source/Core/Log.cpp
+++ b/source/Core/Log.cpp
@@ -26,9 +26,12 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Host/Mutex.h"
+#include "lldb/Host/ThisThread.h"
+#include "lldb/Host/TimeValue.h"
#include "lldb/Interpreter/Args.h"
+
+#include "llvm/ADT/SmallString.h"
using namespace lldb;
using namespace lldb_private;
@@ -113,7 +116,8 @@ Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
// Add the thread name if requested
if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
{
- std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
+ llvm::SmallString<32> thread_name;
+ ThisThread::GetName(thread_name);
if (!thread_name.empty())
header.Printf ("%s ", thread_name.c_str());
}
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index c4fa10fedd86..c0ab66cd2880 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -4986,10 +4986,12 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
+
using namespace lldb_private;
static inline bool
@@ -5000,6 +5002,57 @@ cstring_is_mangled (const char *s)
return false;
}
+static const ConstString &
+get_demangled_name_without_arguments (const Mangled *obj)
+{
+ // This pair is <mangled name, demangled name without function arguments>
+ static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
+
+ // Need to have the mangled & demangled names we're currently examining as statics
+ // so we can return a const ref to them at the end of the func if we don't have
+ // anything better.
+ static ConstString g_last_mangled;
+ static ConstString g_last_demangled;
+
+ ConstString mangled = obj->GetMangledName ();
+ ConstString demangled = obj->GetDemangledName ();
+
+ if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
+ {
+ return g_most_recent_mangled_to_name_sans_args.second;
+ }
+
+ g_last_demangled = demangled;
+ g_last_mangled = mangled;
+
+ const char *mangled_name_cstr = mangled.GetCString();
+
+ if (demangled && mangled_name_cstr && mangled_name_cstr[0])
+ {
+ if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
+ (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
+ mangled_name_cstr[2] != 'G' && // avoid guard variables
+ mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
+ {
+ CPPLanguageRuntime::MethodName cxx_method (demangled);
+ if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty())
+ {
+ std::string shortname = cxx_method.GetContext().str();
+ shortname += "::";
+ shortname += cxx_method.GetBasename().str();
+ ConstString result(shortname.c_str());
+ g_most_recent_mangled_to_name_sans_args.first = mangled;
+ g_most_recent_mangled_to_name_sans_args.second = result;
+ return g_most_recent_mangled_to_name_sans_args.second;
+ }
+ }
+ }
+
+ if (demangled)
+ return g_last_demangled;
+ return g_last_mangled;
+}
+
#pragma mark Mangled
//----------------------------------------------------------------------
// Default constructor
@@ -5215,6 +5268,14 @@ Mangled::NameMatches (const RegularExpression& regex) const
const ConstString&
Mangled::GetName (Mangled::NamePreference preference) const
{
+ if (preference == ePreferDemangledWithoutArguments)
+ {
+ // Call the accessor to make sure we get a demangled name in case
+ // it hasn't been demangled yet...
+ GetDemangledName();
+
+ return get_demangled_name_without_arguments (this);
+ }
if (preference == ePreferDemangled)
{
// Call the accessor to make sure we get a demangled name in case
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 6f16ada49824..900eea2e0419 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -1309,6 +1309,10 @@ Module::GetObjectFile()
// unknown.
m_objfile_sp->GetArchitecture (m_arch);
}
+ else
+ {
+ ReportError ("failed to load objfile for %s", GetFileSpec().GetPath().c_str());
+ }
}
}
return m_objfile_sp.get();
@@ -1706,8 +1710,9 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
const char *name_cstr = name.GetCString();
lookup_name_type_mask = eFunctionNameTypeNone;
match_name_after_lookup = false;
- const char *base_name_start = NULL;
- const char *base_name_end = NULL;
+
+ llvm::StringRef basename;
+ llvm::StringRef context;
if (name_type_mask & eFunctionNameTypeAuto)
{
@@ -1721,16 +1726,16 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
lookup_name_type_mask |= eFunctionNameTypeSelector;
CPPLanguageRuntime::MethodName cpp_method (name);
- llvm::StringRef basename (cpp_method.GetBasename());
+ basename = cpp_method.GetBasename();
if (basename.empty())
{
- if (CPPLanguageRuntime::StripNamespacesFromVariableName (name_cstr, base_name_start, base_name_end))
+ if (CPPLanguageRuntime::ExtractContextAndIdentifier (name_cstr, context, basename))
lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ else
+ lookup_name_type_mask = eFunctionNameTypeFull;
}
else
{
- base_name_start = basename.data();
- base_name_end = base_name_start + basename.size();
lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
}
}
@@ -1745,9 +1750,7 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
CPPLanguageRuntime::MethodName cpp_method (name);
if (cpp_method.IsValid())
{
- llvm::StringRef basename (cpp_method.GetBasename());
- base_name_start = basename.data();
- base_name_end = base_name_start + basename.size();
+ basename = cpp_method.GetBasename();
if (!cpp_method.GetQualifiers().empty())
{
@@ -1760,12 +1763,9 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
}
else
{
- if (!CPPLanguageRuntime::StripNamespacesFromVariableName (name_cstr, base_name_start, base_name_end))
- {
- lookup_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
- if (lookup_name_type_mask == eFunctionNameTypeNone)
- return;
- }
+ // If the CPP method parser didn't manage to chop this up, try to fill in the base name if we can.
+ // If a::b::c is passed in, we need to just look up "c", and then we'll filter the result later.
+ CPPLanguageRuntime::ExtractContextAndIdentifier (name_cstr, context, basename);
}
}
@@ -1780,16 +1780,13 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
}
}
- if (base_name_start &&
- base_name_end &&
- base_name_start != name_cstr &&
- base_name_start < base_name_end)
+ if (!basename.empty())
{
// The name supplied was a partial C++ path like "a::count". In this case we want to do a
// lookup on the basename "count" and then make sure any matching results contain "a::count"
// so that it would match "b::a::count" and "a::count". This is why we set "match_name_after_lookup"
// to true
- lookup_name.SetCStringWithLength(base_name_start, base_name_end - base_name_start);
+ lookup_name.SetString(basename);
match_name_after_lookup = true;
}
else
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index 156f3cf9d0aa..879eb9bd1822 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -484,6 +484,26 @@ ModuleList::FindFunctionSymbols (const ConstString &name,
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();
+
+ Mutex::Locker locker(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);
+ }
+
+ return sc_list.GetSize() - old_size;
+}
+
size_t
ModuleList::FindCompileUnits (const FileSpec &path,
bool append,
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index cda55802fab8..95574cb2deaf 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -2068,6 +2068,229 @@ PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &
return NULL;
}
+#pragma mark MemoryHistory
+
+struct MemoryHistoryInstance
+{
+ MemoryHistoryInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ MemoryHistoryCreateInstance create_callback;
+};
+
+typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
+
+static Mutex &
+GetMemoryHistoryMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static MemoryHistoryInstances &
+GetMemoryHistoryInstances ()
+{
+ static MemoryHistoryInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ MemoryHistoryCreateInstance create_callback
+ )
+{
+ if (create_callback)
+ {
+ MemoryHistoryInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ Mutex::Locker locker (GetMemoryHistoryMutex ());
+ GetMemoryHistoryInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetMemoryHistoryMutex ());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
+
+ MemoryHistoryInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+MemoryHistoryCreateInstance
+PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetMemoryHistoryMutex ());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+MemoryHistoryCreateInstance
+PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetMemoryHistoryMutex ());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
+
+ MemoryHistoryInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark InstrumentationRuntime
+
+struct InstrumentationRuntimeInstance
+{
+ InstrumentationRuntimeInstance() :
+ name(),
+ description(),
+ create_callback(NULL)
+ {
+ }
+
+ ConstString name;
+ std::string description;
+ InstrumentationRuntimeCreateInstance create_callback;
+ InstrumentationRuntimeGetType get_type_callback;
+};
+
+typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
+
+static Mutex &
+GetInstrumentationRuntimeMutex ()
+{
+ static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive);
+ return g_instances_mutex;
+}
+
+static InstrumentationRuntimeInstances &
+GetInstrumentationRuntimeInstances ()
+{
+ static InstrumentationRuntimeInstances g_instances;
+ return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin
+(
+ const ConstString &name,
+ const char *description,
+ InstrumentationRuntimeCreateInstance create_callback,
+ InstrumentationRuntimeGetType get_type_callback
+ )
+{
+ if (create_callback)
+ {
+ InstrumentationRuntimeInstance instance;
+ assert ((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.get_type_callback = get_type_callback;
+ Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ GetInstrumentationRuntimeInstances ().push_back (instance);
+ }
+ return false;
+}
+
+bool
+PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
+{
+ if (create_callback)
+ {
+ Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
+
+ InstrumentationRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (pos->create_callback == create_callback)
+ {
+ instances.erase(pos);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+InstrumentationRuntimeGetType
+PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
+ if (idx < instances.size())
+ return instances[idx].get_type_callback;
+ return NULL;
+}
+
+InstrumentationRuntimeCreateInstance
+PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
+{
+ Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return NULL;
+}
+
+
+InstrumentationRuntimeCreateInstance
+PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
+{
+ if (name)
+ {
+ Mutex::Locker locker (GetInstrumentationRuntimeMutex ());
+ InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
+
+ InstrumentationRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++ pos)
+ {
+ if (name == pos->name)
+ return pos->create_callback;
+ }
+ }
+ return NULL;
+}
+
+#pragma mark PluginManager
+
void
PluginManager::DebuggerInitialize (Debugger &debugger)
{
diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp
index 88415f616828..54924d069537 100644
--- a/source/Core/RegularExpression.cpp
+++ b/source/Core/RegularExpression.cpp
@@ -162,20 +162,11 @@ RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
bool
RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
{
- if (idx < m_matches.size())
+ llvm::StringRef match_str_ref;
+ if (GetMatchAtIndex(s, idx, match_str_ref))
{
- if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
- {
- // Matched the empty string...
- match_str.clear();
- return true;
- }
- else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
- {
- match_str.assign (s + m_matches[idx].rm_so,
- m_matches[idx].rm_eo - m_matches[idx].rm_so);
- return true;
- }
+ match_str = std::move(match_str_ref.str());
+ return true;
}
return false;
}
@@ -185,6 +176,9 @@ RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::St
{
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...
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp
index dee2f2e4bd5e..9c3412a422d0 100644
--- a/source/Core/SearchFilter.cpp
+++ b/source/Core/SearchFilter.cpp
@@ -119,6 +119,15 @@ SearchFilter::Dump (Stream *s) const
}
+lldb::SearchFilterSP
+SearchFilter::CopyForBreakpoint (Breakpoint &breakpoint)
+{
+ SearchFilterSP ret_sp = DoCopyForBreakpoint (breakpoint);
+ TargetSP target_sp = breakpoint.GetTargetSP();
+ ret_sp->SetTarget(target_sp);
+ return ret_sp;
+}
+
//----------------------------------------------------------------------
// UTILITY Functions to help iterate down through the elements of the
// SymbolContext.
@@ -281,29 +290,36 @@ SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &cont
}
//----------------------------------------------------------------------
-// SearchFilterForNonModuleSpecificSearches:
+// SearchFilterForUnconstrainedSearches:
// Selects a shared library matching a given file spec, consulting the targets "black list".
//----------------------------------------------------------------------
- bool
- SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec)
- {
- if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec))
- return false;
- else
- return true;
- }
-
- bool
- SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp)
- {
- if (!module_sp)
- return true;
- else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp))
- return false;
- else
- return true;
- }
+bool
+SearchFilterForUnconstrainedSearches::ModulePasses (const FileSpec &module_spec)
+{
+ if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_spec))
+ return false;
+ else
+ return true;
+}
+
+bool
+SearchFilterForUnconstrainedSearches::ModulePasses (const lldb::ModuleSP &module_sp)
+{
+ if (!module_sp)
+ return true;
+ else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_sp))
+ return false;
+ else
+ return true;
+}
+
+lldb::SearchFilterSP
+SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint (Breakpoint &breakpoint)
+{
+ SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this));
+ return ret_sp;
+}
//----------------------------------------------------------------------
// SearchFilterByModule:
@@ -434,7 +450,7 @@ SearchFilterByModule::GetDescription (Stream *s)
}
else
{
- s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>"));
+ s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>"));
}
}
@@ -449,6 +465,14 @@ SearchFilterByModule::Dump (Stream *s) const
{
}
+
+lldb::SearchFilterSP
+SearchFilterByModule::DoCopyForBreakpoint (Breakpoint &breakpoint)
+{
+ SearchFilterSP ret_sp(new SearchFilterByModule(*this));
+ return ret_sp;
+}
+
//----------------------------------------------------------------------
// SearchFilterByModuleList:
// Selects a shared library matching a given file spec
@@ -458,7 +482,8 @@ SearchFilterByModule::Dump (Stream *s) const
// SearchFilterByModuleList constructors
//----------------------------------------------------------------------
-SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) :
+SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp,
+ const FileSpecList &module_list) :
SearchFilter (target_sp),
m_module_spec_list (module_list)
{
@@ -587,7 +612,7 @@ SearchFilterByModuleList::GetDescription (Stream *s)
}
else
{
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
+ s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<Unknown>"));
}
}
else
@@ -603,7 +628,7 @@ SearchFilterByModuleList::GetDescription (Stream *s)
}
else
{
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
+ s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<Unknown>"));
}
if (i != num_modules - 1)
s->PutCString (", ");
@@ -623,6 +648,14 @@ SearchFilterByModuleList::Dump (Stream *s) const
}
+lldb::SearchFilterSP
+SearchFilterByModuleList::DoCopyForBreakpoint (Breakpoint &breakpoint)
+{
+ SearchFilterSP ret_sp(new SearchFilterByModuleList(*this));
+ return ret_sp;
+}
+
+
//----------------------------------------------------------------------
// SearchFilterByModuleListAndCU:
// Selects a shared library matching a given file spec
@@ -778,7 +811,7 @@ SearchFilterByModuleListAndCU::GetDescription (Stream *s)
}
else
{
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
+ s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<Unknown>"));
}
}
else if (num_modules > 0)
@@ -794,7 +827,7 @@ SearchFilterByModuleListAndCU::GetDescription (Stream *s)
}
else
{
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
+ s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<Unknown>"));
}
if (i != num_modules - 1)
s->PutCString (", ");
@@ -814,3 +847,10 @@ SearchFilterByModuleListAndCU::Dump (Stream *s) const
}
+lldb::SearchFilterSP
+SearchFilterByModuleListAndCU::DoCopyForBreakpoint (Breakpoint &breakpoint)
+{
+ SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this));
+ return ret_sp;
+}
+
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index 3267c1866221..ea33a62b775f 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -28,7 +28,8 @@ Section::Section (const ModuleSP &module_sp,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
- uint32_t flags) :
+ uint32_t flags,
+ uint32_t target_byte_size/*=1*/) :
ModuleChild (module_sp),
UserID (sect_id),
Flags (flags),
@@ -44,7 +45,8 @@ Section::Section (const ModuleSP &module_sp,
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false)
+ m_thread_specific (false),
+ m_target_byte_size(target_byte_size)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
@@ -61,7 +63,8 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
- uint32_t flags) :
+ uint32_t flags,
+ uint32_t target_byte_size/*=1*/) :
ModuleChild (module_sp),
UserID (sect_id),
Flags (flags),
@@ -77,7 +80,8 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false)
+ m_thread_specific (false),
+ m_target_byte_size(target_byte_size)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -186,7 +190,7 @@ Section::ContainsFileAddress (addr_t vm_addr) const
{
if (file_addr <= vm_addr)
{
- const addr_t offset = vm_addr - file_addr;
+ const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
return offset < GetByteSize();
}
}
diff --git a/source/Core/StreamString.cpp b/source/Core/StreamString.cpp
index 8d7d039fd65c..ef2b70583ebd 100644
--- a/source/Core/StreamString.cpp
+++ b/source/Core/StreamString.cpp
@@ -65,6 +65,22 @@ StreamString::GetSize () const
return m_packet.size();
}
+size_t
+StreamString::GetSizeOfLastLine () const
+{
+ const size_t length = m_packet.size();
+ size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
+ if (last_line_begin_pos == std::string::npos)
+ {
+ return length;
+ }
+ else
+ {
+ ++last_line_begin_pos;
+ return length - last_line_begin_pos;
+ }
+}
+
std::string &
StreamString::GetString()
{
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 1819e834536a..fa5fb14db05b 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -34,8 +34,12 @@
#include "lldb/Core/ValueObjectSyntheticFilter.h"
#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
+
#include "lldb/Host/Endian.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -43,6 +47,7 @@
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
@@ -77,6 +82,7 @@ ValueObject::ValueObject (ValueObject &parent) :
m_location_str (),
m_summary_str (),
m_object_desc_str (),
+ m_validation_result(),
m_manager(parent.GetManager()),
m_children (),
m_synthetic_children (),
@@ -89,8 +95,10 @@ ValueObject::ValueObject (ValueObject &parent) :
m_type_summary_sp(),
m_type_format_sp(),
m_synthetic_children_sp(),
+ m_type_validator_sp(),
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
+ m_value_checksum(),
m_value_is_valid (false),
m_value_did_change (false),
m_children_count_valid (false),
@@ -100,7 +108,8 @@ ValueObject::ValueObject (ValueObject &parent) :
m_is_bitfield_for_scalar(false),
m_is_child_at_offset(false),
m_is_getting_summary(false),
- m_did_calculate_complete_objc_class_type(false)
+ m_did_calculate_complete_objc_class_type(false),
+ m_is_synthetic_children_generated(parent.m_is_synthetic_children_generated)
{
m_manager->ManageObject(this);
}
@@ -123,6 +132,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope,
m_location_str (),
m_summary_str (),
m_object_desc_str (),
+ m_validation_result(),
m_manager(),
m_children (),
m_synthetic_children (),
@@ -135,8 +145,10 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope,
m_type_summary_sp(),
m_type_format_sp(),
m_synthetic_children_sp(),
+ m_type_validator_sp(),
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
+ m_value_checksum(),
m_value_is_valid (false),
m_value_did_change (false),
m_children_count_valid (false),
@@ -146,7 +158,8 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope,
m_is_bitfield_for_scalar(false),
m_is_child_at_offset(false),
m_is_getting_summary(false),
- m_did_calculate_complete_objc_class_type(false)
+ m_did_calculate_complete_objc_class_type(false),
+ m_is_synthetic_children_generated(false)
{
m_manager = new ValueObjectManager();
m_manager->ManageObject (this);
@@ -181,7 +194,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format)
return m_error.Success();
}
- bool first_update = m_update_point.IsFirstEvaluation();
+ bool first_update = IsChecksumEmpty();
if (m_update_point.NeedsUpdating())
{
@@ -210,10 +223,35 @@ ValueObject::UpdateValueIfNeeded (bool update_format)
m_error.Clear();
// Call the pure virtual function to update the value
+
+ bool need_compare_checksums = false;
+ llvm::SmallVector<uint8_t, 16> old_checksum;
+
+ if (!first_update && CanProvideValue())
+ {
+ need_compare_checksums = true;
+ old_checksum.resize(m_value_checksum.size());
+ std::copy(m_value_checksum.begin(), m_value_checksum.end(), old_checksum.begin());
+ }
+
bool success = UpdateValue ();
SetValueIsValid (success);
+ if (success)
+ {
+ const uint64_t max_checksum_size = 128;
+ m_data.Checksum(m_value_checksum,
+ max_checksum_size);
+ }
+ else
+ {
+ need_compare_checksums = false;
+ m_value_checksum.clear();
+ }
+
+ assert (!need_compare_checksums || (!old_checksum.empty() && !m_value_checksum.empty()));
+
if (first_update)
SetValueDidChange (false);
else if (!m_value_did_change && success == false)
@@ -222,6 +260,11 @@ ValueObject::UpdateValueIfNeeded (bool update_format)
// as changed if the value used to be valid and now isn't
SetValueDidChange (value_was_valid);
}
+ else if (need_compare_checksums)
+ {
+ SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0], m_value_checksum.size()));
+ }
+
}
else
{
@@ -253,6 +296,7 @@ ValueObject::UpdateFormatsIfNeeded()
#ifndef LLDB_DISABLE_PYTHON
SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType()));
#endif
+ SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
}
return any_change;
@@ -486,7 +530,6 @@ ValueObject::SetValueIsValid (bool b)
bool
ValueObject::GetValueDidChange ()
{
- GetValueAsCString ();
return m_value_did_change;
}
@@ -746,9 +789,9 @@ ValueObject::MightHaveChildren()
const uint32_t type_info = GetTypeInfo();
if (type_info)
{
- if (type_info & (ClangASTType::eTypeHasChildren |
- ClangASTType::eTypeIsPointer |
- ClangASTType::eTypeIsReference))
+ if (type_info & (eTypeHasChildren |
+ eTypeIsPointer |
+ eTypeIsReference))
has_children = true;
}
else
@@ -835,6 +878,14 @@ bool
ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
std::string& destination)
{
+ return GetSummaryAsCString(summary_ptr, destination, TypeSummaryOptions());
+}
+
+bool
+ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
+ std::string& destination,
+ const TypeSummaryOptions& options)
+{
destination.clear();
// ideally we would like to bail out if passing NULL, but if we do so
@@ -851,66 +902,11 @@ ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
GetName().GetCString(),
summary_ptr->GetDescription().c_str());*/
- if (UpdateValueIfNeeded (false))
+ if (UpdateValueIfNeeded (false) && summary_ptr)
{
- if (summary_ptr)
- {
- if (HasSyntheticValue())
- m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
- summary_ptr->FormatObject(this, destination);
- }
- else
- {
- ClangASTType clang_type = GetClangType();
-
- // Do some default printout for function pointers
- if (clang_type)
- {
- if (clang_type.IsFunctionPointerType ())
- {
- StreamString sstr;
- AddressType func_ptr_address_type = eAddressTypeInvalid;
- addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
- if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
- {
- switch (func_ptr_address_type)
- {
- case eAddressTypeInvalid:
- case eAddressTypeFile:
- break;
-
- case eAddressTypeLoad:
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- Address so_addr;
- Target *target = exe_ctx.GetTargetPtr();
- if (target && target->GetSectionLoadList().IsEmpty() == false)
- {
- if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
- {
- so_addr.Dump (&sstr,
- exe_ctx.GetBestExecutionContextScope(),
- Address::DumpStyleResolvedDescription,
- Address::DumpStyleSectionNameOffset);
- }
- }
- }
- break;
-
- case eAddressTypeHost:
- break;
- }
- }
- if (sstr.GetSize() > 0)
- {
- destination.assign (1, '(');
- destination.append (sstr.GetData(), sstr.GetSize());
- destination.append (1, ')');
- }
- }
- }
- }
+ if (HasSyntheticValue())
+ m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
+ summary_ptr->FormatObject(this, destination, options);
}
m_is_getting_summary = false;
return !destination.empty();
@@ -922,7 +918,8 @@ ValueObject::GetSummaryAsCString ()
if (UpdateValueIfNeeded(true) && m_summary_str.empty())
{
GetSummaryAsCString(GetSummaryFormat().get(),
- m_summary_str);
+ m_summary_str,
+ TypeSummaryOptions());
}
if (m_summary_str.empty())
return NULL;
@@ -930,17 +927,26 @@ ValueObject::GetSummaryAsCString ()
}
bool
+ValueObject::GetSummaryAsCString (std::string& destination,
+ const TypeSummaryOptions& options)
+{
+ return GetSummaryAsCString(GetSummaryFormat().get(),
+ destination,
+ options);
+}
+
+bool
ValueObject::IsCStringContainer(bool check_pointer)
{
ClangASTType pointee_or_element_clang_type;
const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
- bool is_char_arr_ptr (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
+ bool is_char_arr_ptr (type_flags.AnySet (eTypeIsArray | eTypeIsPointer) &&
pointee_or_element_clang_type.IsCharType ());
if (!is_char_arr_ptr)
return false;
if (!check_pointer)
return true;
- if (type_flags.Test(ClangASTType::eTypeIsArray))
+ if (type_flags.Test(eTypeIsArray))
return true;
addr_t cstr_address = LLDB_INVALID_ADDRESS;
AddressType cstr_address_type = eAddressTypeInvalid;
@@ -955,8 +961,8 @@ ValueObject::GetPointeeData (DataExtractor& data,
{
ClangASTType pointee_or_element_clang_type;
const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
- const bool is_pointer_type = type_info & ClangASTType::eTypeIsPointer;
- const bool is_array_type = type_info & ClangASTType::eTypeIsArray;
+ const bool is_pointer_type = type_info & eTypeIsPointer;
+ const bool is_array_type = type_info & eTypeIsArray;
if (!(is_pointer_type || is_array_type))
return 0;
@@ -1182,20 +1188,31 @@ strlen_or_inf (const char* str,
return len;
}
+static bool
+CopyStringDataToBufferSP(const StreamString& source,
+ lldb::DataBufferSP& destination)
+{
+ destination.reset(new DataBufferHeap(source.GetSize()+1,0));
+ memcpy(destination->GetBytes(), source.GetString().c_str(), source.GetSize());
+ return true;
+}
+
size_t
-ValueObject::ReadPointedString (Stream& s,
+ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp,
Error& error,
uint32_t max_length,
bool honor_array,
Format item_format)
{
+ StreamString s;
ExecutionContext exe_ctx (GetExecutionContextRef());
Target* target = exe_ctx.GetTargetPtr();
-
+
if (!target)
{
s << "<no target to read from>";
error.SetErrorString("no target to read from");
+ CopyStringDataToBufferSP(s, buffer_sp);
return 0;
}
@@ -1208,7 +1225,7 @@ ValueObject::ReadPointedString (Stream& s,
ClangASTType clang_type = GetClangType();
ClangASTType elem_or_pointee_clang_type;
const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
- if (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
+ if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer) &&
elem_or_pointee_clang_type.IsCharType ())
{
addr_t cstr_address = LLDB_INVALID_ADDRESS;
@@ -1216,7 +1233,7 @@ ValueObject::ReadPointedString (Stream& s,
size_t cstr_len = 0;
bool capped_data = false;
- if (type_flags.Test (ClangASTType::eTypeIsArray))
+ if (type_flags.Test (eTypeIsArray))
{
// We have an array
uint64_t array_size = 0;
@@ -1241,9 +1258,10 @@ ValueObject::ReadPointedString (Stream& s,
{
s << "<invalid address>";
error.SetErrorString("invalid address");
+ CopyStringDataToBufferSP(s, buffer_sp);
return 0;
}
-
+
Address cstr_so_addr (cstr_address);
DataExtractor data;
if (cstr_len > 0 && honor_array)
@@ -1251,30 +1269,21 @@ ValueObject::ReadPointedString (Stream& s,
// I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
// but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
GetPointeeData(data, 0, cstr_len);
-
+
if ((bytes_read = data.GetByteSize()) > 0)
{
total_bytes_read = bytes_read;
- s << '"';
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
if (capped_data)
s << "...";
- s << '"';
}
}
else
{
cstr_len = max_length;
const size_t k_max_buf_size = 64;
-
+
size_t offset = 0;
int cstr_len_displayed = -1;
@@ -1288,12 +1297,10 @@ ValueObject::ReadPointedString (Stream& s,
size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
if (len > k_max_buf_size)
len = k_max_buf_size;
- if (cstr && cstr_len_displayed < 0)
- s << '"';
-
+
if (cstr_len_displayed < 0)
cstr_len_displayed = len;
-
+
if (len == 0)
break;
cstr_len_displayed += len;
@@ -1302,15 +1309,8 @@ ValueObject::ReadPointedString (Stream& s,
if (len > cstr_len)
len = cstr_len;
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
if (len < k_max_buf_size)
break;
@@ -1320,14 +1320,13 @@ ValueObject::ReadPointedString (Stream& s,
capped_cstr = true;
break;
}
-
+
cstr_len -= len;
offset += len;
}
if (cstr_len_displayed >= 0)
{
- s << '"';
if (capped_cstr)
s << "...";
}
@@ -1338,9 +1337,27 @@ ValueObject::ReadPointedString (Stream& s,
error.SetErrorString("not a string object");
s << "<not a string object>";
}
+ CopyStringDataToBufferSP(s, buffer_sp);
return total_bytes_read;
}
+std::pair<TypeValidatorResult, std::string>
+ValueObject::GetValidationStatus ()
+{
+ if (!UpdateValueIfNeeded(true))
+ return {TypeValidatorResult::Success,""}; // not the validator's job to discuss update problems
+
+ if (m_validation_result.hasValue())
+ return m_validation_result.getValue();
+
+ if (!m_type_validator_sp)
+ return {TypeValidatorResult::Success,""}; // no validator no failure
+
+ auto outcome = m_type_validator_sp->FormatObject(this);
+
+ return (m_validation_result = {outcome.m_result,outcome.m_message}).getValue();
+}
+
const char *
ValueObject::GetObjectDescription ()
{
@@ -1428,7 +1445,7 @@ ValueObject::GetValueAsCString ()
}
else
{
- my_format = GetClangType().GetFormat();
+ my_format = GetValue().GetClangType().GetFormat();
}
}
}
@@ -1460,7 +1477,7 @@ uint64_t
ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
{
// If our byte size is zero this is an aggregate type that has children
- if (!GetClangType().IsAggregateType())
+ if (CanProvideValue())
{
Scalar scalar;
if (ResolveValue (scalar))
@@ -1481,7 +1498,7 @@ int64_t
ValueObject::GetValueAsSigned (int64_t fail_value, bool *success)
{
// If our byte size is zero this is an aggregate type that has children
- if (!GetClangType().IsAggregateType())
+ if (CanProvideValue())
{
Scalar scalar;
if (ResolveValue (scalar))
@@ -1506,7 +1523,7 @@ ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle va
Format custom_format)
{
Flags flags(GetTypeInfo());
- if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
+ if (flags.AnySet(eTypeIsArray | eTypeIsPointer)
&& val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
{
if (IsCStringContainer(true) &&
@@ -1516,7 +1533,7 @@ ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle va
custom_format == eFormatVectorOfChar))
return true;
- if (flags.Test(ClangASTType::eTypeIsArray))
+ if (flags.Test(eTypeIsArray))
{
if ((custom_format == eFormatBytes) ||
(custom_format == eFormatBytesWithASCII))
@@ -1555,7 +1572,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
if (allow_special)
{
- if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
+ if (flags.AnySet(eTypeIsArray | eTypeIsPointer)
&& val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
{
// when being asked to get a printable display an array or pointer type directly,
@@ -1568,11 +1585,19 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
custom_format == eFormatVectorOfChar)) // print char[] & char* directly
{
Error error;
- ReadPointedString(s,
+ lldb::DataBufferSP buffer_sp;
+ ReadPointedString(buffer_sp,
error,
0,
(custom_format == eFormatVectorOfChar) ||
(custom_format == eFormatCharArray));
+ lldb_private::formatters::ReadBufferAndDumpToStreamOptions options(*this);
+ options.SetData(DataExtractor(buffer_sp, lldb::eByteOrderInvalid, 8)); // none of this matters for a string - pass some defaults
+ options.SetStream(&s);
+ options.SetPrefixToken(0);
+ options.SetQuote('"');
+ options.SetSourceSize(buffer_sp->GetByteSize());
+ lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
return !error.Fail();
}
@@ -1581,7 +1606,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
// this only works for arrays, because I have no way to know when
// the pointed memory ends, and no special \0 end of data marker
- if (flags.Test(ClangASTType::eTypeIsArray))
+ if (flags.Test(eTypeIsArray))
{
if ((custom_format == eFormatBytes) ||
(custom_format == eFormatBytesWithASCII))
@@ -1729,7 +1754,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
cstr = GetSummaryAsCString();
else if (val_obj_display == eValueObjectRepresentationStyleSummary)
{
- if (GetClangType().IsAggregateType())
+ if (!CanProvideValue())
{
strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
cstr = strm.GetString().c_str();
@@ -2037,7 +2062,7 @@ ValueObject::IsPossibleDynamicType ()
bool
ValueObject::IsObjCNil ()
{
- const uint32_t mask = ClangASTType::eTypeIsObjC | ClangASTType::eTypeIsPointer;
+ const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask);
if (!isObjCpointer)
return false;
@@ -2050,10 +2075,10 @@ ValueObjectSP
ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
{
const uint32_t type_info = GetTypeInfo ();
- if (type_info & ClangASTType::eTypeIsArray)
+ if (type_info & eTypeIsArray)
return GetSyntheticArrayMemberFromArray(index, can_create);
- if (type_info & ClangASTType::eTypeIsPointer)
+ if (type_info & eTypeIsPointer)
return GetSyntheticArrayMemberFromPointer(index, can_create);
return ValueObjectSP();
@@ -2460,6 +2485,46 @@ ValueObject::IsBaseClass (uint32_t& depth)
void
ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
{
+ // synthetic children do not actually "exist" as part of the hierarchy, and sometimes they are consed up in ways
+ // that don't make sense from an underlying language/API standpoint. So, use a special code path here to return
+ // something that can hopefully be used in expression
+ if (m_is_synthetic_children_generated)
+ {
+ UpdateValueIfNeeded();
+
+ if (m_value.GetValueType() == Value::eValueTypeLoadAddress)
+ {
+ if (IsPointerOrReferenceType())
+ {
+ s.Printf("((%s)0x%" PRIx64 ")",
+ GetTypeName().AsCString("void"),
+ GetValueAsUnsigned(0));
+ return;
+ }
+ else
+ {
+ uint64_t load_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ s.Printf("(*( (%s *)0x%" PRIx64 "))",
+ GetTypeName().AsCString("void"),
+ load_addr);
+ return;
+ }
+ }
+ }
+
+ if (CanProvideValue())
+ {
+ s.Printf("((%s)%s)",
+ GetTypeName().AsCString("void"),
+ GetValueAsCString());
+ return;
+ }
+
+ return;
+ }
+
const bool is_deref_of_parent = IsDereferenceOfParent ();
if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
@@ -2499,12 +2564,12 @@ ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExp
{
const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo();
- if (non_base_class_parent_type_info & ClangASTType::eTypeIsPointer)
+ if (non_base_class_parent_type_info & eTypeIsPointer)
{
s.PutCString("->");
}
- else if ((non_base_class_parent_type_info & ClangASTType::eTypeHasChildren) &&
- !(non_base_class_parent_type_info & ClangASTType::eTypeIsArray))
+ else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
+ !(non_base_class_parent_type_info & eTypeIsArray))
{
s.PutChar('.');
}
@@ -2728,15 +2793,15 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
case '-':
{
if (options.m_check_dot_vs_arrow_syntax &&
- root_clang_type_info.Test(ClangASTType::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
+ root_clang_type_info.Test(eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
{
*first_unparsed = expression_cstr;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
return ValueObjectSP();
}
- if (root_clang_type_info.Test(ClangASTType::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
- root_clang_type_info.Test(ClangASTType::eTypeIsPointer) &&
+ if (root_clang_type_info.Test(eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden
+ root_clang_type_info.Test(eTypeIsPointer) &&
options.m_no_fragile_ivar)
{
*first_unparsed = expression_cstr;
@@ -2756,7 +2821,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
case '.': // or fallthrough from ->
{
if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
- root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
+ root_clang_type_info.Test(eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
{
*first_unparsed = expression_cstr;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
@@ -2783,7 +2848,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
if (root->IsSynthetic())
{
*first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchSyntheticChild;
*final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
return ValueObjectSP();
}
@@ -2857,9 +2922,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
case '[':
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTType::eTypeIsVector)) // if this is not a T[] nor a T*
+ if (!root_clang_type_info.Test(eTypeIsArray) && !root_clang_type_info.Test(eTypeIsPointer) && !root_clang_type_info.Test(eTypeIsVector)) // if this is not a T[] nor a T*
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar...
+ if (!root_clang_type_info.Test(eTypeIsScalar)) // if this is not even a scalar...
{
if (options.m_no_synthetic_children) // ...only chance left is synthetic
{
@@ -2879,7 +2944,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (!root_clang_type_info.Test(eTypeIsArray))
{
*first_unparsed = expression_cstr;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
@@ -2916,7 +2981,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
{
- if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (root_clang_type_info.Test(eTypeIsArray))
{
*first_unparsed = expression_cstr+2;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
@@ -2932,7 +2997,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
}
// from here on we do have a valid index
- if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (root_clang_type_info.Test(eTypeIsArray))
{
ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
if (!child_valobj_sp)
@@ -2955,10 +3020,10 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
return ValueObjectSP();
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
+ else if (root_clang_type_info.Test(eTypeIsPointer))
{
if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
- pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
+ pointee_clang_type_info.Test(eTypeIsScalar))
{
Error error;
root = root->Dereference(error);
@@ -2978,7 +3043,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
else
{
if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC
- && pointee_clang_type_info.AllClear(ClangASTType::eTypeIsPointer)
+ && pointee_clang_type_info.AllClear(eTypeIsPointer)
&& root->HasSyntheticValue()
&& options.m_no_synthetic_children == false)
{
@@ -3001,7 +3066,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
}
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar))
+ else if (root_clang_type_info.Test(eTypeIsScalar))
{
root = root->GetSyntheticBitFieldChild(index, index, true);
if (!root.get())
@@ -3019,7 +3084,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
return root;
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsVector))
+ else if (root_clang_type_info.Test(eTypeIsVector))
{
root = root->GetChildAtIndex(index, true);
if (!root.get())
@@ -3104,7 +3169,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
index_lower = index_higher;
index_higher = temp;
}
- if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
+ if (root_clang_type_info.Test(eTypeIsScalar)) // expansion only works for scalars
{
root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
if (!root.get())
@@ -3122,9 +3187,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
return root;
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+ else if (root_clang_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
*what_next == ValueObject::eExpressionPathAftermathDereference &&
- pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
+ pointee_clang_type_info.Test(eTypeIsScalar))
{
Error error;
root = root->Dereference(error);
@@ -3201,9 +3266,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
{
case '[':
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if this is not a T[] nor a T*
+ if (!root_clang_type_info.Test(eTypeIsArray) && !root_clang_type_info.Test(eTypeIsPointer)) // if this is not a T[] nor a T*
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
+ if (!root_clang_type_info.Test(eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
{
*first_unparsed = expression_cstr;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
@@ -3220,7 +3285,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
}
if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
{
- if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (!root_clang_type_info.Test(eTypeIsArray))
{
*first_unparsed = expression_cstr;
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
@@ -3264,7 +3329,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
}
if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
{
- if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (root_clang_type_info.Test(eTypeIsArray))
{
const size_t max_index = root->GetNumChildren() - 1;
for (size_t index = 0; index < max_index; index++)
@@ -3287,7 +3352,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
}
}
// from here on we do have a valid index
- if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
+ if (root_clang_type_info.Test(eTypeIsArray))
{
root = root->GetChildAtIndex(index, true);
if (!root.get())
@@ -3306,10 +3371,10 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
return 1;
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
+ else if (root_clang_type_info.Test(eTypeIsPointer))
{
if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
- pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
+ pointee_clang_type_info.Test(eTypeIsScalar))
{
Error error;
root = root->Dereference(error);
@@ -3391,7 +3456,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
index_lower = index_higher;
index_higher = temp;
}
- if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
+ if (root_clang_type_info.Test(eTypeIsScalar)) // expansion only works for scalars
{
root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
if (!root.get())
@@ -3410,9 +3475,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
return 1;
}
}
- else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
+ else if (root_clang_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
*what_next == ValueObject::eExpressionPathAftermathDereference &&
- pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
+ pointee_clang_type_info.Test(eTypeIsScalar))
{
Error error;
root = root->Dereference(error);
@@ -3480,9 +3545,7 @@ ValueObject::LogValueObject (Log *log, const DumpValueObjectOptions& options)
void
ValueObject::Dump (Stream &s)
{
-
- ValueObjectPrinter printer(this,&s,DumpValueObjectOptions::DefaultOptions());
- printer.PrintValueObject();
+ Dump (s, DumpValueObjectOptions::DefaultOptions());
}
void
@@ -3529,6 +3592,55 @@ ValueObject::CreateConstantValue (const ConstString &name)
return valobj_sp;
}
+ValueObjectSP
+ValueObject::GetQualifiedRepresentationIfAvailable (lldb::DynamicValueType dynValue,
+ bool synthValue)
+{
+ ValueObjectSP result_sp(GetSP());
+
+ switch (dynValue)
+ {
+ case lldb::eDynamicCanRunTarget:
+ case lldb::eDynamicDontRunTarget:
+ {
+ if (!result_sp->IsDynamic())
+ {
+ if (result_sp->GetDynamicValue(dynValue))
+ result_sp = result_sp->GetDynamicValue(dynValue);
+ }
+ }
+ break;
+ case lldb::eNoDynamicValues:
+ {
+ if (result_sp->IsDynamic())
+ {
+ if (result_sp->GetStaticValue())
+ result_sp = result_sp->GetStaticValue();
+ }
+ }
+ break;
+ }
+
+ if (synthValue)
+ {
+ if (!result_sp->IsSynthetic())
+ {
+ if (result_sp->GetSyntheticValue())
+ result_sp = result_sp->GetSyntheticValue();
+ }
+ }
+ else
+ {
+ if (result_sp->IsSynthetic())
+ {
+ if (result_sp->GetNonSyntheticValue())
+ result_sp = result_sp->GetNonSyntheticValue();
+ }
+ }
+
+ return result_sp;
+}
+
lldb::addr_t
ValueObject::GetCPPVTableAddress (AddressType &address_type)
{
@@ -3538,13 +3650,13 @@ ValueObject::GetCPPVTableAddress (AddressType &address_type)
if (type_info)
{
bool ptr_or_ref = false;
- if (type_info & (ClangASTType::eTypeIsPointer | ClangASTType::eTypeIsReference))
+ if (type_info & (eTypeIsPointer | eTypeIsReference))
{
ptr_or_ref = true;
type_info = pointee_type.GetTypeInfo();
}
- const uint32_t cpp_class = ClangASTType::eTypeIsClass | ClangASTType::eTypeIsCPlusPlus;
+ const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
if ((type_info & cpp_class) == cpp_class)
{
if (ptr_or_ref)
@@ -3736,16 +3848,14 @@ ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
ValueObject::EvaluationPoint::EvaluationPoint () :
m_mod_id(),
m_exe_ctx_ref(),
- m_needs_update (true),
- m_first_update (true)
+ m_needs_update (true)
{
}
ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
m_mod_id(),
m_exe_ctx_ref(),
- m_needs_update (true),
- m_first_update (true)
+ m_needs_update (true)
{
ExecutionContext exe_ctx(exe_scope);
TargetSP target_sp (exe_ctx.GetTargetSP());
@@ -3789,8 +3899,7 @@ ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope,
ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
m_mod_id(),
m_exe_ctx_ref(rhs.m_exe_ctx_ref),
- m_needs_update (true),
- m_first_update (true)
+ m_needs_update (true)
{
}
@@ -3884,7 +3993,6 @@ ValueObject::EvaluationPoint::SetUpdated ()
ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
if (process_sp)
m_mod_id = process_sp->GetModID();
- m_first_update = false;
m_needs_update = false;
}
@@ -3900,9 +4008,7 @@ ValueObject::ClearUserVisibleData(uint32_t clear_mask)
m_location_str.clear();
if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary)
- {
m_summary_str.clear();
- }
if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription)
m_object_desc_str.clear();
@@ -3912,6 +4018,9 @@ ValueObject::ClearUserVisibleData(uint32_t clear_mask)
if (m_synthetic_value)
m_synthetic_value = NULL;
}
+
+ if ((clear_mask & eClearUserVisibleDataItemsValidator) == eClearUserVisibleDataItemsValidator)
+ m_validation_result.reset();
}
SymbolContextScope *
@@ -3930,6 +4039,16 @@ ValueObject::CreateValueObjectFromExpression (const char* name,
const char* expression,
const ExecutionContext& exe_ctx)
{
+ return CreateValueObjectFromExpression(name, expression, exe_ctx, EvaluateExpressionOptions());
+}
+
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromExpression (const char* name,
+ const char* expression,
+ const ExecutionContext& exe_ctx,
+ const EvaluateExpressionOptions& options)
+{
lldb::ValueObjectSP retval_sp;
lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
if (!target_sp)
@@ -3938,7 +4057,8 @@ ValueObject::CreateValueObjectFromExpression (const char* name,
return retval_sp;
target_sp->EvaluateExpression (expression,
exe_ctx.GetFrameSP().get(),
- retval_sp);
+ retval_sp,
+ options);
if (retval_sp && name && *name)
retval_sp->SetName(ConstString(name));
return retval_sp;
@@ -3960,7 +4080,7 @@ ValueObject::CreateValueObjectFromAddress (const char* name,
pointer_type,
ConstString(name),
buffer,
- lldb::endian::InlHostByteOrder(),
+ exe_ctx.GetByteOrder(),
exe_ctx.GetAddressByteSize()));
if (ptr_result_valobj_sp)
{
@@ -4057,3 +4177,77 @@ ValueObject::GetFormat () const
}
return m_format;
}
+
+lldb::LanguageType
+ValueObject::GetPreferredDisplayLanguage ()
+{
+ lldb::LanguageType type = lldb::eLanguageTypeUnknown;
+ if (GetRoot())
+ {
+ if (GetRoot() == this)
+ {
+ if (StackFrameSP frame_sp = GetFrameSP())
+ {
+ const SymbolContext& sc(frame_sp->GetSymbolContext(eSymbolContextCompUnit));
+ if (CompileUnit* cu = sc.comp_unit)
+ type = cu->GetLanguage();
+ }
+ }
+ else
+ {
+ type = GetRoot()->GetPreferredDisplayLanguage();
+ }
+ }
+ return type;
+}
+
+bool
+ValueObject::CanProvideValue ()
+{
+ // we need to support invalid types as providers of values because some bare-board
+ // debugging scenarios have no notion of types, but still manage to have raw numeric
+ // values for things like registers. sigh.
+ const ClangASTType &type(GetClangType());
+ return (false == type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
+}
+
+bool
+ValueObject::IsChecksumEmpty ()
+{
+ return m_value_checksum.empty();
+}
+
+ValueObjectSP
+ValueObject::Persist ()
+{
+ if (!UpdateValueIfNeeded())
+ return nullptr;
+
+ TargetSP target_sp(GetTargetSP());
+ if (!target_sp)
+ return nullptr;
+
+ ConstString name(target_sp->GetPersistentVariables().GetNextPersistentVariableName());
+
+ ClangExpressionVariableSP clang_var_sp(new ClangExpressionVariable(target_sp.get(), GetValue(), name));
+ if (clang_var_sp)
+ {
+ clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp;
+ clang_var_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
+ target_sp->GetPersistentVariables().AddVariable(clang_var_sp);
+ }
+
+ return clang_var_sp->GetValueObject();
+}
+
+bool
+ValueObject::IsSyntheticChildrenGenerated ()
+{
+ return m_is_synthetic_children_generated;
+}
+
+void
+ValueObject::SetSyntheticChildrenGenerated (bool b)
+{
+ m_is_synthetic_children_generated = b;
+}
diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp
index 4f4f8cc681d0..b20371b128df 100644
--- a/source/Core/ValueObjectCast.cpp
+++ b/source/Core/ValueObjectCast.cpp
@@ -102,7 +102,7 @@ ValueObjectCast::UpdateValue ()
//m_value.SetContext (Value::eContextTypeClangType, clang_type);
m_value.SetClangType (clang_type);
SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
- if (clang_type.IsAggregateType ())
+ if (!CanProvideValue())
{
// this value object represents an aggregate type whose
// children have values, but this object does not. So we
diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index 33b91f9e30d1..2b3c8344af8f 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -208,7 +208,7 @@ ValueObjectChild::UpdateValue ()
{
const bool thread_and_frame_only_if_stopped = true;
ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
- if (GetClangType().GetTypeInfo() & ClangASTType::eTypeHasValue)
+ if (GetClangType().GetTypeInfo() & lldb::eTypeHasValue)
m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, 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 387e171e3526..fc870d726221 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -122,9 +122,10 @@ ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
ValueObjectSP
ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
Value &value,
- const ConstString &name)
+ const ConstString &name,
+ Module *module)
{
- return (new ValueObjectConstResult (exe_scope, value, name))->GetSP();
+ return (new ValueObjectConstResult (exe_scope, value, name, module))->GetSP();
}
ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
@@ -222,14 +223,18 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope
ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
const Value &value,
- const ConstString &name) :
+ const ConstString &name,
+ Module *module) :
ValueObject (exe_scope),
m_type_name (),
m_byte_size (0),
m_impl(this)
{
m_value = value;
- m_value.GetData(m_data);
+ m_name = name;
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module);
}
ValueObjectConstResult::~ValueObjectConstResult()
@@ -358,3 +363,8 @@ ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic)
return ValueObjectSP();
}
+lldb::LanguageType
+ValueObjectConstResult::GetPreferredDisplayLanguage ()
+{
+ return lldb::eLanguageTypeUnknown;
+}
diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp
index d3e275883509..733d767b7ee1 100644
--- a/source/Core/ValueObjectConstResultImpl.cpp
+++ b/source/Core/ValueObjectConstResultImpl.cpp
@@ -30,13 +30,6 @@
using namespace lldb;
using namespace lldb_private;
-// this macro enables a simpler implementation for some method calls in this object that relies only upon
-// ValueObject knowing how to set the address type of its children correctly. the alternative implementation
-// relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less
-// efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower
-// implementations) can go
-#define TRIVIAL_IMPL 1
-
ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
lldb::addr_t live_address) :
m_impl_backend(valobj),
@@ -48,38 +41,12 @@ ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
}
lldb::ValueObjectSP
-ValueObjectConstResultImpl::DerefOnTarget()
-{
- if (m_load_addr_backend.get() == NULL)
- {
- lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
- ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
- m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- m_impl_backend->GetClangType(),
- m_impl_backend->GetName(),
- tgt_address,
- eAddressTypeLoad,
- exe_ctx.GetAddressByteSize());
- }
- return m_load_addr_backend;
-}
-
-lldb::ValueObjectSP
ValueObjectConstResultImpl::Dereference (Error &error)
{
if (m_impl_backend == NULL)
return lldb::ValueObjectSP();
-#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
return m_impl_backend->ValueObject::Dereference(error);
-#else
- m_impl_backend->UpdateValueIfNeeded(false);
-
- if (NeedsDerefOnTarget())
- return DerefOnTarget()->Dereference(error);
- else
- return m_impl_backend->ValueObject::Dereference(error);
-#endif
}
ValueObject *
@@ -139,7 +106,8 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array
child_bitfield_bit_offset,
child_is_base_class,
child_is_deref_of_parent);
- valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
+ if (m_live_address != LLDB_INVALID_ADDRESS)
+ valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
}
return valobj;
@@ -151,16 +119,7 @@ ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const Cl
if (m_impl_backend == NULL)
return lldb::ValueObjectSP();
-#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
-#else
- m_impl_backend->UpdateValueIfNeeded(false);
-
- if (NeedsDerefOnTarget())
- return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
- else
- return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
-#endif
}
lldb::ValueObjectSP
@@ -193,7 +152,7 @@ ValueObjectConstResultImpl::AddressOf (Error &error)
return m_address_of_backend;
}
else
- return lldb::ValueObjectSP();
+ return m_impl_backend->ValueObject::AddressOf(error);
}
lldb::addr_t
@@ -223,14 +182,5 @@ ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
{
if (m_impl_backend == NULL)
return 0;
-#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
-#else
- m_impl_backend->UpdateValueIfNeeded(false);
-
- if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
- return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
- else
- return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
-#endif
}
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index a6fad7a9b1fd..1b8ec8083f8f 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -241,16 +241,7 @@ ValueObjectDynamicValue::UpdateValue ()
{
if (class_type_or_name.HasType())
{
- // TypeSP are always generated from debug info
- if (!class_type_or_name.HasTypeSP() && class_type_or_name.GetClangASTType().IsRuntimeGeneratedType())
- {
- m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
- class_type_or_name.SetClangASTType(ClangASTType());
- }
- else
- {
- m_type_impl = TypeImpl(FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
- }
+ m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
}
else
{
@@ -329,7 +320,7 @@ ValueObjectDynamicValue::UpdateValue ()
m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
if (m_error.Success())
{
- if (GetClangType().IsAggregateType ())
+ if (!CanProvideValue())
{
// this value object represents an aggregate type whose
// children have values, but this object does not. So we
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index d2cbbfdda240..5fbe87b66522 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -233,7 +233,7 @@ ValueObjectMemory::UpdateValue ()
}
}
- if (GetClangType().IsAggregateType())
+ if (!CanProvideValue())
{
// this value object represents an aggregate type whose
// children have values, but this object does not. So we
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index 18d36164989a..dafe73a5e57e 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -66,16 +66,17 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic
m_name_toindex(),
m_synthetic_children_count(UINT32_MAX),
m_parent_type_name(parent.GetTypeName()),
- m_might_have_children(eLazyBoolCalculate)
+ m_might_have_children(eLazyBoolCalculate),
+ m_provides_value(eLazyBoolCalculate)
{
-#ifdef LLDB_CONFIGURATION_DEBUG
+#ifdef FOOBAR
std::string new_name(parent.GetName().AsCString());